fix
authorMiklos Szeredi <miklos@szeredi.hu>
Sat, 14 Jan 2006 14:47:21 +0000 (14:47 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Sat, 14 Jan 2006 14:47:21 +0000 (14:47 +0000)
ChangeLog
kernel/dev.c
kernel/fuse_i.h

index 5578982702785234689449ba33c7deb3b4d6be0d..a174eef53fc7b8c5950d4960a7b950a7ce505aec 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-01-14  Miklos Szeredi <miklos@szeredi.hu>
+
+       * 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 <miklos@szeredi.hu>
 
        * kernel: add necessary compile flags for 2.4.X/x86_64.
index 073333f710302c2fd8434610dfd8ee56b012c57d..3880f130a7d16801e1e62167301d271438c831bc 100644 (file)
@@ -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;
index 335b0c8aab8c1382966cfa14b4f74c66cfae17f4..84e17dc6c5fdfe4848f19798a3804b069ae4c656 100644 (file)
@@ -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;