From dff627ab62f401e5fc02ddb8cad21ad04c5d9190 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 16 Aug 2004 13:41:19 +0000 Subject: [PATCH] fix --- ChangeLog | 6 ++++++ kernel/dev.c | 35 +++++++++++++++++++++++++++-------- kernel/dir.c | 2 +- kernel/file.c | 2 +- kernel/fuse_i.h | 7 +++++++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34694d6..7637b9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-08-16 Miklos Szeredi + + * Change release method to be non-interruptible. Fixes bug + causing missing release() call when program which has opened files + is killed (reported by Franco Broi and David Shaw) + 2004-07-26 Miklos Szeredi * Check permissions in setattr if 'default_permissions' flag is diff --git a/kernel/dev.c b/kernel/dev.c index 2f778fc..7f6900b 100644 --- a/kernel/dev.c +++ b/kernel/dev.c @@ -62,12 +62,17 @@ static int request_restartable(enum fuse_opcode opcode) } /* Called with fuse_lock held. Releases, and then reaquires it. */ -static void request_wait_answer(struct fuse_req *req) +static void request_wait_answer(struct fuse_req *req, int interruptible) { int intr; spin_unlock(&fuse_lock); - intr = wait_event_interruptible(req->waitq, req->finished); + if (interruptible) + intr = wait_event_interruptible(req->waitq, req->finished); + else { + wait_event(req->waitq, req->finished); + intr = 0; + } spin_lock(&fuse_lock); if(!intr) return; @@ -112,14 +117,17 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) } } -void request_send(struct fuse_conn *fc, struct fuse_in *in, - struct fuse_out *out) +void __request_send(struct fuse_conn *fc, struct fuse_in *in, + struct fuse_out *out, int interruptible) { struct fuse_req *req; - out->h.error = -ERESTARTSYS; - if(down_interruptible(&fc->outstanding)) - return; + if (interruptible) { + out->h.error = -ERESTARTSYS; + if(down_interruptible(&fc->outstanding)) + return; + } else + down(&fc->outstanding); out->h.error = -ENOMEM; req = request_new(); @@ -135,7 +143,7 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in, in->h.unique = get_unique(fc); list_add_tail(&req->list, &fc->pending); wake_up(&fc->waitq); - request_wait_answer(req); + request_wait_answer(req, interruptible); list_del(&req->list); } spin_unlock(&fuse_lock); @@ -145,6 +153,17 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in, up(&fc->outstanding); } +void request_send(struct fuse_conn *fc, struct fuse_in *in, + struct fuse_out *out) +{ + __request_send(fc, in, out, 1); +} + +void request_send_nonint(struct fuse_conn *fc, struct fuse_in *in, + struct fuse_out *out) +{ + __request_send(fc, in, out, 0); +} static inline void destroy_request(struct fuse_req *req) { diff --git a/kernel/dir.c b/kernel/dir.c index 1de0058..4a140a5 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -635,7 +635,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) struct fuse_setattr_out outarg; if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { - err = inode_change_ok(inode, attr); + int err = inode_change_ok(inode, attr); if (err) return err; } diff --git a/kernel/file.c b/kernel/file.c index fdd4d0b..2ba3163 100644 --- a/kernel/file.c +++ b/kernel/file.c @@ -118,7 +118,7 @@ static int fuse_release(struct inode *inode, struct file *file) in.numargs = 1; in.args[0].size = sizeof(inarg); in.args[0].value = &inarg; - request_send(fc, &in, &out); + request_send_nonint(fc, &in, &out); if (out.h.error == -ENOSYS) { fc->oldrelease = 1; return fuse_release_old(inode, file); diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index 7c67e49..c81c41a 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -220,6 +220,13 @@ void fuse_fs_cleanup(void); void request_send(struct fuse_conn *fc, struct fuse_in *in, struct fuse_out *out); +/** + * Send a non-interruptible request + * + */ +void request_send_nonint(struct fuse_conn *fc, struct fuse_in *in, + struct fuse_out *out); + /** * Send a request for which a reply is not expected */ -- 2.30.2