added fsync operation
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 12 Dec 2003 14:06:41 +0000 (14:06 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 12 Dec 2003 14:06:41 +0000 (14:06 +0000)
ChangeLog
example/fusexmp.c
example/hello.c
example/null.c
include/fuse.h
include/linux/fuse.h
kernel/file.c
lib/fuse.c

index ae9fdbb3a53d9a143757342aa25157d2269803e5..15efcd3714717abc781748c140efcbdc99a95468 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@
 
        * Make it compile on 2.4.19.  
 
-       * Add dummy fsync operation (write file failed on xemacs & vi)
+       * Add fsync operation (write file failed on xemacs & vi)
 
 2003-12-12  David McNab <david@rebirthing.co.nz>
 
index e783423e38d57a0fbcc55ddd0ecf6ab046b58f63..d97f3ca321724f93adae2010776f1a11752a8a19 100644 (file)
@@ -267,7 +267,9 @@ static struct fuse_operations xmp_oper = {
     read:      xmp_read,
     write:     xmp_write,
     statfs:    xmp_statfs,
-    release:   NULL
+    release:   NULL,
+    fsync:     NULL
+    
 };
 
 int main(int argc, char *argv[])
index cd8fb5d351e471b3e85048e7cd728ab0a3392f7a..6b461d0b01ced48d19002488fd17665cd1ba37b6 100644 (file)
@@ -86,7 +86,8 @@ static struct fuse_operations hello_oper = {
     read:      hello_read,
     write:     NULL,
     statfs:    NULL,
-    release:   NULL
+    release:   NULL,
+    fsync:     NULL
 };
 
 int main(int argc, char *argv[])
index b712b5c7843249254b9cb6e986c2089e192218e3..ca79dc4f10711d85e69a7993f5dcd7d0bf10ea6e 100644 (file)
@@ -12,7 +12,7 @@
 #include <time.h>
 #include <errno.h>
 
-#define UNUSED __attribute__((unused))
+#define UNUSED(x) x __attribute__((unused))
 
 static int null_getattr(const char *path, struct stat *stbuf)
 {
@@ -89,7 +89,8 @@ static struct fuse_operations null_oper = {
     read:      null_read,
     write:     null_write,
     statfs:    null_statfs,
-    release:   NULL
+    release:   NULL,
+    fsync:     NULL
 };
 
 int main(int argc, char *argv[])
index 719564e41b394f795bdf69fdfdf82586d5793ec5..59e0ed12779100a8fd18d671acd97754b754a55a 100644 (file)
@@ -87,7 +87,9 @@ typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type);
  *       2) all memory mappings unmapped
  *    This call need only be implemented if this information is required,
  *    otherwise set this function to NULL.
- *    
+ * 
+ *  - fsync() has a boolean 'datasync' parameter which if TRUE then do
+ *  an fdatasync() operation.
  */
 struct fuse_operations {
     int (*getattr)  (const char *, struct stat *);
@@ -109,6 +111,7 @@ struct fuse_operations {
     int (*write)    (const char *, const char *, size_t, off_t);
     int (*statfs)   (struct fuse_statfs *);
     int (*release)  (const char *, int);
+    int (*fsync)    (const char *, int);
 };
 
 /** Extra context that may be needed by some filesystems */
index 4be9a283a161b396f1d0bba52b320da844949c15..08ad214d4005fe58fc20d9c431a5e91cf96c4fe9 100644 (file)
@@ -103,7 +103,8 @@ enum fuse_opcode {
        FUSE_WRITE      = 16,
        FUSE_STATFS     = 17,
        FUSE_RELEASE    = 18, /* no reply */
-       FUSE_INVALIDATE = 19  /* user initiated */
+       FUSE_INVALIDATE = 19, /* user initiated */
+       FUSE_FSYNC      = 20
 };
 
 /* Conservative buffer size for the client */
@@ -176,6 +177,10 @@ struct fuse_statfs_out {
        struct fuse_kstatfs st;
 };
 
+struct fuse_fsync_in {
+       int datasync;
+};
+
 struct fuse_in_header {
        int unique;
        enum fuse_opcode opcode;
index ca4440cc2e651f9e94ab39c9f070a9caa8768feb..11e7bc0648741e4d5d143477a7052bea3a9c8331 100644 (file)
@@ -74,7 +74,22 @@ static int fuse_release(struct inode *inode, struct file *file)
 
 static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
 {
-       return 0;
+       struct inode *inode = de->d_inode;
+       struct fuse_conn *fc = INO_FC(inode);
+       struct fuse_in in = FUSE_IN_INIT;
+       struct fuse_out out = FUSE_OUT_INIT;
+       struct fuse_fsync_in inarg;
+       
+       memset(&inarg, 0, sizeof(inarg));
+       inarg.datasync = datasync;
+
+       in.h.opcode = FUSE_FSYNC;
+       in.h.ino = inode->i_ino;
+       in.numargs = 1;
+       in.args[0].size = sizeof(inarg);
+       in.args[0].value = &inarg;
+       request_send(fc, &in, &out);
+       return out.h.error;
 }
 
 static int fuse_readpage(struct file *file, struct page *page)
index d0537fc11022b4c6620336d3b0965d3a54adc621..d382707a33695d7c2baac8c60e09ede12563b47d 100644 (file)
@@ -40,6 +40,7 @@ static const char *opname(enum fuse_opcode opcode)
     case FUSE_WRITE:    return "WRITE";
     case FUSE_STATFS:   return "STATFS";
     case FUSE_RELEASE:  return "RELEASE";
+    case FUSE_FSYNC:    return "FSYNC";
     default:            return "???";
     }
 }
@@ -866,6 +867,24 @@ static void do_statfs(struct fuse *f, struct fuse_in_header *in)
     send_reply(f, in, res, &arg, sizeof(arg));
 }
 
+static void do_fsync(struct fuse *f, struct fuse_in_header *in,
+                     struct fuse_fsync_in *inarg)
+{
+    int res;
+    char *path;
+
+    res = -ENOENT;
+    path = get_path(f, in->ino);
+    if(path != NULL) {
+        /* fsync is not mandatory, so don't return ENOSYS */
+        res = 0;
+        if(f->op.fsync)
+            res = f->op.fsync(path, inarg->datasync);
+        free(path);
+    }
+    send_reply(f, in, res, NULL, 0);
+}
+
 static void free_cmd(struct fuse_cmd *cmd)
 {
     free(cmd->buf);
@@ -960,6 +979,10 @@ void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
         do_statfs(f, in);
         break;
 
+    case FUSE_FSYNC:
+        do_fsync(f, in, (struct fuse_fsync_in *) inarg);
+        break;
+
     default:
         send_reply(f, in, -ENOSYS, NULL, 0);
     }