Fix regression
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 2 Feb 2007 12:23:45 +0000 (12:23 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 2 Feb 2007 12:23:45 +0000 (12:23 +0000)
ChangeLog
include/fuse.h
lib/fuse.c

index e9d2bcd1cdb7e370e34a9d8ccba13d62b89d1bf6..8137979d615cccdf55eb909b3b7fea987a0606e0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-02-02  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Fix regression caused by "Fix possible double lock in certain
+       cases if request is interrupted" on 2007-01-19.  Reported by José
+       Antonio Sánchez
+
+2007-01-30  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Released 2.6.2
+
 2007-01-28  Miklos Szeredi <miklos@szeredi.hu>
 
        * kernel: fix BUG in control filesystem if it is umounted and
index 90c4d5d2c3caff4e8ed5b2cf964002580550533c..83b6f213c84c12b6a2f086f6071d1aa8ba8ceb49 100644 (file)
@@ -172,7 +172,6 @@ struct fuse_operations {
     int (*write) (const char *, const char *, size_t, off_t,
                   struct fuse_file_info *);
 
-    /** Just a placeholder, don't set */
     /** Get file system statistics
      *
      * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
index 3c5dc6cc7316ea2fe7bbf97d56643eb845abf953..f34c7cb8737e2089ccd1cde9802c71b6b9408ea8 100644 (file)
@@ -1437,13 +1437,15 @@ static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
         if (f->conf.kernel_cache)
             fi->keep_cache = 1;
 
+        /* see comment for open */
+        pthread_mutex_lock(&f->lock);
         if (fuse_reply_create(req, &e, fi) == -ENOENT) {
             /* The open syscall was interrupted, so it must be cancelled */
+            pthread_mutex_unlock(&f->lock);
             if(f->op.release)
                 fuse_do_release(f, req, path, fi);
             forget_node(f, e.ino, 1);
         } else {
-            pthread_mutex_lock(&f->lock);
             get_node(f, e.ino)->open_count++;
             pthread_mutex_unlock(&f->lock);
         }
@@ -1526,12 +1528,16 @@ static void fuse_open(fuse_req_t req, fuse_ino_t ino,
         if (f->conf.auto_cache)
             open_auto_cache(f, req, ino, path, fi);
 
+        /* The reply and the open count increase needs to be under a
+           single locked section, otherwise a release could come in
+           between and screw up the accounting */
+        pthread_mutex_lock(&f->lock);
         if (fuse_reply_open(req, fi) == -ENOENT) {
             /* The open syscall was interrupted, so it must be cancelled */
+            pthread_mutex_unlock(&f->lock);
             if(f->op.release && path != NULL)
                 fuse_compat_release(f, req, path, fi);
         } else {
-            pthread_mutex_lock(&f->lock);
             get_node(f, ino)->open_count++;
             pthread_mutex_unlock(&f->lock);
         }