added fsync operation
diff --git a/ChangeLog b/ChangeLog
index ae9fdbb..15efcd3 100644
--- 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>
diff --git a/example/fusexmp.c b/example/fusexmp.c
index e783423..d97f3ca 100644
--- a/example/fusexmp.c
+++ b/example/fusexmp.c
@@ -267,7 +267,9 @@
read: xmp_read,
write: xmp_write,
statfs: xmp_statfs,
- release: NULL
+ release: NULL,
+ fsync: NULL
+
};
int main(int argc, char *argv[])
diff --git a/example/hello.c b/example/hello.c
index cd8fb5d..6b461d0 100644
--- a/example/hello.c
+++ b/example/hello.c
@@ -86,7 +86,8 @@
read: hello_read,
write: NULL,
statfs: NULL,
- release: NULL
+ release: NULL,
+ fsync: NULL
};
int main(int argc, char *argv[])
diff --git a/example/null.c b/example/null.c
index b712b5c..ca79dc4 100644
--- a/example/null.c
+++ b/example/null.c
@@ -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 @@
read: null_read,
write: null_write,
statfs: null_statfs,
- release: NULL
+ release: NULL,
+ fsync: NULL
};
int main(int argc, char *argv[])
diff --git a/include/fuse.h b/include/fuse.h
index 719564e..59e0ed1 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -87,7 +87,9 @@
* 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 @@
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 */
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 4be9a28..08ad214 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -103,7 +103,8 @@
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_kstatfs st;
};
+struct fuse_fsync_in {
+ int datasync;
+};
+
struct fuse_in_header {
int unique;
enum fuse_opcode opcode;
diff --git a/kernel/file.c b/kernel/file.c
index ca4440c..11e7bc0 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -74,7 +74,22 @@
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)
diff --git a/lib/fuse.c b/lib/fuse.c
index d0537fc..d382707 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -40,6 +40,7 @@
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 @@
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 @@
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);
}