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 5a8d8a10e25..937c9e98409 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -3670,6 +3670,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; } |