[RHEL7,COMMIT] fs/fuse kio: fix loss of FUSE_FSYNC/FUSE_FLUSH reqs

Submitted by Konstantin Khorenko on Dec. 4, 2018, 1:17 p.m.

Details

Message ID 201812041317.wB4DH8DJ002645@finist-ce7.sw.ru
State New
Series "Fuse KIO: fix fsync/flush loss"
Headers show

Commit Message

Konstantin Khorenko Dec. 4, 2018, 1:17 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.20.2.vz7.73.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.20.2.vz7.73.17
------>
commit d8f9e7650c1e6315e8ddffee9f71beafb62a534a
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Tue Dec 4 16:17:08 2018 +0300

    fs/fuse kio: fix loss of FUSE_FSYNC/FUSE_FLUSH reqs
    
    Fast-Path can loss fsync/flush requests, because PCS_REQ_T_SYNC request set up
    PCS_MAP_FLUSHING flag, but never cleans it. Although initially PCS_MAP_FLUSHING
    flag was created for sync timer, so PCS_REQ_T_SYNC request should ignore
    everything related to PCS_REQ_T_SYNC flag.
    
    This patch adds timer_sync flag in prepare_map_flush_ireq() to ignore all sync
    timer stuff on PCS_REQ_T_SYNC way.
    
    https://pmc.acronis.com/browse/VSTOR-18475
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_map.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c
index 459645417462..4bd18c5224ab 100644
--- a/fs/fuse/kio/pcs/pcs_map.c
+++ b/fs/fuse/kio/pcs/pcs_map.c
@@ -2959,20 +2959,24 @@  static void prepare_map_flush_msg(struct pcs_map_entry * m, struct pcs_int_reque
 	msg->done = sync_done;
 }
 
-static bool valid_for_flush(struct pcs_map_entry *m)
+static bool valid_for_flush(struct pcs_map_entry *m, bool timer_sync)
 {
-	if (m->state & PCS_MAP_DEAD)
-		return false;
+	if (timer_sync) {
+		if (m->state & PCS_MAP_DEAD)
+			return false;
 
+		if (m->flags & PCS_MAP_FLUSHING)
+			return false;
+	}
 	if (!(m->flags & PCS_MAP_DIRTY))
 		return false;
-	if (m->flags & PCS_MAP_FLUSHING)
-		return false;
 
 	return true;
 }
 
-static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_request **sreqp)
+static int prepare_map_flush_ireq(struct pcs_map_entry *m,
+				  struct pcs_int_request **sreqp,
+				  bool timer_sync)
 {
 	struct pcs_dentry_info *de;
 	struct pcs_cs_list *cslist;
@@ -2980,7 +2984,7 @@  static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_reques
 	struct pcs_msg * msg;
 
 	spin_lock(&m->lock);
-	if (!valid_for_flush(m)) {
+	if (!valid_for_flush(m, timer_sync)) {
 		spin_unlock(&m->lock);
 		return 0;
 	}
@@ -3010,7 +3014,7 @@  static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_reques
 	/* All resources allocated, we need to recheck maps state again */
 	spin_lock(&m->lock);
 	cslist_put(cslist);
-	if (!valid_for_flush(m) || m->cs_list != cslist) {
+	if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) {
 		spin_unlock(&m->lock);
 		return 0;
 	}
@@ -3025,7 +3029,8 @@  static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_reques
 	sreq->complete_cb = pcs_flushreq_complete;
 	sreq->flushreq.msg = msg;
 	FUSE_KTRACE(sreq->cc->fc, "timed FLUSH " MAP_FMT, MAP_ARGS(m));
-	m->flags |= PCS_MAP_FLUSHING;
+	if (timer_sync)
+		m->flags |= PCS_MAP_FLUSHING;
 	__pcs_map_get(m);
 	spin_unlock(&m->lock);
 	*sreqp	= sreq;
@@ -3047,7 +3052,7 @@  static void sync_timer_work(struct work_struct *w)
 	struct pcs_int_request * sreq = NULL;
 	int err;
 
-	err = prepare_map_flush_ireq(m, &sreq);
+	err = prepare_map_flush_ireq(m, &sreq, true);
 	if (err) {
 		spin_lock(&m->lock);
 		if (!(m->state & PCS_MAP_DEAD))
@@ -3125,7 +3130,7 @@  void map_inject_flush_req(struct pcs_int_request *ireq)
 				break;
 			if (!maps[i])
 				continue;
-			err = prepare_map_flush_ireq(maps[i], &sreq);
+			err = prepare_map_flush_ireq(maps[i], &sreq, false);
 			pcs_map_put(maps[i]);
 			if (err) {
 				pcs_set_local_error(&ireq->error, PCS_ERR_NOMEM);