+2004-08-16 Miklos Szeredi <miklos@szeredi.hu>
+
+ * 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 <miklos@szeredi.hu>
* Check permissions in setattr if 'default_permissions' flag is
}
/* 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;
}
}
-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();
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);
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)
{
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);
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
*/