From: Miklos Szeredi Date: Fri, 12 Dec 2003 14:06:41 +0000 (+0000) Subject: added fsync operation X-Git-Tag: fuse_1_1_pre1~8 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=5e43f2c00c1ce3a9ee3ed9c2b5a9b32dabbb6e60;p=qemu-gpiodev%2Flibfuse.git 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 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 @@ 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[]) 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 @@ 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[]) 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 #include -#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[]) 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 @@ 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 */ 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 @@ 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; 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_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) 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 @@ 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); }