summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 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;
}