diff options
| -rw-r--r-- | fs/fuse/dev.c | 14 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 16 |
2 files changed, 19 insertions, 11 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 4f1ca7b119ed..bc8a3846a4bf 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -181,7 +181,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
| 181 | */ | 181 | */ |
| 182 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) | 182 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
| 183 | { | 183 | { |
| 184 | req->finished = 1; | 184 | req->state = FUSE_REQ_FINISHED; |
| 185 | spin_unlock(&fuse_lock); | 185 | spin_unlock(&fuse_lock); |
| 186 | if (req->background) { | 186 | if (req->background) { |
| 187 | down_read(&fc->sbput_sem); | 187 | down_read(&fc->sbput_sem); |
| @@ -250,10 +250,10 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | |||
| 250 | 250 | ||
| 251 | spin_unlock(&fuse_lock); | 251 | spin_unlock(&fuse_lock); |
| 252 | block_sigs(&oldset); | 252 | block_sigs(&oldset); |
| 253 | wait_event_interruptible(req->waitq, req->finished); | 253 | wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED); |
| 254 | restore_sigs(&oldset); | 254 | restore_sigs(&oldset); |
| 255 | spin_lock(&fuse_lock); | 255 | spin_lock(&fuse_lock); |
| 256 | if (req->finished) | 256 | if (req->state == FUSE_REQ_FINISHED) |
| 257 | return; | 257 | return; |
| 258 | 258 | ||
| 259 | req->out.h.error = -EINTR; | 259 | req->out.h.error = -EINTR; |
| @@ -268,10 +268,10 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | |||
| 268 | wait_event(req->waitq, !req->locked); | 268 | wait_event(req->waitq, !req->locked); |
| 269 | spin_lock(&fuse_lock); | 269 | spin_lock(&fuse_lock); |
| 270 | } | 270 | } |
| 271 | if (!req->sent && !list_empty(&req->list)) { | 271 | if (req->state == FUSE_REQ_PENDING) { |
| 272 | list_del(&req->list); | 272 | list_del(&req->list); |
| 273 | __fuse_put_request(req); | 273 | __fuse_put_request(req); |
| 274 | } else if (!req->finished && req->sent) | 274 | } else if (req->state == FUSE_REQ_SENT) |
| 275 | background_request(fc, req); | 275 | background_request(fc, req); |
| 276 | } | 276 | } |
| 277 | 277 | ||
| @@ -306,6 +306,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | |||
| 306 | fc->outstanding_debt++; | 306 | fc->outstanding_debt++; |
| 307 | } | 307 | } |
| 308 | list_add_tail(&req->list, &fc->pending); | 308 | list_add_tail(&req->list, &fc->pending); |
| 309 | req->state = FUSE_REQ_PENDING; | ||
| 309 | wake_up(&fc->waitq); | 310 | wake_up(&fc->waitq); |
| 310 | } | 311 | } |
| 311 | 312 | ||
| @@ -639,6 +640,7 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, | |||
| 639 | goto err_unlock; | 640 | goto err_unlock; |
| 640 | 641 | ||
| 641 | req = list_entry(fc->pending.next, struct fuse_req, list); | 642 | req = list_entry(fc->pending.next, struct fuse_req, list); |
| 643 | req->state = FUSE_REQ_READING; | ||
| 642 | list_del_init(&req->list); | 644 | list_del_init(&req->list); |
| 643 | 645 | ||
| 644 | in = &req->in; | 646 | in = &req->in; |
| @@ -672,7 +674,7 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, | |||
| 672 | if (!req->isreply) | 674 | if (!req->isreply) |
| 673 | request_end(fc, req); | 675 | request_end(fc, req); |
| 674 | else { | 676 | else { |
| 675 | req->sent = 1; | 677 | req->state = FUSE_REQ_SENT; |
| 676 | list_add_tail(&req->list, &fc->processing); | 678 | list_add_tail(&req->list, &fc->processing); |
| 677 | spin_unlock(&fuse_lock); | 679 | spin_unlock(&fuse_lock); |
| 678 | } | 680 | } |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 27937e8018eb..8cc87ebeed2e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -111,6 +111,15 @@ struct fuse_out { | |||
| 111 | struct fuse_arg args[3]; | 111 | struct fuse_arg args[3]; |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | /** The request state */ | ||
| 115 | enum fuse_req_state { | ||
| 116 | FUSE_REQ_INIT = 0, | ||
| 117 | FUSE_REQ_PENDING, | ||
| 118 | FUSE_REQ_READING, | ||
| 119 | FUSE_REQ_SENT, | ||
| 120 | FUSE_REQ_FINISHED | ||
| 121 | }; | ||
| 122 | |||
| 114 | /** | 123 | /** |
| 115 | * A request to the client | 124 | * A request to the client |
| 116 | */ | 125 | */ |
| @@ -140,11 +149,8 @@ struct fuse_req { | |||
| 140 | /** Data is being copied to/from the request */ | 149 | /** Data is being copied to/from the request */ |
| 141 | unsigned locked:1; | 150 | unsigned locked:1; |
| 142 | 151 | ||
| 143 | /** Request has been sent to userspace */ | 152 | /** State of the request */ |
| 144 | unsigned sent:1; | 153 | enum fuse_req_state state; |
| 145 | |||
| 146 | /** The request is finished */ | ||
| 147 | unsigned finished:1; | ||
| 148 | 154 | ||
| 149 | /** The request input */ | 155 | /** The request input */ |
| 150 | struct fuse_in in; | 156 | struct fuse_in in; |
