[Devel] [PATCH RH9 1/2] fuse: add 'struct fuse_file *ff' field to 'struct fuse_args'
Kui Liu
Kui.Liu at acronis.com
Wed Mar 16 14:52:26 MSK 2022
We need to check the FUSE_S_FAIL_IMMEDIATELY flag bit of ff->ff_state before
put a request to the input queue. Currently, the fuse_file fuse_pointer is passed
around differently for synchronous and background requests.
For background request, it simply reuses the pointer saved in ia->ff, which
is quite convenient and didn't require significant changes.
For synchronous request, the pointer is passed as a function parameter instead,
which is quite inconvenient, as it resulted in change to many functions just
for the sake of passing this parameter. This makes code look very messy.
In this patch, we add 'fuse_file *ff' field to 'struct fuse_args', which will
then be used for passing the fuse_file pointer by both synchronous and background
requests. This significantly simplifies handling of synchronous request so that
a significant amount of code can be cleaned up, especially code brought in by commit
39ee75b5c56 is in fact dropped completely.
Signed-off-by: Liu Kui <Kui.Liu at acronis.com<mailto:Kui.Liu at acronis.com>>
---
fs/fuse/dev.c | 61 ++++--------------------------
fs/fuse/file.c | 4 +-
fs/fuse/fuse_i.h | 11 ++----
fs/fuse/kio/kio_noop.c | 2 +-
fs/fuse/kio/kio_nullio.c | 2 +-
fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 53 ++++++++------------------
6 files changed, 31 insertions(+), 102 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 213527e0f773..e9b4f2df5899 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -295,7 +295,7 @@ static void flush_bg_queue(struct fuse_conn *fc, struct fuse_iqueue *fiq)
spin_unlock(&fc->bg_lock);
list_for_each_entry_safe(req, next, &kio_reqs, list) {
list_del_init(&req->list);
- fc->kio.op->req_send(req, NULL, true);
+ fc->kio.op->req_send(req, true);
}
spin_lock(&fc->bg_lock);
}
@@ -450,18 +450,19 @@ static void request_wait_answer(struct fuse_req *req)
wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags) && !req->args->end);
}
-static void __fuse_request_send(struct fuse_req *req, struct fuse_file *ff)
+static void __fuse_request_send(struct fuse_req *req)
{
struct fuse_mount *fm = req->fm;
struct fuse_conn *fc = fm->fc;
struct fuse_iqueue *fiq = req->args->fiq;
+ struct fuse_file *ff = req->args->ff;
BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
if (fc->kio.op) {
int ret = fc->kio.op->req_classify(req, false, false);
if (likely(!ret))
- return fc->kio.op->req_send(req, ff, false);
+ return fc->kio.op->req_send(req, false);
else if (ret < 0)
return;
}
@@ -548,8 +549,7 @@ static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args)
__set_bit(FR_KIO_INTERNAL, &req->flags);
}
-ssize_t fuse_simple_check_request(struct fuse_mount *fm, struct fuse_args *args,
- struct fuse_file *ff)
+ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args)
{
struct fuse_conn *fc = fm->fc;
struct fuse_req *req;
@@ -578,7 +578,7 @@ ssize_t fuse_simple_check_request(struct fuse_mount *fm, struct fuse_args *args,
if (!args->noreply)
__set_bit(FR_ISREPLY, &req->flags);
- __fuse_request_send(req, ff);
+ __fuse_request_send(req);
ret = req->out.h.error;
if (!ret && args->out_argvar) {
BUG_ON(args->out_numargs == 0);
@@ -588,59 +588,13 @@ ssize_t fuse_simple_check_request(struct fuse_mount *fm, struct fuse_args *args,
return ret;
}
-
-ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args)
-{
- return fuse_simple_check_request(fm, args, NULL);
-}
EXPORT_SYMBOL_GPL(fuse_simple_request);
-bool fuse_has_req_ff(struct fuse_req *req)
-{
- switch (req->in.h.opcode) {
- case FUSE_WRITE:
- case FUSE_READ:
- return true;
- default:
- return false;
- }
-}
-EXPORT_SYMBOL_GPL(fuse_has_req_ff);
-
-struct fuse_file* fuse_get_req_ff(struct fuse_req *req)
-{
- switch (req->in.h.opcode) {
- case FUSE_WRITE:
- case FUSE_READ: {
- struct fuse_io_args *ia = container_of(req->args, typeof(*ia), ap.args);
- return ia->ff;
- }
- default:
- return NULL;
- }
-}
-EXPORT_SYMBOL_GPL(fuse_get_req_ff);
-
-bool fuse_set_req_ff(struct fuse_req *req, struct fuse_file *ff)
-{
- switch (req->in.h.opcode) {
- case FUSE_WRITE:
- case FUSE_READ: {
- struct fuse_io_args *ia = container_of(req->args, typeof(*ia), ap.args);
- ia->ff = ff;
- return true;
- }
- default:
- return false;
- }
-}
-EXPORT_SYMBOL_GPL(fuse_set_req_ff);
-
static int fuse_request_queue_background(struct fuse_req *req)
{
struct fuse_mount *fm = req->fm;
struct fuse_conn *fc = fm->fc;
- struct fuse_file *ff = fuse_get_req_ff(req);
+ struct fuse_file *ff = req->args->ff;
struct fuse_iqueue *fiq = req->args->fiq;
int ret = -ENOTCONN;
@@ -653,7 +607,6 @@ static int fuse_request_queue_background(struct fuse_req *req)
__set_bit(FR_ISREPLY, &req->flags);
spin_lock(&fc->bg_lock);
if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state)) {
- BUG_ON(req->in.h.opcode != FUSE_READ);
ret = -EIO;
} else if (likely(fc->connected)) {
fc->num_background++;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 8d75d9f0f6ef..1cce68a2feb5 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -794,6 +794,7 @@ void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
if (fiq->handled_by_fud)
args->fiq = fiq;
args->inode = file->f_path.dentry->d_inode;
+ args->ff = ff;
}
}
@@ -1021,7 +1022,7 @@ static ssize_t fuse_send_read(struct fuse_io_args *ia, loff_t pos, size_t count,
if (ia->io->async)
return fuse_async_req_send(fm, ia, count);
- return fuse_simple_check_request(fm, &ia->ap.args, ff);
+ return fuse_simple_request(fm, &ia->ap.args);
}
static void fuse_read_update_size(struct inode *inode, loff_t size,
@@ -1297,6 +1298,7 @@ static void fuse_write_args_fill(struct fuse_io_args *ia, struct fuse_file *ff,
args->out_args[0].size = sizeof(ia->write.out);
args->out_args[0].value = &ia->write.out;
args->io_inode = inode;
+ args->ff = ff;
}
static unsigned int fuse_write_flags(struct kiocb *iocb)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 17f67b947917..aa74b63b2392 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -331,6 +331,9 @@ struct fuse_args {
/** Request will be handled by fud pointing to this fiq */
struct fuse_iqueue *fiq;
+
+ /** Fuse file used in the request or NULL*/
+ struct fuse_file *ff;
};
struct fuse_args_pages {
@@ -618,7 +621,7 @@ struct fuse_kio_ops {
/* Request handling hooks */
struct fuse_req *(*req_alloc)(struct fuse_mount *fm, gfp_t flags);
int (*req_classify)(struct fuse_req *req, bool bg, bool locked);
- void (*req_send)(struct fuse_req *req, struct fuse_file *ff, bool bg);
+ void (*req_send)(struct fuse_req *req, bool bg);
/* Inode scope hooks */
int (*file_open)(struct file *file, struct inode *inode);
@@ -1190,18 +1193,12 @@ void fuse_dev_cleanup(void);
int fuse_ctl_init(void);
void __exit fuse_ctl_cleanup(void);
-bool fuse_has_req_ff(struct fuse_req *req);
-struct fuse_file* fuse_get_req_ff(struct fuse_req *req);
-bool fuse_set_req_ff(struct fuse_req *req, struct fuse_file *ff);
-
/**
* Simple request sending that does request allocation and freeing
*/
ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args);
int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
gfp_t gfp_flags);
-ssize_t fuse_simple_check_request(struct fuse_mount *fm, struct fuse_args *args,
- struct fuse_file *ff);
/**
* End a finished request
diff --git a/fs/fuse/kio/kio_noop.c b/fs/fuse/kio/kio_noop.c
index 5371b90438d1..1d167d648eaa 100644
--- a/fs/fuse/kio/kio_noop.c
+++ b/fs/fuse/kio/kio_noop.c
@@ -55,7 +55,7 @@ static struct fuse_req *noop_req_alloc(struct fuse_mount *fm, gfp_t flags)
return fuse_generic_request_alloc(fm, noop_req_cachep, flags);
}
-static void noop_req_send(struct fuse_req *req, struct fuse_file *ff, bool bg)
+static void noop_req_send(struct fuse_req *req, bool bg)
{
struct fuse_conn *fc = req->fm->fc;
diff --git a/fs/fuse/kio/kio_nullio.c b/fs/fuse/kio/kio_nullio.c
index 62a2bdeaf6b0..f7466ca2b25d 100644
--- a/fs/fuse/kio/kio_nullio.c
+++ b/fs/fuse/kio/kio_nullio.c
@@ -82,7 +82,7 @@ static struct fuse_req *nullio_req_alloc(struct fuse_mount *fm, gfp_t flags)
return req;
}
-static void nullio_req_send(struct fuse_req *req, struct fuse_file *ff, bool bg)
+static void nullio_req_send(struct fuse_req *req, bool bg)
{
struct fuse_conn *fc = req->fm->fc;
struct fuse_io_args *ia = container_of(req->args, typeof(*ia), ap.args);
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 9506cd0bd4ed..af008e63294c 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -764,23 +764,10 @@ static void wait_shrink(struct pcs_fuse_req *r, struct pcs_dentry_info *di)
list_add_tail(&r->exec.ireq.list, &di->size.queue);
}
-static void _pcs_ff_free_end(struct fuse_mount *fm, struct fuse_args *args, int error)
+static bool kqueue_insert(struct pcs_dentry_info *di, struct fuse_req *req)
{
- struct fuse_req *req = args->req;
- struct pcs_fuse_req *r = pcs_req_from_fuse(req);
- struct fuse_file *req_ff = fuse_get_req_ff(req);
-
- BUG_ON(!req_ff);
- BUG_ON(args->inode);
- fuse_release_ff(args->inode, req_ff);
-
- if (r->end)
- r->end(fm, args, error);
-}
+ struct fuse_file *ff = req->args->ff;
-static bool kqueue_insert(struct pcs_dentry_info *di, struct fuse_file *ff,
- struct fuse_req *req)
-{
spin_lock(&di->kq_lock);
if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state)) {
spin_unlock(&di->kq_lock);
@@ -791,14 +778,12 @@ static bool kqueue_insert(struct pcs_dentry_info *di, struct fuse_file *ff,
return true;
}
-static inline int req_wait_grow_queue(struct pcs_fuse_req *r,
- struct fuse_file *ff,
- off_t offset, size_t size)
+static inline int req_wait_grow_queue(struct pcs_fuse_req *r, off_t offset, size_t size)
{
struct pcs_dentry_info *di = get_pcs_inode(r->req.args->io_inode);
struct fuse_inode *fi = get_fuse_inode(r->req.args->io_inode);
- if (!kqueue_insert(di, ff, &r->req))
+ if (!kqueue_insert(di, &r->req))
return -EIO;
BUG_ON(r->req.in.h.opcode != FUSE_WRITE && r->req.in.h.opcode != FUSE_FALLOCATE);
@@ -816,7 +801,7 @@ static inline int req_wait_grow_queue(struct pcs_fuse_req *r,
* -EPERM: Nope
* 1: request placed to pended queue
*/
-static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
+static int pcs_fuse_prep_rw(struct pcs_fuse_req *r)
{
struct fuse_req *req = &r->req;
struct fuse_args *args = req->args;
@@ -828,13 +813,6 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
spin_lock(&di->lock);
/* Deffer all requests if shrink requested to prevent livelock */
if (di->size.op == PCS_SIZE_SHRINK) {
- if (ff && fuse_has_req_ff(&r->req) &&
- !fuse_get_req_ff(&r->req)) {
- r->end = r->req.args->end;
- fuse_set_req_ff(&r->req, fuse_file_get(ff));
- __set_bit(FR_ASYNC, &r->req.flags);
- r->req.args->end = _pcs_ff_free_end;
- }
wait_shrink(r, di);
ret = 1;
goto out;
@@ -864,7 +842,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
if (in->offset + in->size > di->fileinfo.attr.size) {
pcs_fuse_prep_io(r, PCS_REQ_T_WRITE, in->offset,
in->size, 0);
- ret = req_wait_grow_queue(r, ff, in->offset, in->size);
+ ret = req_wait_grow_queue(r, in->offset, in->size);
goto out;
}
@@ -909,7 +887,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
in->length, 0);
else
pcs_fuse_prep_fallocate(r);
- ret = req_wait_grow_queue(r, ff, in->offset, in->length);
+ ret = req_wait_grow_queue(r, in->offset, in->length);
goto out;
}
@@ -929,7 +907,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
BUG();
}
- if (!kqueue_insert(di, ff, req))
+ if (!kqueue_insert(di, req))
ret = -EIO;
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);
@@ -941,8 +919,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r, struct fuse_file *ff)
return ret;
}
-static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
- struct fuse_file *ff)
+static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req)
{
struct pcs_fuse_req *r = pcs_req_from_fuse(req);
struct fuse_args *args = req->args;
@@ -965,7 +942,7 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
case FUSE_READ:
case FUSE_FSYNC:
case FUSE_FLUSH:
- ret = pcs_fuse_prep_rw(r, ff);
+ ret = pcs_fuse_prep_rw(r);
if (likely(!ret))
goto submit;
if (ret > 0)
@@ -1004,7 +981,7 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
inarg->length = di->fileinfo.attr.size - inarg->offset;
}
- ret = pcs_fuse_prep_rw(r, ff);
+ ret = pcs_fuse_prep_rw(r);
if (likely(!ret))
goto submit;
if (ret > 0)
@@ -1021,7 +998,7 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
goto error;
}
- ret = pcs_fuse_prep_rw(r, ff);
+ ret = pcs_fuse_prep_rw(r);
if (likely(!ret))
goto submit;
if (ret > 0)
@@ -1104,7 +1081,7 @@ static void _pcs_shrink_end(struct fuse_mount *fm, struct fuse_args *args, int e
TRACE("resubmit %p\n", &r->req);
list_del_init(&ireq->list);
- pcs_fuse_submit(pfc, &r->req, fuse_get_req_ff(&r->req));
+ pcs_fuse_submit(pfc, &r->req);
}
}
@@ -1241,7 +1218,7 @@ static int kpcs_req_classify(struct fuse_req *req, bool bg, bool lk)
return 1;
}
-static void kpcs_req_send(struct fuse_req *req, struct fuse_file *ff, bool bg)
+static void kpcs_req_send(struct fuse_req *req, bool bg)
{
struct fuse_conn *fc = req->fm->fc;
struct pcs_fuse_cluster *pfc = (struct pcs_fuse_cluster*)fc->kio.ctx;
@@ -1259,7 +1236,7 @@ static void kpcs_req_send(struct fuse_req *req, struct fuse_file *ff, bool bg)
refcount_inc(&req->count);
__clear_bit(FR_PENDING, &req->flags);
- pcs_fuse_submit(pfc, req, ff ? : fuse_get_req_ff(req));
+ pcs_fuse_submit(pfc, req);
if (!bg)
wait_event(req->waitq,
test_bit(FR_FINISHED, &req->flags) && !req->args->end);
--
2.27.0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvz.org/pipermail/devel/attachments/20220316/5e6b26e5/attachment-0001.html>
More information about the Devel
mailing list