summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2018-09-03 09:07:58 -0400
committerShyamsundar Ranganathan <srangana@redhat.com>2018-10-02 12:45:23 +0000
commit315b45f85ecba15d7fc8f2342468b89ee4747c48 (patch)
tree3b632dbe4f2422cb1adf897d91e32b9288546280
parentf7af62ecd893bd977cebc4e6586f1e524b36561b (diff)
ctime: Provide noatime option
Most of the applications are {c|m}time dependant and very few are atime dependant. So provide noatime option to not update atime when ctime feature is enabled. Also this option has to be enabled with ctime feature to avoid unnecessary self heal. Since AFR/EC reads data from single subvolume, atime is only updated in one subvolume triggering self heal. Backport of: > Patch: https://review.gluster.org/21073 > BUG: 1593538 > Change-Id: I085fb33c882296545345f5df194cde7b6cbc337e > Signed-off-by: Kotresh HR <khiremat@redhat.com> (cherry picked from commit 89636be4c73b12de2e11c75d8e59527bb243f147) updates: bz#1633015 Change-Id: I085fb33c882296545345f5df194cde7b6cbc337e Signed-off-by: Kotresh HR <khiremat@redhat.com>
-rw-r--r--libglusterfs/src/glfs-message-id.h1
-rw-r--r--tests/basic/ctime/ctime-noatime.t51
-rw-r--r--xlators/features/utime/src/Makefile.am2
-rw-r--r--xlators/features/utime/src/utime-gen-fops-c.py6
-rw-r--r--xlators/features/utime/src/utime-helpers.c15
-rw-r--r--xlators/features/utime/src/utime-helpers.h4
-rw-r--r--xlators/features/utime/src/utime-mem-types.h21
-rw-r--r--xlators/features/utime/src/utime-messages.h28
-rw-r--r--xlators/features/utime/src/utime.c52
-rw-r--r--xlators/features/utime/src/utime.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c8
-rw-r--r--xlators/storage/posix/src/posix-metadata.c8
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;
}