[Devel] [PATCH RHEL7 COMMIT] fs/fuse kio: disable parallel fsyncs and file shrinks

Vasily Averin vvs at virtuozzo.com
Tue Mar 2 09:53:22 MSK 2021


The commit is pushed to "branch-rh7-3.10.0-1160.15.2.vz7.173.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.15.2.vz7.173.1
------>
commit a3733d55c98fc13a3a0fe51fb82026d9de2b3c63
Author: Alexey Kuznetsov <kuznet at virtuozzo.com>
Date:   Tue Mar 2 09:53:22 2021 +0300

    fs/fuse kio: disable parallel fsyncs and file shrinks
    
    All IO requests were blocked by shrinks, but fsync.
    Though formally they are not mutually exclusive this
    results in problems with internal consistensy.
    
    https://pmc.acronis.com/browse/VSTOR-36154
    
    Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
    Reviewed-by: Ildar Ismagilov <ildar.ismagilov at virtuozzo.com>
    Signed-off-by: Ildar Ismagilov <ildar.ismagilov at virtuozzo.com>
---
 fs/fuse/kio/pcs/fuse_io.c          |  2 ++
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 16 +++++++++-------
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/fs/fuse/kio/pcs/fuse_io.c b/fs/fuse/kio/pcs/fuse_io.c
index cbee5f2..d0d4c58 100644
--- a/fs/fuse/kio/pcs/fuse_io.c
+++ b/fs/fuse/kio/pcs/fuse_io.c
@@ -57,10 +57,12 @@ static void on_read_done(struct pcs_fuse_req *r, size_t size)
 static void on_sync_done(struct pcs_fuse_req *r)
 {
 	struct pcs_fuse_cluster *pfc = cl_from_req(r);
+	struct fuse_inode *fi = get_fuse_inode(r->req.io_inode);
 
 	DTRACE("do fuse_request_end req:%p op:%d err:%d\n", &r->req, r->req.in.h.opcode, r->req.out.h.error);
 	fuse_stat_observe(pfc->fc, KFUSE_OP_FSYNC, ktime_sub(ktime_get(), r->exec.ireq.ts));
 	fuse_stat_account(pfc->fc, KFUSE_OP_FSYNC, 0);
+	fuse_read_dio_end(fi);
 	request_end(pfc->fc, &r->req);
 }
 
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 2ea1faa..1cdcb15 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -756,7 +756,7 @@ static void wait_shrink(struct pcs_fuse_req *r, struct pcs_dentry_info *di)
 	assert_spin_locked(&di->lock);
 	BUG_ON(r->exec.size_required);
 	/* Writes already blocked via fuse_set_nowrite */
-	BUG_ON(r->req.in.h.opcode != FUSE_READ);
+	BUG_ON(r->req.in.h.opcode != FUSE_READ && r->req.in.h.opcode != FUSE_FSYNC && r->req.in.h.opcode != FUSE_FLUSH);
 
 	TRACE("insert ino:%ld r:%p\n", r->req.io_inode->i_ino, r);
 	list_add_tail(&r->exec.ireq.list, &di->size.queue);
@@ -912,13 +912,17 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
 		}
 		break;
 	}
+	case FUSE_FSYNC:
+	case FUSE_FLUSH:
+		pcs_fuse_prep_io(r, PCS_REQ_T_SYNC, 0, 0, 0);
+		break;
 	default:
 		BUG();
 	}
 
 	if (!kqueue_insert(di, ff, req))
 		ret = -EIO;
-	else if (req->in.h.opcode == FUSE_READ)
+	else if (req->in.h.opcode == FUSE_READ || req->in.h.opcode == FUSE_FSYNC || req->in.h.opcode == FUSE_FLUSH)
 		fuse_read_dio_begin(fi);
 	else
 		fuse_write_dio_begin(fi);
@@ -949,6 +953,8 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 	switch (req->in.h.opcode) {
 	case FUSE_WRITE:
 	case FUSE_READ:
+	case FUSE_FSYNC:
+	case FUSE_FLUSH:
 		ret = pcs_fuse_prep_rw(r, ff);
 		if (likely(!ret))
 			goto submit;
@@ -999,10 +1005,6 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 		}
 		break;
 	}
-	case FUSE_FSYNC:
-	case FUSE_FLUSH:
-		pcs_fuse_prep_io(r, PCS_REQ_T_SYNC, 0, 0, 0);
-		goto submit;
 	case FUSE_IOCTL:
 		if (pfc->fc->no_fiemap) {
 			req->out.h.error = -EOPNOTSUPP;
@@ -1086,7 +1088,7 @@ static void _pcs_shrink_end(struct fuse_conn *fc, struct fuse_req *req)
 		struct pcs_fuse_req *r = container_of(ireq, struct pcs_fuse_req, exec.ireq);
 
 		BUG_ON(r->exec.size_required);
-		BUG_ON(r->req.in.h.opcode != FUSE_READ);
+		BUG_ON(r->req.in.h.opcode != FUSE_READ && r->req.in.h.opcode != FUSE_FSYNC && r->req.in.h.opcode != FUSE_FLUSH);
 
 		TRACE("resubmit %p\n", &r->req);
 		list_del_init(&ireq->list);


More information about the Devel mailing list