diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index e5c541b7c7af268ad9ee4c2983e748c59d84d46b..f1e2efd6b1862c1449e4bc4c25fce2ebfc62d87d 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); } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d0c23d075427f2eeaf00625778bd2310ea5a04af..64835cf589363efa283550ab465faec6bf98fd22 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1743,7 +1743,7 @@ static bool fuse_writepage_in_flight(struct fuse_req *new_req, } } - if (old_req->num_pages == 1 && old_req->state == FUSE_REQ_PENDING) { + if (old_req->num_pages == 1 && test_bit(FR_PENDING, &old_req->flags)) { struct backing_dev_info *bdi = inode_to_bdi(page->mapping->host); copy_highpage(old_req->pages[0], page); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 3fd65f613515fa2927ab71e699e811fb2ca7c5e8..8eaf3b0de033792ef5db0d159ba5bff4251bd47a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -241,14 +241,6 @@ struct fuse_args { #define FUSE_ARGS(args) struct fuse_args args = {} -/** The request state */ -enum fuse_req_state { - FUSE_REQ_PENDING = 0, - FUSE_REQ_IO, - FUSE_REQ_SENT, - FUSE_REQ_FINISHED -}; - /** The request IO state (for asynchronous processing) */ struct fuse_io_priv { int async; @@ -274,6 +266,9 @@ struct fuse_io_priv { * FR_ABORTED: the request was aborted * FR_INTERRUPTED: the request has been interrupted * FR_LOCKED: data is being copied to/from the request + * FR_PENDING: request is not yet in userspace + * FR_SENT: request is in userspace, waiting for an answer + * FR_FINISHED: request is finished */ enum fuse_req_flag { FR_ISREPLY, @@ -283,6 +278,9 @@ enum fuse_req_flag { FR_ABORTED, FR_INTERRUPTED, FR_LOCKED, + FR_PENDING, + FR_SENT, + FR_FINISHED, }; /** @@ -309,9 +307,6 @@ struct fuse_req { /* Request flags, updated with test/set/clear_bit() */ unsigned long flags; - /** State of the request */ - enum fuse_req_state state; - /** The request input */ struct fuse_in in;