[Devel] [PATCH RHEL8 COMMIT] fs/fuse kio: disable parallel fsyncs and file shrinks
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Apr 23 11:55:01 MSK 2021
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.19
------>
commit 66bc101e2f5a126f78bc8812b362591c58a50ea0
Author: Alexey Kuznetsov <kuznet at virtuozzo.com>
Date: Fri Apr 23 11:55:01 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 fc4af3a38523..ddf643503598 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.args->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);
fuse_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 67132d4dc8c4..c7b79b90c33e 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -750,7 +750,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.args->io_inode->i_ino, r);
list_add_tail(&r->exec.ireq.list, &di->size.queue);
@@ -913,13 +913,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);
@@ -951,6 +955,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;
@@ -1001,10 +1007,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;
@@ -1089,7 +1091,7 @@ static void _pcs_shrink_end(struct fuse_conn *fc, struct fuse_args *args, int er
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