diff options
| -rw-r--r-- | libglusterfs/src/glfs-message-id.h | 1 | ||||
| -rw-r--r-- | tests/basic/ctime/ctime-noatime.t | 51 | ||||
| -rw-r--r-- | xlators/features/utime/src/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime-gen-fops-c.py | 6 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime-helpers.c | 15 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime-helpers.h | 4 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime-mem-types.h | 21 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime-messages.h | 28 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime.c | 52 | ||||
| -rw-r--r-- | xlators/features/utime/src/utime.h | 4 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 8 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-metadata.c | 8 | 
12 files changed, 191 insertions, 9 deletions
diff --git a/libglusterfs/src/glfs-message-id.h b/libglusterfs/src/glfs-message-id.h index 21d5397d2e6..7b25918b084 100644 --- a/libglusterfs/src/glfs-message-id.h +++ b/libglusterfs/src/glfs-message-id.h @@ -90,6 +90,7 @@ enum _msgid_comp {      GLFS_MSGID_COMP(QUIESCE, 1),      GLFS_MSGID_COMP(TA, 1),      GLFS_MSGID_COMP(TEMPLATE, 1), +    GLFS_MSGID_COMP(UTIME, 1),      /* --- new segments for messages goes above this line --- */ diff --git a/tests/basic/ctime/ctime-noatime.t b/tests/basic/ctime/ctime-noatime.t new file mode 100644 index 00000000000..d71528c566c --- /dev/null +++ b/tests/basic/ctime/ctime-noatime.t @@ -0,0 +1,51 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../afr.rc +cleanup; + +function atime_compare { +    local atime=$1 +    local file_name=$2 +    local atime1=$(stat -c "%X" $file_name) + +    if [ $atime == $atime1 ] +    then +        echo "0" +    else +        echo "1" +    fi +} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume set $V0 performance.stat-prefetch off +TEST $CLI volume set $V0 performance.read-ahead off +TEST $CLI volume set $V0 performance.quick-read off +TEST $CLI volume set $V0 performance.read-after-open off +TEST $CLI volume set $V0 performance.open-behind off +TEST $CLI volume set $V0 performance.write-behind off +TEST $CLI volume set $V0 performance.io-cache off + +TEST $CLI volume set $V0 utime on +TEST $CLI volume set $V0 ctime on +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +TEST "echo hello_world > FILE" +atime1=$(stat -c "%X" FILE) + +TEST "cat FILE > /dev/null" +EXPECT "0" atime_compare $atime1 FILE + +sleep 1 + +TEST $CLI volume set $V0 noatime off +TEST "cat FILE > /dev/null" +EXPECT "1" atime_compare $atime1 FILE + +cd - +cleanup diff --git a/xlators/features/utime/src/Makefile.am b/xlators/features/utime/src/Makefile.am index e94a00a8326..7c3adbc2195 100644 --- a/xlators/features/utime/src/Makefile.am +++ b/xlators/features/utime/src/Makefile.am @@ -15,6 +15,8 @@ utime_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la  noinst_HEADERS_utime  = $(UTIME_SRC)/utime-helpers.h  noinst_HEADERS_utime += $(UTIME_SRC)/utime.h +noinst_HEADERS_utime += $(UTIME_SRC)/utime-messages.h +noinst_HEADERS_utime += $(UTIME_SRC)/utime-mem-types.h  noinst_HEADERS = $(top_srcdir)/xlators/lib/src/libxlator.h  noinst_HEADERS += $(noinst_HEADERS_utime) diff --git a/xlators/features/utime/src/utime-gen-fops-c.py b/xlators/features/utime/src/utime-gen-fops-c.py index d7f12d18f2b..ab56dc9a4b3 100644 --- a/xlators/features/utime/src/utime-gen-fops-c.py +++ b/xlators/features/utime/src/utime-gen-fops-c.py @@ -16,7 +16,7 @@ gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this,  {          gl_timespec_get(&frame->root->ctime); -        (void) utime_update_attribute_flags(frame, GF_FOP_@UPNAME@); +        (void) utime_update_attribute_flags(frame, this, GF_FOP_@UPNAME@);          STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this),                      FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@);          return 0; @@ -41,7 +41,7 @@ gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this,  {          gl_timespec_get(&frame->root->ctime); -        (void) utime_update_attribute_flags(frame, GF_FOP_READ); +        (void) utime_update_attribute_flags(frame, this, GF_FOP_READ);          STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this),                      FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@);          return 0; @@ -55,7 +55,7 @@ gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this,  {          gl_timespec_get(&frame->root->ctime); -        (void) utime_update_attribute_flags(frame, GF_FOP_WRITE); +        (void) utime_update_attribute_flags(frame, this, GF_FOP_WRITE);          STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this),                      FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@);          return 0; diff --git a/xlators/features/utime/src/utime-helpers.c b/xlators/features/utime/src/utime-helpers.c index 2d74bc76e07..c79e12badfa 100644 --- a/xlators/features/utime/src/utime-helpers.c +++ b/xlators/features/utime/src/utime-helpers.c @@ -9,6 +9,7 @@  */  #include "utime-helpers.h" +#include "utime.h"  void  gl_timespec_get(struct timespec *ts) @@ -21,12 +22,17 @@ gl_timespec_get(struct timespec *ts)  }  void -utime_update_attribute_flags(call_frame_t *frame, glusterfs_fop_t fop) +utime_update_attribute_flags(call_frame_t *frame, xlator_t *this, +                             glusterfs_fop_t fop)  { -    if (!frame) { +    utime_priv_t *utime_priv = NULL; + +    if (!frame || !this) {          goto out;      } +    utime_priv = this->private; +      switch (fop) {          case GF_FOP_SETXATTR:          case GF_FOP_FSETXATTR: @@ -42,9 +48,10 @@ utime_update_attribute_flags(call_frame_t *frame, glusterfs_fop_t fop)          case GF_FOP_OPENDIR:          case GF_FOP_OPEN:          case GF_FOP_READ: -            frame->root->flags |= MDATA_ATIME; +            if (!utime_priv->noatime) { +                frame->root->flags |= MDATA_ATIME; +            }              break; -          case GF_FOP_MKNOD:          case GF_FOP_MKDIR:          case GF_FOP_SYMLINK: diff --git a/xlators/features/utime/src/utime-helpers.h b/xlators/features/utime/src/utime-helpers.h index 4efe75619eb..b89867a3db3 100644 --- a/xlators/features/utime/src/utime-helpers.h +++ b/xlators/features/utime/src/utime-helpers.h @@ -13,12 +13,14 @@  #include "glusterfs-fops.h"  #include "stack.h" +#include "xlator.h"  #include "timespec.h"  #include <time.h>  void  gl_timespec_get(struct timespec *ts);  void -utime_update_attribute_flags(call_frame_t *frame, glusterfs_fop_t fop); +utime_update_attribute_flags(call_frame_t *frame, xlator_t *this, +                             glusterfs_fop_t fop);  #endif /* _UTIME_HELPERS_H */ diff --git a/xlators/features/utime/src/utime-mem-types.h b/xlators/features/utime/src/utime-mem-types.h new file mode 100644 index 00000000000..fbd9aff0eca --- /dev/null +++ b/xlators/features/utime/src/utime-mem-types.h @@ -0,0 +1,21 @@ +/* +  Copyright (c) 2018 Red Hat, Inc. <http://www.redhat.com> +  This file is part of GlusterFS. + +  This file is licensed to you under your choice of the GNU Lesser +  General Public License, version 3 or any later version (LGPLv3 or +  later), or the GNU General Public License, version 2 (GPLv2), in all +  cases as published by the Free Software Foundation. +*/ + +#ifndef __UTIME_MEM_TYPES_H__ +#define __UTIME_MEM_TYPES_H__ + +#include "mem-types.h" + +enum gf_utime_mem_types_ { +    utime_mt_utime_t = gf_common_mt_end + 1, +    utime_mt_end +}; + +#endif /* __UTIME_MEM_TYPES_H__ */ diff --git a/xlators/features/utime/src/utime-messages.h b/xlators/features/utime/src/utime-messages.h new file mode 100644 index 00000000000..7613c335d43 --- /dev/null +++ b/xlators/features/utime/src/utime-messages.h @@ -0,0 +1,28 @@ +/* +  Copyright (c) 2018 Red Hat, Inc. <http://www.redhat.com> +  This file is part of GlusterFS. + +  This file is licensed to you under your choice of the GNU Lesser +  General Public License, version 3 or any later version (LGPLv3 or +  later), or the GNU General Public License, version 2 (GPLv2), in all +  cases as published by the Free Software Foundation. +*/ + +#ifndef __UTIME_MESSAGES_H__ +#define __UTIME_MESSAGES_H__ + +#include "glfs-message-id.h" + +/* To add new message IDs, append new identifiers at the end of the list. + * + * Never remove a message ID. If it's not used anymore, you can rename it or + * leave it as it is, but not delete it. This is to prevent reutilization of + * IDs by other messages. + * + * The component name must match one of the entries defined in + * glfs-message-id.h. + */ + +GLFS_MSGID(UTIME, UTIME_MSG_NO_MEMORY); + +#endif /* __UTIME_MESSAGES_H__ */ diff --git a/xlators/features/utime/src/utime.c b/xlators/features/utime/src/utime.c index 7671904b717..418e4c4a0d5 100644 --- a/xlators/features/utime/src/utime.c +++ b/xlators/features/utime/src/utime.c @@ -9,6 +9,8 @@  */  #include "utime.h" +#include "utime-messages.h" +#include "utime-mem-types.h"  int32_t  gf_utime_invalidate(xlator_t *this, inode_t *inode) @@ -120,21 +122,57 @@ gf_utime_priv(xlator_t *this)  }  int32_t +mem_acct_init(xlator_t *this) +{ +    if (xlator_mem_acct_init(this, utime_mt_end + 1) != 0) { +        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY, +               "Memory accounting initialization failed."); +        return -1; +    } +    return 0; +} + +int32_t  init(xlator_t *this)  { +    utime_priv_t *utime = NULL; + +    utime = GF_MALLOC(sizeof(*utime), utime_mt_utime_t); +    if (utime == NULL) { +        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY, +               "Failed to allocate private memory."); +        return -1; +    } +    memset(utime, 0, sizeof(*utime)); + +    this->private = utime; +    GF_OPTION_INIT("noatime", utime->noatime, bool, err); +      return 0; +err: +    return -1;  }  void  fini(xlator_t *this)  { +    utime_priv_t *utime = NULL; + +    utime = this->private; +    GF_FREE(utime);      return;  }  int32_t -reconfigure(xlator_t *this, dict_t *dict) +reconfigure(xlator_t *this, dict_t *options)  { +    utime_priv_t *utime = this->private; + +    GF_OPTION_RECONF("noatime", utime->noatime, options, bool, err); +      return 0; +err: +    return -1;  }  int @@ -180,3 +218,15 @@ struct xlator_dumpops dumpops = {      .priv_to_dict = gf_utime_priv_to_dict,      .priv = gf_utime_priv,  }; + +struct volume_options options[] = { +    {.key = {"noatime"}, +     .type = GF_OPTION_TYPE_BOOL, +     .default_value = "on", +     .op_version = {GD_OP_VERSION_5_0}, +     .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, +     .tags = {"ctime"}, +     .description = "Enable/Disable atime updation when ctime feature is " +                    "enabled. When noatime is on, atime is not updated with " +                    "ctime feature enabled and vice versa."}, +    {.key = {NULL}}}; diff --git a/xlators/features/utime/src/utime.h b/xlators/features/utime/src/utime.h index f8d5eca082e..236183d4bcc 100644 --- a/xlators/features/utime/src/utime.h +++ b/xlators/features/utime/src/utime.h @@ -16,4 +16,8 @@  #include "defaults.h"  #include "utime-autogen-fops.h" +typedef struct utime_priv { +    gf_boolean_t noatime; +} utime_priv_t; +  #endif /* __UTIME_H__ */ diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 8ff5ed0e2b5..fa260253a80 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -3650,6 +3650,14 @@ struct volopt_map_entry glusterd_volopt_map[] = {       .op_version = GD_OP_VERSION_4_1_0,       .description = "enable/disable utime translator on the volume.",       .flags = VOLOPT_FLAG_CLIENT_OPT | VOLOPT_FLAG_XLATOR_OPT}, +    {.key = "ctime.noatime", +     .voltype = "features/utime", +     .validate_fn = validate_boolean, +     .value = "on", +     .option = "noatime", +     .op_version = GD_OP_VERSION_5_0, +     .description = "enable/disable noatime option with ctime enabled.", +     .flags = VOLOPT_FLAG_CLIENT_OPT | VOLOPT_FLAG_XLATOR_OPT},      {.key = "feature.cloudsync-storetype",       .voltype = "features/cloudsync",       .op_version = GD_OP_VERSION_5_0, diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c index 82b05ebffc2..947d7be2d68 100644 --- a/xlators/storage/posix/src/posix-metadata.c +++ b/xlators/storage/posix/src/posix-metadata.c @@ -605,6 +605,10 @@ posix_set_ctime(call_frame_t *frame, xlator_t *this, const char *real_path,      if (priv->ctime) {          (void)posix_get_mdata_flag(frame->root->flags, &flag); +        if ((flag.ctime == 0) && (flag.mtime == 0) && (flag.atime == 0)) { +            goto out; +        } +          if (frame->root->ctime.tv_sec == 0) {              gf_msg(this->name, GF_LOG_WARNING, errno, P_MSG_SETMDATA_FAILED,                     "posix set mdata failed, No ctime : %s gfid:%s", real_path, @@ -640,6 +644,9 @@ posix_set_parent_ctime(call_frame_t *frame, xlator_t *this,      if (inode && priv->ctime) {          (void)posix_get_parent_mdata_flag(frame->root->flags, &flag); +        if ((flag.ctime == 0) && (flag.mtime == 0) && (flag.atime == 0)) { +            goto out; +        }          ret = posix_set_mdata_xattr(this, real_path, fd, inode,                                      &frame->root->ctime, stbuf, &flag,                                      _gf_false); @@ -649,5 +656,6 @@ posix_set_parent_ctime(call_frame_t *frame, xlator_t *this,                     uuid_utoa(inode->gfid));          }      } +out:      return;  }  | 
