aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/dev.c')
-rw-r--r--fs/fuse/dev.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 3ad22beb24c..db534bcde45 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -129,7 +129,7 @@ static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
129 struct fuse_file *ff = file->private_data; 129 struct fuse_file *ff = file->private_data;
130 130
131 do { 131 do {
132 wait_event(fc->blocked_waitq, ff->reserved_req); 132 wait_event(fc->reserved_req_waitq, ff->reserved_req);
133 spin_lock(&fc->lock); 133 spin_lock(&fc->lock);
134 if (ff->reserved_req) { 134 if (ff->reserved_req) {
135 req = ff->reserved_req; 135 req = ff->reserved_req;
@@ -155,7 +155,7 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
155 fuse_request_init(req); 155 fuse_request_init(req);
156 BUG_ON(ff->reserved_req); 156 BUG_ON(ff->reserved_req);
157 ff->reserved_req = req; 157 ff->reserved_req = req;
158 wake_up(&fc->blocked_waitq); 158 wake_up_all(&fc->reserved_req_waitq);
159 spin_unlock(&fc->lock); 159 spin_unlock(&fc->lock);
160 fput(file); 160 fput(file);
161} 161}
@@ -224,13 +224,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
224 fc->blocked = 0; 224 fc->blocked = 0;
225 wake_up_all(&fc->blocked_waitq); 225 wake_up_all(&fc->blocked_waitq);
226 } 226 }
227 if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
228 clear_bdi_congested(&fc->bdi, READ);
229 clear_bdi_congested(&fc->bdi, WRITE);
230 }
227 fc->num_background--; 231 fc->num_background--;
228 } 232 }
229 spin_unlock(&fc->lock); 233 spin_unlock(&fc->lock);
230 dput(req->dentry);
231 mntput(req->vfsmount);
232 if (req->file)
233 fput(req->file);
234 wake_up(&req->waitq); 234 wake_up(&req->waitq);
235 if (end) 235 if (end)
236 end(fc, req); 236 end(fc, req);
@@ -273,28 +273,41 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
273 queue_interrupt(fc, req); 273 queue_interrupt(fc, req);
274 } 274 }
275 275
276 if (req->force) { 276 if (!req->force) {
277 spin_unlock(&fc->lock);
278 wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
279 spin_lock(&fc->lock);
280 } else {
281 sigset_t oldset; 277 sigset_t oldset;
282 278
283 /* Only fatal signals may interrupt this */ 279 /* Only fatal signals may interrupt this */
284 block_sigs(&oldset); 280 block_sigs(&oldset);
285 wait_answer_interruptible(fc, req); 281 wait_answer_interruptible(fc, req);
286 restore_sigs(&oldset); 282 restore_sigs(&oldset);
283
284 if (req->aborted)
285 goto aborted;
286 if (req->state == FUSE_REQ_FINISHED)
287 return;
288
289 /* Request is not yet in userspace, bail out */
290 if (req->state == FUSE_REQ_PENDING) {
291 list_del(&req->list);
292 __fuse_put_request(req);
293 req->out.h.error = -EINTR;
294 return;
295 }
287 } 296 }
288 297
289 if (req->aborted) 298 /*
290 goto aborted; 299 * Either request is already in userspace, or it was forced.
291 if (req->state == FUSE_REQ_FINISHED) 300 * Wait it out.
292 return; 301 */
302 spin_unlock(&fc->lock);
303 wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
304 spin_lock(&fc->lock);
293 305
294 req->out.h.error = -EINTR; 306 if (!req->aborted)
295 req->aborted = 1; 307 return;
296 308
297 aborted: 309 aborted:
310 BUG_ON(req->state != FUSE_REQ_FINISHED);
298 if (req->locked) { 311 if (req->locked) {
299 /* This is uninterruptible sleep, because data is 312 /* This is uninterruptible sleep, because data is
300 being copied to/from the buffers of req. During 313 being copied to/from the buffers of req. During
@@ -305,14 +318,6 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
305 wait_event(req->waitq, !req->locked); 318 wait_event(req->waitq, !req->locked);
306 spin_lock(&fc->lock); 319 spin_lock(&fc->lock);
307 } 320 }
308 if (req->state == FUSE_REQ_PENDING) {
309 list_del(&req->list);
310 __fuse_put_request(req);
311 } else if (req->state == FUSE_REQ_SENT) {
312 spin_unlock(&fc->lock);
313 wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
314 spin_lock(&fc->lock);
315 }
316} 321}
317 322
318static unsigned len_args(unsigned numargs, struct fuse_arg *args) 323static unsigned len_args(unsigned numargs, struct fuse_arg *args)
@@ -378,6 +383,10 @@ static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
378 fc->num_background++; 383 fc->num_background++;
379 if (fc->num_background == FUSE_MAX_BACKGROUND) 384 if (fc->num_background == FUSE_MAX_BACKGROUND)
380 fc->blocked = 1; 385 fc->blocked = 1;
386 if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
387 set_bdi_congested(&fc->bdi, READ);
388 set_bdi_congested(&fc->bdi, WRITE);
389 }
381 390
382 queue_request(fc, req); 391 queue_request(fc, req);
383 spin_unlock(&fc->lock); 392 spin_unlock(&fc->lock);
@@ -738,11 +747,12 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
738 fuse_copy_finish(&cs); 747 fuse_copy_finish(&cs);
739 spin_lock(&fc->lock); 748 spin_lock(&fc->lock);
740 req->locked = 0; 749 req->locked = 0;
741 if (!err && req->aborted) 750 if (req->aborted) {
742 err = -ENOENT; 751 request_end(fc, req);
752 return -ENODEV;
753 }
743 if (err) { 754 if (err) {
744 if (!req->aborted) 755 req->out.h.error = -EIO;
745 req->out.h.error = -EIO;
746 request_end(fc, req); 756 request_end(fc, req);
747 return err; 757 return err;
748 } 758 }