From: Miklos Szeredi Date: Sun, 1 Oct 2006 14:41:04 +0000 (+0000) Subject: Add support for FLUSH+RELEASE operation X-Git-Tag: fuse_2_6_0_rc2~1 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=4fca432f2d3dd5d07d4ec0f932bc7275fb206f3e;p=qemu-gpiodev%2Flibfuse.git Add support for FLUSH+RELEASE operation --- diff --git a/ChangeLog b/ChangeLog index 0478639..1234576 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2006-10-01 Miklos Szeredi + * 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 diff --git a/kernel/fuse_kernel.h b/kernel/fuse_kernel.h index c2243d9..94154b1 100644 --- a/kernel/fuse_kernel.h +++ b/kernel/fuse_kernel.h @@ -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 { diff --git a/lib/fuse.c b/lib/fuse.c index c28528e..c87bff3 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -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) { diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 4308a26..f7de2c7 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -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);