From e2e4ac2c990a9b09740e4be6ae2de811154cc5b3 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 18 May 2004 08:45:28 +0000 Subject: [PATCH] added flush() call --- ChangeLog | 4 ++++ include/fuse.h | 25 ++++++++++++++++++------- include/linux/fuse.h | 1 + kernel/file.c | 17 +++++++++++++++++ lib/fuse.c | 20 ++++++++++++++++++++ 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5631b3c..c5c5a5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2004-05-18 Miklos Szeredi + + * Added flush() call + 2004-05-04 Miklos Szeredi * Extended attributes support for 2.4 (patch by Cody Pisto) diff --git a/include/fuse.h b/include/fuse.h index 1cb7bbf..3babaf6 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -86,15 +86,25 @@ typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type); * - release() is called when an open file has: * 1) all file descriptors closed * 2) all memory mappings unmapped - * For every open() call there will be exactly one release() call - * with the same flags. It is possible to have a file opened more - * than once, in which case only the last release will mean, that - * no more reads/writes will happen on the file. This call need - * only be implemented if this information is required, otherwise - * set this function to NULL. + * For every open() call there will be exactly one release() call + * with the same flags. It is possible to have a file opened more + * than once, in which case only the last release will mean, that no + * more reads/writes will happen on the file. The return value of + * release is ignored. This call need only be implemented if this + * information is required, otherwise set this function to NULL. + * + * - flush() is called when close() has been called on an open file. + * NOTE: this does not mean that the file is released (e.g. after + * fork() an open file will have two references which both must be + * closed before the file is released). The flush() method can be + * called more than once for each open(). The return value of + * flush() is passed on to the close() system call. Implementing + * this call is optional. If it is not needed by the filesystem, + * then set the callback pointer to NULL. * * - fsync() has a boolean 'datasync' parameter which if TRUE then do - * an fdatasync() operation. */ + * an fdatasync() operation. + */ struct fuse_operations { int (*getattr) (const char *, struct stat *); int (*readlink) (const char *, char *, size_t); @@ -114,6 +124,7 @@ struct fuse_operations { int (*read) (const char *, char *, size_t, off_t); int (*write) (const char *, const char *, size_t, off_t); int (*statfs) (const char *, struct statfs *); + int (*flush) (const char *); int (*release) (const char *, int); int (*fsync) (const char *, int); int (*setxattr) (const char *, const char *, const char *, size_t, int); diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 63cf167..027cb5e 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -82,6 +82,7 @@ enum fuse_opcode { FUSE_GETXATTR = 22, FUSE_LISTXATTR = 23, FUSE_REMOVEXATTR = 24, + FUSE_FLUSH = 25, }; /* Conservative buffer size for the client */ diff --git a/kernel/file.c b/kernel/file.c index 2c9473f..c9a44fd 100644 --- a/kernel/file.c +++ b/kernel/file.c @@ -92,6 +92,22 @@ static int fuse_release(struct inode *inode, struct file *file) return 0; } +static int fuse_flush(struct file *file) +{ + struct inode *inode = file->f_dentry->d_inode; + struct fuse_conn *fc = INO_FC(inode); + struct fuse_in in = FUSE_IN_INIT; + struct fuse_out out = FUSE_OUT_INIT; + + in.h.opcode = FUSE_FLUSH; + in.h.ino = inode->i_ino; + request_send(fc, &in, &out); + if (out.h.error == -ENOSYS) + return 0; + else + return out.h.error; +} + static int fuse_fsync(struct file *file, struct dentry *de, int datasync) { struct inode *inode = de->d_inode; @@ -470,6 +486,7 @@ static struct file_operations fuse_file_operations = { .write = generic_file_write, .mmap = generic_file_mmap, .open = fuse_open, + .flush = fuse_flush, .release = fuse_release, .fsync = fuse_fsync, #ifdef KERNEL_2_6 diff --git a/lib/fuse.c b/lib/fuse.c index fddcc33..9f5e8a9 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -829,6 +829,22 @@ static void do_open(struct fuse *f, struct fuse_in_header *in, } } +static void do_flush(struct fuse *f, struct fuse_in_header *in) +{ + char *path; + int res; + + res = -ENOENT; + path = get_path(f, in->ino); + if(path != NULL) { + res = -ENOSYS; + if(f->op.flush) + res = f->op.flush(path); + free(path); + } + send_reply(f, in, res, NULL, 0); +} + static void do_release(struct fuse *f, struct fuse_in_header *in, struct fuse_open_in *arg) { @@ -1215,6 +1231,10 @@ void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd) do_open(f, in, (struct fuse_open_in *) inarg); break; + case FUSE_FLUSH: + do_flush(f, in); + break; + case FUSE_RELEASE: do_release(f, in, (struct fuse_open_in *) inarg); break; -- 2.30.2