[patch 10/11] fuse: no abort on interrupt
From: Miklos Szeredi
Date: Fri Aug 03 2007 - 13:54:40 EST
From: Miklos Szeredi <mszeredi@xxxxxxx>
Don't set 'aborted' flag on a request if it's interrupted. We have to
wait for the answer anyway, and this would only a very little time
while copying the reply.
This means, that write() on the fuse device will not return -ENOENT
during normal operation, only if the filesystem is aborted by a forced
umount or through the fusectl interface.
This could simplify userspace code somewhat when backward
compatibility with earlier kernel versions is not required.
Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxx>
---
Index: linux/fs/fuse/dev.c
===================================================================
--- linux.orig/fs/fuse/dev.c 2007-08-03 18:37:24.000000000 +0200
+++ linux/fs/fuse/dev.c 2007-08-03 18:37:25.000000000 +0200
@@ -273,28 +273,41 @@ static void request_wait_answer(struct f
queue_interrupt(fc, req);
}
- if (req->force) {
- spin_unlock(&fc->lock);
- wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
- spin_lock(&fc->lock);
- } else {
+ if (!req->force) {
sigset_t oldset;
/* Only fatal signals may interrupt this */
block_sigs(&oldset);
wait_answer_interruptible(fc, req);
restore_sigs(&oldset);
+
+ if (req->aborted)
+ goto aborted;
+ if (req->state == FUSE_REQ_FINISHED)
+ return;
+
+ /* Request is not yet in userspace, bail out */
+ if (req->state == FUSE_REQ_PENDING) {
+ list_del(&req->list);
+ __fuse_put_request(req);
+ req->out.h.error = -EINTR;
+ return;
+ }
}
- if (req->aborted)
- goto aborted;
- if (req->state == FUSE_REQ_FINISHED)
- return;
+ /*
+ * Either request is already in userspace, or it was forced.
+ * Wait it out.
+ */
+ spin_unlock(&fc->lock);
+ wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
+ spin_lock(&fc->lock);
- req->out.h.error = -EINTR;
- req->aborted = 1;
+ if (!req->aborted)
+ return;
aborted:
+ BUG_ON(req->state != FUSE_REQ_FINISHED);
if (req->locked) {
/* This is uninterruptible sleep, because data is
being copied to/from the buffers of req. During
@@ -305,14 +318,6 @@ static void request_wait_answer(struct f
wait_event(req->waitq, !req->locked);
spin_lock(&fc->lock);
}
- if (req->state == FUSE_REQ_PENDING) {
- list_del(&req->list);
- __fuse_put_request(req);
- } else if (req->state == FUSE_REQ_SENT) {
- spin_unlock(&fc->lock);
- wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
- spin_lock(&fc->lock);
- }
}
static unsigned len_args(unsigned numargs, struct fuse_arg *args)
--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/