Fix possible double lock in certain cases if request is interrupted
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 19 Jan 2007 22:26:39 +0000 (22:26 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 19 Jan 2007 22:26:39 +0000 (22:26 +0000)
ChangeLog
lib/fuse.c

index c40b3c30a308e1e71dedce46c2d9671dda36b85a..d9558ad17da65a8fb10b9c12cc791fe3ef57b3ab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
        * Build fix for 2.6.16 vanila and 2.6.15 FC5 kernels.  Patch from
        Ian Abbott
 
+       * Fix possible double lock in certain cases if request is
+       interrupted
+
 2007-01-18  Miklos Szeredi <miklos@szeredi.hu>
 
        * Fix abort in fuse_new() compatibility API for opts == NULL case.
index 994a31f773dc341f4693f5e23b1f6e8a8fccfb05..e6e2a7ddabc8f28f4705ad03b0f684806e48f3e2 100644 (file)
@@ -1437,16 +1437,14 @@ static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
         if (f->conf.kernel_cache)
             fi->keep_cache = 1;
 
-        pthread_mutex_lock(&f->lock);
         if (fuse_reply_create(req, &e, fi) == -ENOENT) {
             /* The open syscall was interrupted, so it must be cancelled */
             if(f->op.release)
                 fuse_do_release(f, req, path, fi);
-            pthread_mutex_unlock(&f->lock);
             forget_node(f, e.ino, 1);
         } else {
-            struct node *node = get_node(f, e.ino);
-            node->open_count ++;
+            pthread_mutex_lock(&f->lock);
+            get_node(f, e.ino)->open_count ++;
             pthread_mutex_unlock(&f->lock);
         }
     } else
@@ -1476,10 +1474,12 @@ static void open_auto_cache(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
             struct stat stbuf;
             int err;
 
+            pthread_mutex_unlock(&f->lock);
             if (f->op.fgetattr)
                 err = fuse_do_fgetattr(f, req, path, &stbuf, fi);
             else
                 err = fuse_do_getattr(f, req, path, &stbuf);
+            pthread_mutex_lock(&f->lock);
 
             if (!err)
                 update_stat(node, &stbuf);
@@ -1750,7 +1750,6 @@ static void fuse_opendir(fuse_req_t req, fuse_ino_t ino,
             dh->fh = fi.fh;
         }
         if (!err) {
-            pthread_mutex_lock(&f->lock);
             if (fuse_reply_open(req, llfi) == -ENOENT) {
                 /* The opendir syscall was interrupted, so it must be
                    cancelled */
@@ -1759,7 +1758,6 @@ static void fuse_opendir(fuse_req_t req, fuse_ino_t ino,
                 pthread_mutex_destroy(&dh->lock);
                 free(dh);
             }
-            pthread_mutex_unlock(&f->lock);
         } else {
             reply_err(req, err);
             free(dh);