From bc9cf5ba83dffbc2fb5a6821a6f40e6acff59897 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 31 Jul 2013 17:55:03 -0400 Subject: fuse-bridge: update to fuse protocol minor version 16 (Linux) 7.14 - Splice write support to fuse device node. No gluster changes required besides header update. 7.15 - Store/retrieve notification support. No gluster changes required besides header update. 7.16 - BATCH_FORGET request support. Implement a handler for BATCH_FORGET requests and update the header. - Updated ioctl() ABI. No gluster changes required besides header update. BUG: 990744 Change-Id: If3061a720ba566ee6731ad8b77cdc665d8fbf781 Signed-off-by: Brian Foster Reviewed-on: http://review.gluster.org/5449 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- contrib/fuse-include/fuse_kernel.h | 62 ++++++++++++++++++++++++++++++++++-- xlators/mount/fuse/src/fuse-bridge.c | 39 +++++++++++++++++------ 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/contrib/fuse-include/fuse_kernel.h b/contrib/fuse-include/fuse_kernel.h index 2f4e26ff..ac6a11af 100644 --- a/contrib/fuse-include/fuse_kernel.h +++ b/contrib/fuse-include/fuse_kernel.h @@ -60,6 +60,19 @@ * 7.13 * - make max number of background requests and congestion threshold * tunables + * + * 7.14 + * - add splice support to fuse device + * + * 7.15 + * - add store notify + * - add retrieve notify + * + * 7.16 + * - add BATCH_FORGET request + * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct + * fuse_ioctl_iovec' instead of ambiguous 'struct iovec' + * - add FUSE_IOCTL_32BIT flag */ #ifndef _LINUX_FUSE_H @@ -76,7 +89,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 13 +#define FUSE_KERNEL_MINOR_VERSION 16 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -206,12 +219,14 @@ struct fuse_file_lock { * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed * FUSE_IOCTL_RETRY: retry with new iovecs + * FUSE_IOCTL_32BIT: 32bit ioctl * * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs */ #define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_UNRESTRICTED (1 << 1) #define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_32BIT (1 << 3) #define FUSE_IOCTL_MAX_IOV 256 @@ -261,7 +276,8 @@ enum fuse_opcode { FUSE_DESTROY = 38, FUSE_IOCTL = 39, FUSE_POLL = 40, - + FUSE_NOTIFY_REPLY = 41, + FUSE_BATCH_FORGET = 42, FUSE_FALLOCATE = 43, FUSE_READDIRPLUS = 44, /* CUSE specific operations */ @@ -272,6 +288,8 @@ enum fuse_notify_code { FUSE_NOTIFY_POLL = 1, FUSE_NOTIFY_INVAL_INODE = 2, FUSE_NOTIFY_INVAL_ENTRY = 3, + FUSE_NOTIFY_STORE = 4, + FUSE_NOTIFY_RETRIEVE = 5, FUSE_NOTIFY_CODE_MAX, }; @@ -295,6 +313,16 @@ struct fuse_forget_in { __u64 nlookup; }; +struct fuse_forget_one { + __u64 nodeid; + __u64 nlookup; +}; + +struct fuse_batch_forget_in { + __u32 count; + __u32 dummy; +}; + struct fuse_getattr_in { __u32 getattr_flags; __u32 dummy; @@ -515,6 +543,11 @@ struct fuse_ioctl_in { __u32 out_size; }; +struct fuse_ioctl_iovec { + __u64 base; + __u64 len; +}; + struct fuse_ioctl_out { __s32 result; __u32 flags; @@ -598,4 +631,29 @@ struct fuse_notify_inval_entry_out { __u32 padding; }; +struct fuse_notify_store_out { + __u64 nodeid; + __u64 offset; + __u32 size; + __u32 padding; +}; + +struct fuse_notify_retrieve_out { + __u64 notify_unique; + __u64 nodeid; + __u64 offset; + __u32 size; + __u32 padding; +}; + +/* Matches the size of fuse_write_in */ +struct fuse_notify_retrieve_in { + __u64 dummy1; + __u64 offset; + __u32 size; + __u32 dummy2; + __u64 dummy3; + __u64 dummy4; +}; + #endif /* _LINUX_FUSE_H */ diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index efabf9f6..945222e9 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -941,12 +941,23 @@ fuse_xlator_forget (xlator_t *this, inode_t *inode) return 0; } +static inline void +do_forget(xlator_t *this, uint64_t unique, uint64_t nodeid, uint64_t nlookup) +{ + inode_t *fuse_inode = fuse_ino_to_inode(nodeid, this); + + fuse_log_eh(this, "%"PRIu64": FORGET %"PRIu64"/%"PRIu64" gfid: (%s)", + unique, nodeid, nlookup, uuid_utoa(fuse_inode->gfid)); + + inode_forget(fuse_inode, nlookup); + inode_unref(fuse_inode); +} + static void fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg) { struct fuse_forget_in *ffi = msg; - inode_t *fuse_inode = NULL; if (finh->nodeid == 1) { GF_FREE (finh); @@ -957,16 +968,26 @@ fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg) "%"PRIu64": FORGET %"PRIu64"/%"PRIu64, finh->unique, finh->nodeid, ffi->nlookup); - fuse_inode = fuse_ino_to_inode (finh->nodeid, this); + do_forget(this, finh->unique, finh->nodeid, ffi->nlookup); + + GF_FREE (finh); +} - fuse_log_eh (this, "%"PRIu64": FORGET %"PRIu64"/%"PRIu64" gfid: (%s)", - finh->unique, finh->nodeid, ffi->nlookup, - uuid_utoa (fuse_inode->gfid)); +static void +fuse_batch_forget(xlator_t *this, fuse_in_header_t *finh, void *msg) +{ + struct fuse_batch_forget_in *fbfi = msg; + struct fuse_forget_one *ffo = (struct fuse_forget_one *) (fbfi + 1); + int i; - inode_forget (fuse_inode, ffi->nlookup); - inode_unref (fuse_inode); + gf_log("glusterfs-fuse", GF_LOG_TRACE, + "%"PRIu64": BATCH_FORGET %"PRIu64"/%"PRIu32, + finh->unique, finh->nodeid, fbfi->count); - GF_FREE (finh); + for (i = 0; i < fbfi->count; i++) + do_forget(this, finh->unique, ffo[i].nodeid, ffo[i].nlookup); + + GF_FREE(finh); } static int @@ -5868,7 +5889,7 @@ static fuse_handler_t *fuse_std_ops[FUSE_OP_HIGH] = { /* [FUSE_IOCTL] */ /* [FUSE_POLL] */ /* [FUSE_NOTIFY_REPLY] */ - /* [FUSE_BATCH_FORGET] */ + [FUSE_BATCH_FORGET]= fuse_batch_forget, [FUSE_FALLOCATE] = fuse_fallocate, [FUSE_READDIRPLUS] = fuse_readdirp, }; -- cgit