diff options
| author | Csaba Henk <csaba@gluster.com> | 2009-07-14 17:10:38 -0700 | 
|---|---|---|
| committer | Csaba Henk <csaba@gluster.com> | 2009-08-12 06:21:04 -0700 | 
| commit | ab5df475c5c7e9e0f3268fe94a6280e71d34c1db (patch) | |
| tree | 9aa51bd5fa15e802af6307765e173c96177f6fc3 | |
| parent | d5910898f1602dc16ab158b06c37abcd98a0588a (diff) | |
upgrade FUSE protocol to 7.12 and add support for older versions of the protocol
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 65 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse_kernel.h | 68 | 
2 files changed, 115 insertions, 18 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 2700d6ed0..8e1b26258 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -59,7 +59,7 @@  #define ZR_DIRECT_IO_OPT        "direct-io-mode"  #define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check" -#define FUSE_711_OP_HIGH (FUSE_POLL + 1) +#define FUSE_712_OP_HIGH (FUSE_POLL + 1)  #define OFFSET_MAX 0x7fffffffffffffffLL  #define GLUSTERFS_XATTR_LEN_MAX  65536 @@ -69,6 +69,7 @@ typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh,  struct fuse_private {          int                  fd; +        uint32_t             proto_minor;          char                *volfile;          size_t               volfile_size;          char                *mount_point; @@ -525,7 +526,10 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          feo.attr_valid_nsec =                            calc_timeout_nsec (priv->attribute_timeout); -                        send_fuse_obj (this, finh, &feo); +                        priv->proto_minor >= 9 ? +                        send_fuse_obj (this, finh, &feo) : +                        send_fuse_data (this, finh, &feo, +                                        FUSE_COMPAT_ENTRY_OUT_SIZE);                  } else {                          /* Refurbish the entry_out as attr_out. Too hacky?... */                          fao = (struct fuse_attr_out *) @@ -537,7 +541,10 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          fao->attr_valid_nsec =                            calc_timeout_nsec (priv->attribute_timeout); -                        send_fuse_obj (this, finh, fao); +                        priv->proto_minor >= 9 ? +                        send_fuse_obj (this, finh, fao) : +                        send_fuse_data (this, finh, fao, +                                        FUSE_COMPAT_ATTR_OUT_SIZE);                  }          } else {                  gf_log ("glusterfs-fuse", @@ -1194,8 +1201,13 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)          struct fuse_mknod_in *fmi = msg;          char         *name = (char *)(fmi + 1); -        fuse_state_t *state = NULL; -        int32_t       ret = -1; +        fuse_state_t   *state = NULL; +        fuse_private_t *priv = NULL; +        int32_t         ret = -1; + +        priv = this->private; +        if (priv->proto_minor < 12) +                name = (char *)msg + FUSE_COMPAT_MKNOD_IN_SIZE;          GET_STATE (this, finh, state);          ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); @@ -1542,7 +1554,9 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  fouh.error = 0;                  iov_out[0].iov_base = &fouh;                  iov_out[1].iov_base = &feo; -                iov_out[1].iov_len = sizeof (feo); +                iov_out[1].iov_len = priv->proto_minor >= 9 ? +                                     sizeof (feo) : +                                     FUSE_COMPAT_ENTRY_OUT_SIZE;                  iov_out[2].iov_base = &foo;                  iov_out[2].iov_len = sizeof (foo);                  if (send_fuse_iov (this, finh, iov_out, 3) == ENOENT) { @@ -1571,15 +1585,20 @@ out:  static void  fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)  { -        struct fuse_open_in *foi = msg; -        char         *name = (char *)(foi + 1); +        struct fuse_create_in *fci = msg; +        char         *name = (char *)(fci + 1); +        fuse_private_t        *priv = NULL;          fuse_state_t *state = NULL;          fd_t         *fd = NULL;          int32_t       ret = -1; +        priv = this->private; +        if (priv->proto_minor < 12) +                name = (char *)((struct fuse_open_in *)msg + 1); +          GET_STATE (this, finh, state); -        state->flags = foi->flags; +        state->flags = fci->flags;          ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);          if (ret < 0) { @@ -1602,7 +1621,7 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)                  state->loc.path);          FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE, -                  create, &state->loc, state->flags, foi->mode, fd); +                  create, &state->loc, state->flags, fci->mode, fd);          return;  } @@ -1757,12 +1776,17 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)          struct fuse_write_in *fwi = msg;          char            *buf = (char *)(fwi + 1); +        fuse_private_t  *priv = NULL;          fuse_state_t    *state = NULL;          struct iovec     vector;          fd_t            *fd = NULL;          struct iobref   *iobref = NULL;          struct iobuf    *iobuf = NULL; +        priv = this->private; +        if (priv->proto_minor < 9) +                buf = (char *)msg + FUSE_COMPAT_WRITE_IN_SIZE; +          GET_STATE (this, finh, state);          state->size = fwi->size;          state->off  = fwi->offset; @@ -2034,9 +2058,11 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  {          fuse_state_t *state = NULL;          fuse_in_header_t *finh = NULL; +        fuse_private_t   *priv = NULL;          struct fuse_statfs_out fso = {{0, }, };          state = frame->root->state; +        priv  = this->private;          finh  = state->finh;          /*            Filesystems (like ZFS on solaris) reports @@ -2075,8 +2101,9 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  fso.st.ffree   = buf->f_ffree;                  fso.st.namelen = buf->f_namemax; -                send_fuse_obj (this, finh, &fso); - +                priv->proto_minor >= 4 ? +                send_fuse_obj (this, finh, &fso) : +                send_fuse_data (this, finh, &fso, FUSE_COMPAT_STATFS_SIZE);          } else {                  gf_log ("glusterfs-fuse", GF_LOG_WARNING,                          "%"PRIu64": ERR => -1 (%s)", frame->root->unique, @@ -2634,8 +2661,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)                  goto out;          } -        if (fini->major != FUSE_KERNEL_VERSION || -            fini->minor < 9) { +        if (fini->major != FUSE_KERNEL_VERSION) {                  gf_log ("glusterfs-fuse", GF_LOG_ERROR,                          "unsupported FUSE protocol version %d.%d",                          fini->major, fini->minor); @@ -2643,6 +2669,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)                  close (priv->fd);                  goto out;          } +        priv->proto_minor = fini->minor;          fino.major = FUSE_KERNEL_VERSION;          fino.minor = FUSE_KERNEL_MINOR_VERSION; @@ -2684,7 +2711,7 @@ fuse_discard (xlator_t *this, fuse_in_header_t *finh, void *msg)          FREE (finh);  } -static fuse_handler_t *fuse_ops[FUSE_711_OP_HIGH]; +static fuse_handler_t *fuse_ops[FUSE_712_OP_HIGH];  int  fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -3048,6 +3075,12 @@ init (xlator_t *this_xl)          }          ret = mount (fsname, priv->mount_point, "fuse.glusterfs", 0,                       mount_param); +        if (ret == -1 && errno == ENODEV) +                /* fs subtype support was added by 79c0b2df aka +                   v2.6.21-3159-g79c0b2d. Probably we have an +                   older kernel ... */ +                ret = mount (fsname, priv->mount_point, "fuse", 0, +                             mount_param);          if (ret == -1) {                  gf_log ("glusterfs-fuse", GF_LOG_ERROR,                          "mount failed (%s)", strerror (errno)); @@ -3061,7 +3094,7 @@ init (xlator_t *this_xl)          priv->first_call = 2; -        for (i = 0; i < FUSE_711_OP_HIGH; i++) +        for (i = 0; i < FUSE_712_OP_HIGH; i++)                  fuse_ops[i] = fuse_enosys;          fuse_ops[FUSE_INIT]        = fuse_init;          fuse_ops[FUSE_DESTROY]     = fuse_discard; diff --git a/xlators/mount/fuse/src/fuse_kernel.h b/xlators/mount/fuse/src/fuse_kernel.h index df558e394..dac35d8b9 100644 --- a/xlators/mount/fuse/src/fuse_kernel.h +++ b/xlators/mount/fuse/src/fuse_kernel.h @@ -51,6 +51,11 @@   *  - add IOCTL message   *  - add unsolicited notification support   *  - add POLL message and NOTIFY_POLL notification + * + * 7.12 + *  - add umask flag to input argument of open, mknod and mkdir + *  - add notification messages for invalidation of inodes and + *    directory entries   */  #ifndef _LINUX_FUSE_H @@ -58,6 +63,7 @@  #include <sys/types.h>  #define __u64 uint64_t +#define __s64 int64_t  #define __u32 uint32_t  #define __s32 int32_t @@ -65,7 +71,7 @@  #define FUSE_KERNEL_VERSION 7  /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 11 +#define FUSE_KERNEL_MINOR_VERSION 12  /** The node ID of the root inode */  #define FUSE_ROOT_ID 1 @@ -141,6 +147,7 @@ struct fuse_file_lock {   * INIT request/reply flags   *   * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." + * FUSE_DONT_MASK: don't apply umask to file mode on create operations   */  #define FUSE_ASYNC_READ		(1 << 0)  #define FUSE_POSIX_LOCKS	(1 << 1) @@ -148,6 +155,14 @@ struct fuse_file_lock {  #define FUSE_ATOMIC_O_TRUNC	(1 << 3)  #define FUSE_EXPORT_SUPPORT	(1 << 4)  #define FUSE_BIG_WRITES		(1 << 5) +#define FUSE_DONT_MASK		(1 << 6) + +/** + * CUSE INIT request/reply flags + * + * CUSE_UNRESTRICTED_IOCTL:  use unrestricted ioctl + */ +#define CUSE_UNRESTRICTED_IOCTL	(1 << 0)  /**   * Release flags @@ -239,10 +254,15 @@ enum fuse_opcode {  	FUSE_DESTROY       = 38,  	FUSE_IOCTL         = 39,  	FUSE_POLL          = 40, + +	/* CUSE specific operations */ +	CUSE_INIT          = 4096,  };  enum fuse_notify_code {  	FUSE_NOTIFY_POLL   = 1, +	FUSE_NOTIFY_INVAL_INODE = 2, +	FUSE_NOTIFY_INVAL_ENTRY = 3,  	FUSE_NOTIFY_CODE_MAX,  }; @@ -281,14 +301,18 @@ struct fuse_attr_out {  	struct fuse_attr attr;  }; +#define FUSE_COMPAT_MKNOD_IN_SIZE 8 +  struct fuse_mknod_in {  	__u32	mode;  	__u32	rdev; +	__u32	umask; +	__u32	padding;  };  struct fuse_mkdir_in {  	__u32	mode; -	__u32	padding; +	__u32	umask;  };  struct fuse_rename_in { @@ -320,7 +344,14 @@ struct fuse_setattr_in {  struct fuse_open_in {  	__u32	flags; +	__u32	unused; +}; + +struct fuse_create_in { +	__u32	flags;  	__u32	mode; +	__u32	umask; +	__u32	padding;  };  struct fuse_open_out { @@ -430,6 +461,27 @@ struct fuse_init_out {  	__u32	max_write;  }; +#define CUSE_INIT_INFO_MAX 4096 + +struct cuse_init_in { +	__u32	major; +	__u32	minor; +	__u32	unused; +	__u32	flags; +}; + +struct cuse_init_out { +	__u32	major; +	__u32	minor; +	__u32	unused; +	__u32	flags; +	__u32	max_read; +	__u32	max_write; +	__u32	dev_major;		/* chardev major */ +	__u32	dev_minor;		/* chardev minor */ +	__u32	spare[10]; +}; +  struct fuse_interrupt_in {  	__u64	unique;  }; @@ -506,4 +558,16 @@ struct fuse_dirent {  #define FUSE_DIRENT_SIZE(d) \  	FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) +struct fuse_notify_inval_inode_out { +	__u64	ino; +	__s64	off; +	__s64	len; +}; + +struct fuse_notify_inval_entry_out { +	__u64	parent; +	__u32	namelen; +	__u32	padding; +}; +  #endif /* _LINUX_FUSE_H */  | 
