Add support for FLUSH+RELEASE operation
authorMiklos Szeredi <miklos@szeredi.hu>
Sun, 1 Oct 2006 14:41:04 +0000 (14:41 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Sun, 1 Oct 2006 14:41:04 +0000 (14:41 +0000)
ChangeLog
kernel/fuse_kernel.h
lib/fuse.c
lib/fuse_lowlevel.c

index 0478639e685b856d29e3c844f81d5246ec98a1dd..123457607d873dc879971a84cfe8e27b7431efaa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2006-10-01  Miklos Szeredi <miklos@szeredi.hu>
 
+       * Add support for FLUSH+RELEASE operation for FreeBSD.  Original
+       patch by Csaba Henk
+
        * Add init script to insert fuse module and mount the control
        filesystem.  The script is installed as /etc/init.d/fuse and on
        debian based systems (where update-rc.d is available) symlinks
index c2243d9e1998d50e860cd207bd03ae403d359fc9..94154b12ac006b35043de25c0db316c9d1b807e9 100644 (file)
@@ -50,7 +50,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 7
+#define FUSE_KERNEL_MINOR_VERSION 8
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -127,6 +127,11 @@ struct fuse_file_lock {
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
 
+/**
+ * Release flags
+ */
+#define FUSE_RELEASE_FLUSH     (1 << 0)
+
 enum fuse_opcode {
        FUSE_LOOKUP        = 1,
        FUSE_FORGET        = 2,  /* no reply */
@@ -241,7 +246,8 @@ struct fuse_open_out {
 struct fuse_release_in {
        __u64   fh;
        __u32   flags;
-       __u32   padding;
+       __u32   release_flags;
+       __u64   lock_owner;
 };
 
 struct fuse_flush_in {
index c28528eba06a2f05dec149ad47090ac9ba38bb16..c87bff3b4e09c9c5f6738d81cb1e13a6580c6f08 100644 (file)
@@ -583,6 +583,17 @@ static int fuse_do_open(struct fuse *f, fuse_req_t req, char *path,
     return res;
 }
 
+static int fuse_do_flush(struct fuse *f, fuse_req_t req, const char *path,
+                         struct fuse_file_info *fi)
+{
+    int res;
+    struct fuse_intr_data d;
+    fuse_prepare_interrupt(f, req, &d);
+    res = f->op.flush(path, fi);
+    fuse_finish_interrupt(f, req, &d);
+    return res;
+}
+
 static int fuse_do_statfs(struct fuse *f, fuse_req_t req, const char *path,
                           struct statvfs *buf)
 {
@@ -1628,14 +1639,17 @@ static void fuse_release(fuse_req_t req, fuse_ino_t ino,
     char *path;
     struct node *node;
     int unlink_hidden = 0;
+    int err = 0;
 
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, ino);
     if (f->conf.debug) {
-        printf("RELEASE[%llu] flags: 0x%x\n", (unsigned long long) fi->fh,
-               fi->flags);
+        printf("RELEASE%s[%llu] flags: 0x%x\n", fi->flush ? "+FLUSH" : "", 
+               (unsigned long long) fi->fh, fi->flags);
         fflush(stdout);
     }
+    if (fi->flush && path && f->op.flush)
+        err = fuse_do_flush(f, req, path, fi);
     if (f->op.release)
         fuse_compat_release(f, req, path, fi);
 
@@ -1656,7 +1670,7 @@ static void fuse_release(fuse_req_t req, fuse_ino_t ino,
         free(path);
     pthread_rwlock_unlock(&f->tree_lock);
 
-    reply_err(req, 0);
+    reply_err(req, err);
 }
 
 static void fuse_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
@@ -2277,12 +2291,8 @@ static void fuse_flush(fuse_req_t req, fuse_ino_t ino,
             fflush(stdout);
         }
         err = -ENOSYS;
-        if (f->op.flush) {
-            struct fuse_intr_data d;
-            fuse_prepare_interrupt(f, req, &d);
-            err = f->op.flush(path, fi);
-            fuse_finish_interrupt(f, req, &d);
-        }
+        if (f->op.flush)
+            err = fuse_do_flush(f, req, path, fi);
         free(path);
     }
     if (f->op.lock) {
index 4308a262246ae5a17bf4a2c64c0d8e25590ea728..f7de2c7ad380e26ce7e2d8f8dbb79dd8e262b3af 100644 (file)
@@ -643,6 +643,10 @@ static void do_release(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
     fi.flags = arg->flags;
     fi.fh = arg->fh;
     fi.fh_old = fi.fh;
+    if (req->f->conn.proto_minor >= 8) {
+        fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
+        fi.lock_owner = arg->lock_owner;
+    }
 
     if (req->f->op.release)
         req->f->op.release(req, nodeid, &fi);