Commit 40ac7ab2 authored by Miklos Szeredi's avatar Miklos Szeredi

fuse: simplify 'nofail' request

Instead of complex games with a reserved request, just use __GFP_NOFAIL.

Both calers (flush, readdir) guarantee that connection was already
initialized, so no need to wait for fc->initialized.

Also remove unneeded clearing of FR_BACKGROUND flag.
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 1f4e9d03
...@@ -242,52 +242,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, ...@@ -242,52 +242,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
} }
EXPORT_SYMBOL_GPL(fuse_get_req_for_background); EXPORT_SYMBOL_GPL(fuse_get_req_for_background);
/*
* Return request in fuse_file->reserved_req. However that may
* currently be in use. If that is the case, wait for it to become
* available.
*/
static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
struct file *file)
{
struct fuse_req *req = NULL;
struct fuse_inode *fi = get_fuse_inode(file_inode(file));
struct fuse_file *ff = file->private_data;
do {
wait_event(fc->reserved_req_waitq, ff->reserved_req);
spin_lock(&fi->lock);
if (ff->reserved_req) {
req = ff->reserved_req;
ff->reserved_req = NULL;
req->stolen_file = get_file(file);
}
spin_unlock(&fi->lock);
} while (!req);
return req;
}
/*
* Put stolen request back into fuse_file->reserved_req
*/
static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
{
struct file *file = req->stolen_file;
struct fuse_inode *fi = get_fuse_inode(file_inode(file));
struct fuse_file *ff = file->private_data;
WARN_ON(req->max_pages);
spin_lock(&fi->lock);
memset(req, 0, sizeof(*req));
fuse_request_init(req, NULL, NULL, 0);
BUG_ON(ff->reserved_req);
ff->reserved_req = req;
wake_up_all(&fc->reserved_req_waitq);
spin_unlock(&fi->lock);
fput(file);
}
/* /*
* Gets a requests for a file operation, always succeeds * Gets a requests for a file operation, always succeeds
* *
...@@ -301,25 +255,18 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) ...@@ -301,25 +255,18 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
* filesystem should not have it's own file open. If deadlock is * filesystem should not have it's own file open. If deadlock is
* intentional, it can still be broken by "aborting" the filesystem. * intentional, it can still be broken by "aborting" the filesystem.
*/ */
struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc)
struct file *file)
{ {
struct fuse_req *req; struct fuse_req *req;
atomic_inc(&fc->num_waiting); atomic_inc(&fc->num_waiting);
wait_event(fc->blocked_waitq, fc->initialized); req = __fuse_request_alloc(0, GFP_KERNEL | __GFP_NOFAIL);
/* Matches smp_wmb() in fuse_set_initialized() */
smp_rmb();
req = fuse_request_alloc(0);
if (!req)
req = get_reserved_req(fc, file);
req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid()); req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid()); req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
__set_bit(FR_WAITING, &req->flags); __set_bit(FR_WAITING, &req->flags);
__clear_bit(FR_BACKGROUND, &req->flags);
return req; return req;
} }
...@@ -342,10 +289,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) ...@@ -342,10 +289,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
fuse_drop_waiting(fc); fuse_drop_waiting(fc);
} }
if (req->stolen_file) fuse_request_free(req);
put_reserved_req(fc, req);
else
fuse_request_free(req);
} }
} }
EXPORT_SYMBOL_GPL(fuse_put_request); EXPORT_SYMBOL_GPL(fuse_put_request);
...@@ -719,7 +663,7 @@ void fuse_force_forget(struct file *file, u64 nodeid) ...@@ -719,7 +663,7 @@ void fuse_force_forget(struct file *file, u64 nodeid)
memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, sizeof(inarg));
inarg.nlookup = 1; inarg.nlookup = 1;
req = fuse_get_req_nofail_nopages(fc, file); req = fuse_get_req_nofail_nopages(fc);
req->in.h.opcode = FUSE_FORGET; req->in.h.opcode = FUSE_FORGET;
req->in.h.nodeid = nodeid; req->in.h.nodeid = nodeid;
req->in.numargs = 1; req->in.numargs = 1;
......
...@@ -432,7 +432,7 @@ static int fuse_flush(struct file *file, fl_owner_t id) ...@@ -432,7 +432,7 @@ static int fuse_flush(struct file *file, fl_owner_t id)
if (err) if (err)
return err; return err;
req = fuse_get_req_nofail_nopages(fc, file); req = fuse_get_req_nofail_nopages(fc);
memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, sizeof(inarg));
inarg.fh = ff->fh; inarg.fh = ff->fh;
inarg.lock_owner = fuse_lock_owner_id(fc, id); inarg.lock_owner = fuse_lock_owner_id(fc, id);
......
...@@ -435,8 +435,6 @@ struct fuse_req { ...@@ -435,8 +435,6 @@ struct fuse_req {
/** Request completion callback */ /** Request completion callback */
void (*end)(struct fuse_conn *, struct fuse_req *); void (*end)(struct fuse_conn *, struct fuse_req *);
/** Request is stolen from fuse_file->reserved_req */
struct file *stolen_file;
}; };
struct fuse_iqueue { struct fuse_iqueue {
...@@ -580,9 +578,6 @@ struct fuse_conn { ...@@ -580,9 +578,6 @@ struct fuse_conn {
/** waitq for blocked connection */ /** waitq for blocked connection */
wait_queue_head_t blocked_waitq; wait_queue_head_t blocked_waitq;
/** waitq for reserved requests */
wait_queue_head_t reserved_req_waitq;
/** Connection established, cleared on umount, connection /** Connection established, cleared on umount, connection
abort and device release */ abort and device release */
unsigned connected; unsigned connected;
...@@ -927,8 +922,7 @@ void __fuse_get_request(struct fuse_req *req); ...@@ -927,8 +922,7 @@ void __fuse_get_request(struct fuse_req *req);
/** /**
* Gets a requests for a file operation, always succeeds * Gets a requests for a file operation, always succeeds
*/ */
struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc);
struct file *file);
/** /**
* Decrement reference count of a request. If count goes to zero free * Decrement reference count of a request. If count goes to zero free
......
...@@ -617,7 +617,6 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns) ...@@ -617,7 +617,6 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns)
refcount_set(&fc->count, 1); refcount_set(&fc->count, 1);
atomic_set(&fc->dev_count, 1); atomic_set(&fc->dev_count, 1);
init_waitqueue_head(&fc->blocked_waitq); init_waitqueue_head(&fc->blocked_waitq);
init_waitqueue_head(&fc->reserved_req_waitq);
fuse_iqueue_init(&fc->iq); fuse_iqueue_init(&fc->iq);
INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->bg_queue);
INIT_LIST_HEAD(&fc->entry); INIT_LIST_HEAD(&fc->entry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment