diff options
| author | Csaba Henk <csaba@redhat.com> | 2018-05-03 10:22:18 +0200 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2018-05-04 17:42:12 +0000 | 
| commit | 2ac79ed8048753dfd2494d3a4d3b0e9411673e3a (patch) | |
| tree | 080da10738f9dade1fcb787d43f333c641dffe04 /xlators/mount | |
| parent | 15866ac9773e89cd9e017e7d3bf8aa01a87edfd8 (diff) | |
fuse: add support for kernel writeback cache
- Added kernel-writeback-cache command line and xlator
  option for requesting utilisation of the writeback
  cache of the kernel in FUSE_INIT (see [1]).
- Added attr-times-granularity command line and xlator
  option via which granularity of the {a,m,c}time in
  stat (attr) data that we support can be indicated to
  kernel. This is a means to avoid divergence of the
  attr times between kernel and userspace that could
  occur with writeback-cache, while still maintaining
  maximum time precision the FUSE server is capable of
  (see [2]).
- Handling FATTR_CTIME flag in FUSE_SETATTR that
  indicates presence of ctime in setattr payload.
  Currently we cannot associate arbitrary ctimes to
  files on backend, so we just touch them to update
  their ctimes to current time. Having ctimes in setattr
  payload is also a side effect of writeback cache
  (see [3] and [4]).
[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4d99ff8,
     "fuse: Turn writeback cache on"
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e27c9d3,
     "fuse: fuse: add time_gran to INIT_OUT"
[3]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e18bda,
     "fuse: add .write_inode"
[4]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ab9e13f,
     "fuse: allow ctime flushing to userspace"
Updates: #435
Change-Id: Id174c8e0c815c4456c35f8c53e41a6a507d91855
Signed-off-by: Csaba Henk <csaba@redhat.com>
Diffstat (limited to 'xlators/mount')
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 50 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 4 | ||||
| -rwxr-xr-x | xlators/mount/fuse/utils/mount.glusterfs.in | 14 | 
3 files changed, 64 insertions, 4 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index f509d84a15b..322b4deeffa 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -1233,6 +1233,11 @@ fattr_to_gf_set_attr (int32_t valid)          if (valid & FATTR_MTIME)                  gf_valid |= GF_SET_ATTR_MTIME; +#if FUSE_KERNEL_MINOR_VERSION >= 23 +        if (valid & FATTR_CTIME) +                gf_valid |= GF_SET_ATTR_CTIME; +#endif +          if (valid & FATTR_SIZE)                  gf_valid |= GF_SET_ATTR_SIZE; @@ -1271,7 +1276,11 @@ fuse_setattr_resume (fuse_state_t *state)          if ((state->valid & (FATTR_MASK)) != FATTR_SIZE) {                  if (state->fd &&                      !((state->valid & FATTR_ATIME) || -                      (state->valid & FATTR_MTIME))) { +                      (state->valid & FATTR_MTIME) +#if FUSE_KERNEL_MINOR_VERSION >= 23 +                       || (state->valid & FATTR_CTIME) +#endif +                     )) {                          /*                              there is no "futimes" call, so don't send                              fsetattr if ATIME or MTIME is set @@ -1346,8 +1355,14 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg,                  state->attr.ia_size  = fsi->size;                  state->attr.ia_atime = fsi->atime;                  state->attr.ia_mtime = fsi->mtime; +#if FUSE_KERNEL_MINOR_VERSION >= 23 +                state->attr.ia_ctime = fsi->ctime; +#endif                  state->attr.ia_atime_nsec = fsi->atimensec;                  state->attr.ia_mtime_nsec = fsi->mtimensec; +#if FUSE_KERNEL_MINOR_VERSION >= 23 +                state->attr.ia_ctime_nsec = fsi->ctimensec; +#endif                  state->attr.ia_prot = ia_prot_from_st_mode (fsi->mode);                  state->attr.ia_uid  = fsi->uid; @@ -4253,14 +4268,23 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg,  	if (fini->flags & FUSE_ASYNC_DIO)  		fino.flags |= FUSE_ASYNC_DIO;  #endif + +        size = sizeof (fino); +#if FUSE_KERNEL_MINOR_VERSION >= 23          /* FUSE 7.23 and newer added attributes to the fuse_init_out struct */ -        if (fini->minor > 22) { -                size = sizeof (fino); -        } else { +        if (fini->minor < 23) {                  /* reduce the size, chop off unused attributes from &fino */                  size = FUSE_COMPAT_22_INIT_OUT_SIZE;          } +        /* Writeback cache support */ +        if (fini->minor >= 23) { +                if (priv->kernel_writeback_cache) +                        fino.flags |= FUSE_WRITEBACK_CACHE; +                fino.time_gran = priv->attr_times_granularity; +        } +#endif +          ret = send_fuse_data (this, finh, &fino, size);          if (ret == 0)                  gf_log ("glusterfs-fuse", GF_LOG_INFO, @@ -5770,6 +5794,12 @@ init (xlator_t *this_xl)          GF_OPTION_INIT("thin-client", priv->thin_client, bool,                         cleanup_exit); +        /* Writeback cache support */ +        GF_OPTION_INIT("kernel-writeback-cache", priv->kernel_writeback_cache, +                       bool, cleanup_exit); +        GF_OPTION_INIT("attr-times-granularity", priv->attr_times_granularity, +	               int32, cleanup_exit); +          /* user has set only background-qlen, not congestion-threshold,             use the fuse kernel driver formula to set congestion. ie, 75% */          if (dict_get (this_xl->options, "background-qlen") && @@ -6093,5 +6123,17 @@ struct volume_options options[] = {            .max = 64,            .description = "Sets fuse reader thread count.",          }, +        { .key = {"kernel-writeback-cache"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "false", +          .description = "Enables fuse in-kernel writeback cache.", +        }, +        { .key = {"attr-times-granularity"}, +          .type = GF_OPTION_TYPE_INT, +          .default_value = "0", +          .min = 0, +          .max = 1000000000, +          .description = "Supported granularity of file attribute times.", +        },          { .key = {NULL} },  }; diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 6cf9d2f7cf8..b26b5e21109 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -147,6 +147,10 @@ struct fuse_private {          gf_boolean_t         mount_finished;          gf_boolean_t         handle_graph_switch;          pthread_cond_t       migrate_cond; + +        /* Writeback cache support */ +        gf_boolean_t         kernel_writeback_cache; +        int                  attr_times_granularity;  };  typedef struct fuse_private fuse_private_t; diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in index 6890ff00121..9d9069aa1f7 100755 --- a/xlators/mount/fuse/utils/mount.glusterfs.in +++ b/xlators/mount/fuse/utils/mount.glusterfs.in @@ -269,6 +269,14 @@ start_glusterfs ()          cmd_line=$(echo "$cmd_line --xlator-option=$xlator_option");      fi +    if [ -n "$kernel_writeback_cache" ]; then +        cmd_line=$(echo "$cmd_line --kernel-writeback-cache=$kernel_writeback_cache"); +    fi + +    if [ -n "$attr_times_granularity" ]; then +        cmd_line=$(echo "$cmd_line --attr-times-granularity=$attr_times_granularity"); +    fi +      if [ -n "$process_name" ]; then          cmd_line=$(echo "$cmd_line --process-name fuse.$process_name");      else @@ -520,6 +528,12 @@ with_options()                  [ $value = "false" ] ; then                  no_root_squash=1;              fi ;; +        "kernel-writeback-cache") +            kernel_writeback_cache=$value +            ;; +        "attr-times-granularity") +            attr_times_granularity=$value +            ;;          "context"|"fscontext"|"defcontext"|"rootcontext")              # standard SElinux mount options to pass to the kernel              [ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts,"  | 
