update flush changes
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 11 May 2007 09:19:36 +0000 (09:19 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 11 May 2007 09:19:36 +0000 (09:19 +0000)
ChangeLog
lib/fuse.c
lib/modules/subdir.c

index c2baf3712458c9c7f44fbcd19746d2f1248e791f..d43e088a7ebadf6dcad762d6bf31128ea2ade93b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,9 @@
        * libfuse: fix return value of fuse_loop()/fuse_loop_mt().
        Error reported by Csaba Henk, fix by Miklos Szeredi
 
-       * libfuse: various flush related fixes
+       * libfuse: fix unlock in flush
+
+       * libfuse: do unlocking on RELEASE+FLUSH
  
 2007-05-03  Miklos Szeredi <miklos@szeredi.hu>
 
index 817b16f6b3a53236fe7acbb0900d6cf832ae16c1..42866f1567f25bd42f113dad64858d1fd0fdab55 100644 (file)
@@ -2579,16 +2579,35 @@ static void lock_to_flock(struct lock *lock, struct flock *flock)
     flock->l_pid = lock->pid;
 }
 
-static void fuse_flush_common(struct fuse_fs *fs, const char *path,
-                              struct fuse_file_info *fi,
-                              struct flock *lock, int *err, int *errlock)
+static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
+                             const char *path, struct fuse_file_info *fi)
 {
-    *err = fuse_fs_flush(fs, path, fi);
+    struct fuse_intr_data d;
+    struct flock lock;
+    struct lock l;
+    int err;
+    int errlock;
+
+    fuse_prepare_interrupt(f, req, &d);
+    memset(&lock, 0, sizeof(lock));
+    lock.l_type = F_UNLCK;
+    lock.l_whence = SEEK_SET;
+    err = fuse_fs_flush(f->fs, path, fi);
+    errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
+    fuse_finish_interrupt(f, req, &d);
+
+    if (errlock != -ENOSYS) {
+        flock_to_lock(&lock, &l);
+        l.owner = fi->lock_owner;
+        pthread_mutex_lock(&f->lock);
+        locks_insert(get_node(f, ino), &l);
+        pthread_mutex_unlock(&f->lock);
 
-    memset(lock, 0, sizeof(*lock));
-    lock->l_type = F_UNLCK;
-    lock->l_whence = SEEK_SET;
-    *errlock = fuse_fs_lock(fs, path, fi, F_SETLK, lock);
+        /* if op.lock() is defined FLUSH is needed regardless of op.flush() */
+        if (err == -ENOSYS)
+            err = 0;
+    }
+    return err;
 }
 
 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
@@ -2596,41 +2615,27 @@ static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
 {
     struct fuse *f = req_fuse_prepare(req);
     struct fuse_intr_data d;
-    struct flock lock;
-    struct lock l;
     char *path;
     int err = 0;
-    int errlock = -ENOSYS;
 
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, ino);
-    if (!path)
-        path = "-";
     if (f->conf.debug) {
         printf("RELEASE%s[%llu] flags: 0x%x\n", fi->flush ? "+FLUSH" : "", 
                (unsigned long long) fi->fh, fi->flags);
         fflush(stdout);
     }
-    fuse_prepare_interrupt(f, req, &d);
+
     if (fi->flush) {
-        fuse_flush_common(f->fs, path, fi, &lock, &err, &errlock);
-        if (err == -ENOSYS && errlock == -ENOSYS)
+        err = fuse_flush_common(f, req, ino, path, fi);
+        if (err == -ENOSYS)
             err = 0;
-        else if (err == -ENOSYS || !err)
-            err = errlock;
     }
+
+    fuse_prepare_interrupt(f, req, &d);
     fuse_do_release(f, ino, path, fi);
     fuse_finish_interrupt(f, req, &d);
-    if (errlock != -ENOSYS) {
-        flock_to_lock(&lock, &l);
-        l.owner = fi->lock_owner;
-        pthread_mutex_lock(&f->lock);
-        locks_insert(get_node(f, ino), &l);
-        pthread_mutex_unlock(&f->lock);
-    }
-
-    if (path)
-        free(path);
+    free(path);
     pthread_rwlock_unlock(&f->tree_lock);
 
     reply_err(req, err);
@@ -2640,36 +2645,17 @@ static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
                        struct fuse_file_info *fi)
 {
     struct fuse *f = req_fuse_prepare(req);
-    struct fuse_intr_data d;
-    struct flock lock;
-    struct lock l;
     char *path;
     int err;
-    int errlock;
 
-    err = -ENOENT;
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, ino);
     if (path && f->conf.debug) {
         printf("FLUSH[%llu]\n", (unsigned long long) fi->fh);
         fflush(stdout);
     }
-    fuse_prepare_interrupt(f, req, &d);
-    fuse_flush_common(f->fs, path ? path : "-" , fi, &lock, &err, &errlock);
-    fuse_finish_interrupt(f, req, &d);
-    if (errlock != -ENOSYS) {
-        flock_to_lock(&lock, &l);
-        l.owner = fi->lock_owner;
-        pthread_mutex_lock(&f->lock);
-        locks_insert(get_node(f, ino), &l);
-        pthread_mutex_unlock(&f->lock);
-
-        /* if op.lock() is defined FLUSH is needed regardless of op.flush() */
-        if (err == -ENOSYS)
-            err = 0;
-    }
-    if (path)
-        free(path);
+    err = fuse_flush_common(f, req, ino, path, fi);
+    free(path);
     pthread_rwlock_unlock(&f->tree_lock);
     reply_err(req, err);
 }
index 8174e34f6d2194cd527a7ac2b0d52b7c7faf7c00..1d0677e25730faf2757fdc91876d383c4842a7d5 100644 (file)
@@ -118,7 +118,7 @@ static void transform_symlink(struct subdir *d, const char *path,
         return;
 
     strip_common(&l, &path);
-    if (l - buf < d->baselen)
+    if (l - buf < (long) d->baselen)
         return;
 
     dotdots = count_components(path);