summaryrefslogtreecommitdiffstats
path: root/fs/fuse/dev.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2015-07-01 16:26:01 +0200
committerMiklos Szeredi <mszeredi@suse.cz>2015-07-01 16:26:01 +0200
commit33e14b4dfdc477344efbcd9b4218f2b350f0f893 (patch)
tree8f56045f3f3de4f5e1fc42fe0d03e48c1ede57c4 /fs/fuse/dev.c
parent7a3b2c754749c73b4a255b2a1070c24dba589098 (diff)
downloadop-kernel-dev-33e14b4dfdc477344efbcd9b4218f2b350f0f893.zip
op-kernel-dev-33e14b4dfdc477344efbcd9b4218f2b350f0f893.tar.gz
fuse: req state use flags
Use flags for representing the state in fuse_req. This is needed since req->list will be protected by different locks in different states, hence we'll want the state itself to be split into distinct bits, each protected with the relevant lock in that state. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/dev.c')
-rw-r--r--fs/fuse/dev.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index e5c541b..f1e2efd 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -48,6 +48,7 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages,
req->pages = pages;
req->page_descs = page_descs;
req->max_pages = npages;
+ __set_bit(FR_PENDING, &req->flags);
}
static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
@@ -380,8 +381,10 @@ __releases(fc->lock)
req->end = NULL;
list_del_init(&req->list);
list_del_init(&req->intr_entry);
+ WARN_ON(test_bit(FR_PENDING, &req->flags));
+ WARN_ON(test_bit(FR_SENT, &req->flags));
smp_wmb();
- req->state = FUSE_REQ_FINISHED;
+ set_bit(FR_FINISHED, &req->flags);
if (test_bit(FR_BACKGROUND, &req->flags)) {
clear_bit(FR_BACKGROUND, &req->flags);
if (fc->num_background == fc->max_background)
@@ -421,13 +424,13 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
if (!fc->no_interrupt) {
/* Any signal may interrupt this */
err = wait_event_interruptible(req->waitq,
- req->state == FUSE_REQ_FINISHED);
+ test_bit(FR_FINISHED, &req->flags));
if (!err)
return;
spin_lock(&fc->lock);
set_bit(FR_INTERRUPTED, &req->flags);
- if (req->state == FUSE_REQ_SENT)
+ if (test_bit(FR_SENT, &req->flags))
queue_interrupt(fc, req);
spin_unlock(&fc->lock);
}
@@ -438,7 +441,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
/* Only fatal signals may interrupt this */
block_sigs(&oldset);
err = wait_event_interruptible(req->waitq,
- req->state == FUSE_REQ_FINISHED);
+ test_bit(FR_FINISHED, &req->flags));
restore_sigs(&oldset);
if (!err)
@@ -446,7 +449,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
spin_lock(&fc->lock);
/* Request is not yet in userspace, bail out */
- if (req->state == FUSE_REQ_PENDING) {
+ if (test_bit(FR_PENDING, &req->flags)) {
list_del(&req->list);
spin_unlock(&fc->lock);
__fuse_put_request(req);
@@ -460,7 +463,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
* Either request is already in userspace, or it was forced.
* Wait it out.
*/
- wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
+ wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
}
static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
@@ -1273,7 +1276,7 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
}
req = list_entry(fc->pending.next, struct fuse_req, list);
- req->state = FUSE_REQ_IO;
+ clear_bit(FR_PENDING, &req->flags);
list_move(&req->list, &fc->io);
in = &req->in;
@@ -1308,7 +1311,7 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
if (!test_bit(FR_ISREPLY, &req->flags)) {
request_end(fc, req);
} else {
- req->state = FUSE_REQ_SENT;
+ set_bit(FR_SENT, &req->flags);
list_move_tail(&req->list, &fc->processing);
if (test_bit(FR_INTERRUPTED, &req->flags))
queue_interrupt(fc, req);
@@ -1904,7 +1907,7 @@ static ssize_t fuse_dev_do_write(struct fuse_conn *fc,
return nbytes;
}
- req->state = FUSE_REQ_IO;
+ clear_bit(FR_SENT, &req->flags);
list_move(&req->list, &fc->io);
req->out.h = oh;
set_bit(FR_LOCKED, &req->flags);
@@ -2059,6 +2062,8 @@ __acquires(fc->lock)
struct fuse_req *req;
req = list_entry(head->next, struct fuse_req, list);
req->out.h.error = -ECONNABORTED;
+ clear_bit(FR_PENDING, &req->flags);
+ clear_bit(FR_SENT, &req->flags);
request_end(fc, req);
spin_lock(&fc->lock);
}
OpenPOWER on IntegriCloud