From 9db5faa842b930ef2dd3557a8e26c34dfc94d6a8 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sat, 14 Jan 2006 14:47:21 +0000 Subject: [PATCH] fix --- ChangeLog | 11 +++++++++++ kernel/dev.c | 12 +++++------- kernel/fuse_i.h | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5578982..a174eef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-01-14 Miklos Szeredi + + * kernel: fix a couple of bugs + + * Order of request_end() and fuse_copy_finish() was wrong + + * request_end() used request pointer after decrementing refcount + + * Clearing ->connected or ->mounted connection flags could race + with setting other bitfields not protected with a lock + 2006-01-10 Miklos Szeredi * kernel: add necessary compile flags for 2.4.X/x86_64. diff --git a/kernel/dev.c b/kernel/dev.c index 073333f..3880f13 100644 --- a/kernel/dev.c +++ b/kernel/dev.c @@ -221,9 +221,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) */ static void request_end(struct fuse_conn *fc, struct fuse_req *req) { - int putback; req->finished = 1; - putback = atomic_dec_and_test(&req->count); spin_unlock(&fuse_lock); if (req->background) { down_read(&fc->sbput_sem); @@ -237,13 +235,11 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) { /* Special case for failed iget in CREATE */ u64 nodeid = req->in.h.nodeid; - __fuse_get_request(req); fuse_reset_request(req); fuse_send_forget(fc, req, nodeid, 1); - putback = 0; + return; } - if (putback) - fuse_putback_request(fc, req); + fuse_put_request(fc, req); } /* @@ -824,8 +820,10 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, list_del_init(&req->list); if (req->interrupted) { - request_end(fc, req); + spin_unlock(&fuse_lock); fuse_copy_finish(&cs); + spin_lock(&fuse_lock); + request_end(fc, req); return -ENOENT; } req->out.h = oh; diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index 335b0c8..84e17dc 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -315,10 +315,10 @@ struct fuse_conn { u64 reqctr; /** Mount is active */ - unsigned mounted : 1; + unsigned mounted; /** Connection established */ - unsigned connected : 1; + unsigned connected; /** Connection failed (version mismatch) */ unsigned conn_error : 1; -- 2.30.2