aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/dev.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index c78f60e1ba5d..cc6c2908fb12 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -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)