BACKPORT: fuse: add simple background helper

Create a helper named fuse_simple_background() that is similar to
fuse_simple_request().  Unlike the latter, it returns immediately and calls
the supplied 'end' callback when the reply is received.

The supplied 'args' pointer is stored in 'fuse_req' which allows the
callback to interpret the output arguments decoded from the reply.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: UtsavBalar1231 <utsavbalar1231@gmail.com>
Change-Id: I28e9eb9ec3985759b90349329a483433b57bc056
This commit is contained in:
Miklos Szeredi 2019-09-10 15:04:10 +02:00 committed by spakkkk
parent e9b13d9ffa
commit 8fad56046b
2 changed files with 51 additions and 0 deletions

View File

@ -633,6 +633,51 @@ bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req)
return queued;
}
static void fuse_simple_end(struct fuse_conn *fc, struct fuse_req *req)
{
struct fuse_args *args = req->args;
int err = req->out.h.error;
if (!err && args->out_argvar) {
BUG_ON(args->out_numargs == 0);
args->out_args[args->out_numargs - 1].size =
req->out.args[args->out_numargs - 1].size;
}
req->args->end(fc, req->args, req->out.h.error);
}
int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args,
gfp_t gfp_flags)
{
struct fuse_req *req;
if (args->force) {
WARN_ON(!args->nocreds);
req = __fuse_request_alloc(0, gfp_flags);
if (!req)
return -ENOMEM;
__set_bit(FR_BACKGROUND, &req->flags);
} else {
WARN_ON(args->nocreds);
req = __fuse_get_req(fc, 0, true);
if (IS_ERR(req))
return PTR_ERR(req);
}
fuse_args_to_req(req, args);
req->args = args;
req->end = fuse_simple_end;
if (!fuse_request_queue_background(fc, req)) {
fuse_put_request(fc, req);
return -ENOTCONN;
}
return 0;
}
EXPORT_SYMBOL_GPL(fuse_simple_background);
void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
{
WARN_ON(!req->end);

View File

@ -304,6 +304,7 @@ struct fuse_args {
bool page_replace:1;
struct fuse_in_arg in_args[3];
struct fuse_arg out_args[2];
void (*end)(struct fuse_conn *fc, struct fuse_args *args, int error);
/* Path used for completing d_canonical_path */
struct path *canonical_path;
@ -387,6 +388,9 @@ struct fuse_req {
/** Entry on the interrupts list */
struct list_head intr_entry;
/* Input/output arguments */
struct fuse_args *args;
/** refcount */
refcount_t count;
@ -956,6 +960,8 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req);
* Simple request sending that does request allocation and freeing
*/
ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);
int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args,
gfp_t gfp_flags);
/**
* Send a request in the background