mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 17:59:32 +00:00
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>
This commit is contained in:
parent
338f2e3f33
commit
1259728731
2 changed files with 51 additions and 0 deletions
|
@ -626,6 +626,51 @@ bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req)
|
||||||
return queued;
|
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)
|
void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
|
||||||
{
|
{
|
||||||
WARN_ON(!req->end);
|
WARN_ON(!req->end);
|
||||||
|
|
|
@ -301,6 +301,7 @@ struct fuse_args {
|
||||||
bool page_replace:1;
|
bool page_replace:1;
|
||||||
struct fuse_in_arg in_args[3];
|
struct fuse_in_arg in_args[3];
|
||||||
struct fuse_arg out_args[2];
|
struct fuse_arg out_args[2];
|
||||||
|
void (*end)(struct fuse_conn *fc, struct fuse_args *args, int error);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fuse_args_pages {
|
struct fuse_args_pages {
|
||||||
|
@ -381,6 +382,9 @@ struct fuse_req {
|
||||||
/** Entry on the interrupts list */
|
/** Entry on the interrupts list */
|
||||||
struct list_head intr_entry;
|
struct list_head intr_entry;
|
||||||
|
|
||||||
|
/* Input/output arguments */
|
||||||
|
struct fuse_args *args;
|
||||||
|
|
||||||
/** refcount */
|
/** refcount */
|
||||||
refcount_t count;
|
refcount_t count;
|
||||||
|
|
||||||
|
@ -948,6 +952,8 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req);
|
||||||
* Simple request sending that does request allocation and freeing
|
* Simple request sending that does request allocation and freeing
|
||||||
*/
|
*/
|
||||||
ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);
|
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
|
* Send a request in the background
|
||||||
|
|
Loading…
Reference in a new issue