|
|
3604df |
From 66ea04f631a46c12fe1e40d1bb710d64e34764b2 Mon Sep 17 00:00:00 2001
|
|
|
3604df |
From: Poornima G <pgurusid@redhat.com>
|
|
|
3604df |
Date: Fri, 11 Dec 2015 05:12:07 -0500
|
|
|
3604df |
Subject: [PATCH 116/141] md-cache: Add cache invalidation support for metadata cache
|
|
|
3604df |
|
|
|
3604df |
Problem:
|
|
|
3604df |
md-cache currently updates its stat in cbks of selected fops.
|
|
|
3604df |
The default cache time is 1 second, if this is increasd to reap the
|
|
|
3604df |
benefits of caching, we may end up with stale cache for long time,
|
|
|
3604df |
as there is no logic yet to notify md-cache of backend changes by
|
|
|
3604df |
another client.
|
|
|
3604df |
|
|
|
3604df |
Solution:
|
|
|
3604df |
Use the existing upcall mechanism to invalidate the cache.
|
|
|
3604df |
For this feature to work, "features.cache-invalidation" volume
|
|
|
3604df |
option should be enabled.
|
|
|
3604df |
|
|
|
3604df |
This patch as is doesn't improve any performance, the benifit of the
|
|
|
3604df |
patch is that it provides coherency for stat cache, hence the cache
|
|
|
3604df |
timeout can be quite longer which in turn can improve the performance.
|
|
|
3604df |
|
|
|
3604df |
Change-Id: I2dbb0afa7b5e4a5a248f910188e0918e02f18692
|
|
|
3604df |
BUG: 1284873
|
|
|
3604df |
Signed-off-by: Poornima G <pgurusid@redhat.com>
|
|
|
3604df |
Reviewed-on: http://review.gluster.org/12951
|
|
|
3604df |
Smoke: Gluster Build System <jenkins@build.gluster.org>
|
|
|
3604df |
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
|
|
|
3604df |
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
3604df |
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
|
|
|
3604df |
Reviewed-on: https://code.engineering.redhat.com/gerrit/87029
|
|
|
3604df |
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
|
|
|
3604df |
Tested-by: Rajesh Joseph <rjoseph@redhat.com>
|
|
|
3604df |
---
|
|
|
3604df |
tests/bugs/md-cache/bug-1211863.t | 60 ++++-
|
|
|
3604df |
xlators/mgmt/glusterd/src/glusterd-volume-set.c | 6 +
|
|
|
3604df |
.../performance/md-cache/src/md-cache-messages.h | 10 +-
|
|
|
3604df |
xlators/performance/md-cache/src/md-cache.c | 258 ++++++++++++++++++--
|
|
|
3604df |
4 files changed, 304 insertions(+), 30 deletions(-)
|
|
|
3604df |
|
|
|
3604df |
diff --git a/tests/bugs/md-cache/bug-1211863.t b/tests/bugs/md-cache/bug-1211863.t
|
|
|
3604df |
index b969fbb..4fa9e33 100644
|
|
|
3604df |
--- a/tests/bugs/md-cache/bug-1211863.t
|
|
|
3604df |
+++ b/tests/bugs/md-cache/bug-1211863.t
|
|
|
3604df |
@@ -5,18 +5,64 @@
|
|
|
3604df |
|
|
|
3604df |
cleanup;
|
|
|
3604df |
|
|
|
3604df |
-TEST glusterd
|
|
|
3604df |
+## 1. Start glusterd
|
|
|
3604df |
+TEST glusterd;
|
|
|
3604df |
|
|
|
3604df |
-TEST $CLI volume create $V0 $H0:$B0/$V0
|
|
|
3604df |
+## 2. Lets create volume
|
|
|
3604df |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2,3};
|
|
|
3604df |
+
|
|
|
3604df |
+## 3. Start the volume
|
|
|
3604df |
TEST $CLI volume start $V0
|
|
|
3604df |
|
|
|
3604df |
-TEST $CLI volume set $V0 cache-samba-metadata on
|
|
|
3604df |
-EXPECT 'on' volinfo_field $V0 'performance.cache-samba-metadata'
|
|
|
3604df |
+## 4. Enable the upcall xlator, and increase the md-cache timeout to max
|
|
|
3604df |
+TEST $CLI volume set $V0 performance.md-cache-timeout 600
|
|
|
3604df |
+TEST $CLI volume set $V0 performance.cache-samba-metadata on
|
|
|
3604df |
|
|
|
3604df |
-TEST $CLI volume set $V0 cache-samba-metadata off
|
|
|
3604df |
-EXPECT 'off' volinfo_field $V0 'performance.cache-samba-metadata'
|
|
|
3604df |
+## 6. Create two gluster mounts
|
|
|
3604df |
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0
|
|
|
3604df |
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M1
|
|
|
3604df |
+
|
|
|
3604df |
+## 8. Create a file
|
|
|
3604df |
+TEST touch $M0/file1
|
|
|
3604df |
+
|
|
|
3604df |
+## 9. Setxattr from mount-0
|
|
|
3604df |
+TEST "setfattr -n user.DOSATTRIB -v "abc" $M0/file1"
|
|
|
3604df |
+## 10. Getxattr from mount-1, this should return the correct value as it is a fresh getxattr
|
|
|
3604df |
+TEST "getfattr -n user.DOSATTRIB $M1/file1 | grep -q abc"
|
|
|
3604df |
+
|
|
|
3604df |
+## 11. Now modify the same xattr from mount-0 again
|
|
|
3604df |
+TEST "setfattr -n user.DOSATTRIB -v "xyz" $M0/file1"
|
|
|
3604df |
+## 12. Since the xattr is already cached in mount-1 it returns the old xattr
|
|
|
3604df |
+ #value, until the timeout (600)
|
|
|
3604df |
+TEST "getfattr -n user.DOSATTRIB $M1/file1 | grep -q abc"
|
|
|
3604df |
+
|
|
|
3604df |
+## 13. Unmount to clean all the cache
|
|
|
3604df |
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0
|
|
|
3604df |
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1
|
|
|
3604df |
|
|
|
3604df |
+TEST $CLI volume set $V0 features.cache-invalidation on
|
|
|
3604df |
+TEST $CLI volume set $V0 features.cache-invalidation-timeout 600
|
|
|
3604df |
+
|
|
|
3604df |
+## 18. Restart the volume to restart the bick process
|
|
|
3604df |
TEST $CLI volume stop $V0
|
|
|
3604df |
-TEST $CLI volume delete $V0
|
|
|
3604df |
+TEST $CLI volume start $V0
|
|
|
3604df |
+
|
|
|
3604df |
+## 20. Create two gluster mounts
|
|
|
3604df |
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0
|
|
|
3604df |
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M1
|
|
|
3604df |
+
|
|
|
3604df |
+## 22. Repeat the tests 11-14, but this time since cache invalidation is on,
|
|
|
3604df |
+ #the getxattr will reflect the new value
|
|
|
3604df |
+TEST "setfattr -n user.DOSATTRIB -v "abc" $M0/file1"
|
|
|
3604df |
+TEST "getfattr -n user.DOSATTRIB $M1/file1 | grep -q abc"
|
|
|
3604df |
+TEST "setfattr -n user.DOSATTRIB -v "xyz" $M0/file1"
|
|
|
3604df |
+sleep 2; #There can be a very very small window where the next getxattr
|
|
|
3604df |
+ #reaches md-cache, before the cache-invalidation caused by previous
|
|
|
3604df |
+ #setxattr, reaches md-cache. Hence sleeping for 2 sec.
|
|
|
3604df |
+ #Also it should not be > 600.
|
|
|
3604df |
+TEST "getfattr -n user.DOSATTRIB $M1/file1 | grep -q xyz"
|
|
|
3604df |
+
|
|
|
3604df |
+TEST $CLI volume set $V0 cache-samba-metadata off
|
|
|
3604df |
+EXPECT 'off' volinfo_field $V0 'performance.cache-samba-metadata'
|
|
|
3604df |
|
|
|
3604df |
cleanup;
|
|
|
3604df |
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
|
|
|
3604df |
index 100e032..de7bcb4 100644
|
|
|
3604df |
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
|
|
|
3604df |
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
|
|
|
3604df |
@@ -1967,6 +1967,12 @@ struct volopt_map_entry glusterd_volopt_map[] = {
|
|
|
3604df |
.op_version = 2,
|
|
|
3604df |
.flags = OPT_FLAG_CLIENT_OPT
|
|
|
3604df |
},
|
|
|
3604df |
+ { .key = "features.cache-invalidation",
|
|
|
3604df |
+ .voltype = "performance/md-cache",
|
|
|
3604df |
+ .option = "cache-invalidation",
|
|
|
3604df |
+ .op_version = GD_OP_VERSION_3_9_0,
|
|
|
3604df |
+ .flags = OPT_FLAG_CLIENT_OPT
|
|
|
3604df |
+ },
|
|
|
3604df |
|
|
|
3604df |
/* Feature translators */
|
|
|
3604df |
{ .key = "features.uss",
|
|
|
3604df |
diff --git a/xlators/performance/md-cache/src/md-cache-messages.h b/xlators/performance/md-cache/src/md-cache-messages.h
|
|
|
3604df |
index 2fe8d45..a4259ba 100644
|
|
|
3604df |
--- a/xlators/performance/md-cache/src/md-cache-messages.h
|
|
|
3604df |
+++ b/xlators/performance/md-cache/src/md-cache-messages.h
|
|
|
3604df |
@@ -40,7 +40,7 @@
|
|
|
3604df |
*/
|
|
|
3604df |
|
|
|
3604df |
#define GLFS_MD_CACHE_BASE GLFS_MSGID_COMP_MD_CACHE
|
|
|
3604df |
-#define GLFS_MD_CACHE_NUM_MESSAGES 1
|
|
|
3604df |
+#define GLFS_MD_CACHE_NUM_MESSAGES 2
|
|
|
3604df |
#define GLFS_MSGID_END (GLFS_MD_CACHE_BASE + GLFS_MD_CACHE_NUM_MESSAGES + 1)
|
|
|
3604df |
|
|
|
3604df |
/* Messages with message IDs */
|
|
|
3604df |
@@ -58,6 +58,14 @@
|
|
|
3604df |
|
|
|
3604df |
#define MD_CACHE_MSG_NO_MEMORY (GLFS_MD_CACHE_BASE + 1)
|
|
|
3604df |
|
|
|
3604df |
+/*!
|
|
|
3604df |
+ * @messageid
|
|
|
3604df |
+ * @diagnosis
|
|
|
3604df |
+ * @recommendedaction None
|
|
|
3604df |
+ *
|
|
|
3604df |
+ */
|
|
|
3604df |
+
|
|
|
3604df |
+#define MD_CACHE_MSG_DISCARD_UPDATE (GLFS_MD_CACHE_BASE + 2)
|
|
|
3604df |
|
|
|
3604df |
/*------------*/
|
|
|
3604df |
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
|
|
|
3604df |
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c
|
|
|
3604df |
index 1ad9e8e..fd2b366 100644
|
|
|
3604df |
--- a/xlators/performance/md-cache/src/md-cache.c
|
|
|
3604df |
+++ b/xlators/performance/md-cache/src/md-cache.c
|
|
|
3604df |
@@ -16,6 +16,8 @@
|
|
|
3604df |
#include "md-cache-mem-types.h"
|
|
|
3604df |
#include "compat-errno.h"
|
|
|
3604df |
#include "glusterfs-acl.h"
|
|
|
3604df |
+#include "defaults.h"
|
|
|
3604df |
+#include "upcall-utils.h"
|
|
|
3604df |
#include <assert.h>
|
|
|
3604df |
#include <sys/time.h>
|
|
|
3604df |
#include "md-cache-messages.h"
|
|
|
3604df |
@@ -34,6 +36,9 @@ struct mdc_conf {
|
|
|
3604df |
gf_boolean_t force_readdirp;
|
|
|
3604df |
gf_boolean_t cache_swift_metadata;
|
|
|
3604df |
gf_boolean_t cache_samba_metadata;
|
|
|
3604df |
+ gf_boolean_t mdc_invalidation;
|
|
|
3604df |
+ time_t last_child_down;
|
|
|
3604df |
+ gf_lock_t lock;
|
|
|
3604df |
};
|
|
|
3604df |
|
|
|
3604df |
|
|
|
3604df |
@@ -328,20 +333,58 @@ unlock:
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
|
|
|
3604df |
+/* Cache is valid if:
|
|
|
3604df |
+ * - It is not cached before any brick was down. Brick down case is handled by
|
|
|
3604df |
+ * invalidating all the cache when any brick went down.
|
|
|
3604df |
+ * - The cache time is not expired
|
|
|
3604df |
+ */
|
|
|
3604df |
+static gf_boolean_t
|
|
|
3604df |
+__is_cache_valid (xlator_t *this, time_t mdc_time)
|
|
|
3604df |
+{
|
|
|
3604df |
+ time_t now = 0;
|
|
|
3604df |
+ gf_boolean_t ret = _gf_true;
|
|
|
3604df |
+ struct mdc_conf *conf = NULL;
|
|
|
3604df |
+ int timeout = 0;
|
|
|
3604df |
+ time_t last_child_down = 0;
|
|
|
3604df |
+
|
|
|
3604df |
+ conf = this->private;
|
|
|
3604df |
+
|
|
|
3604df |
+ /* conf->lock here is not taken deliberately, so that the multi
|
|
|
3604df |
+ * threaded IO doesn't contend on a global lock. While updating
|
|
|
3604df |
+ * the variable, the lock is taken, so that atleast the writes are
|
|
|
3604df |
+ * intact. The read of last_child_down may return junk, but that
|
|
|
3604df |
+ * is for a very short period of time.
|
|
|
3604df |
+ */
|
|
|
3604df |
+ last_child_down = conf->last_child_down;
|
|
|
3604df |
+ timeout = conf->timeout;
|
|
|
3604df |
+
|
|
|
3604df |
+ time (&now;;
|
|
|
3604df |
+
|
|
|
3604df |
+ if ((mdc_time == 0) ||
|
|
|
3604df |
+ ((last_child_down != 0) && (mdc_time < last_child_down))) {
|
|
|
3604df |
+ ret = _gf_false;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+ if (now >= (mdc_time + timeout)) {
|
|
|
3604df |
+ ret = _gf_false;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+out:
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+
|
|
|
3604df |
static gf_boolean_t
|
|
|
3604df |
is_md_cache_iatt_valid (xlator_t *this, struct md_cache *mdc)
|
|
|
3604df |
{
|
|
|
3604df |
- struct mdc_conf *conf = NULL;
|
|
|
3604df |
- time_t now = 0;
|
|
|
3604df |
gf_boolean_t ret = _gf_true;
|
|
|
3604df |
- conf = this->private;
|
|
|
3604df |
-
|
|
|
3604df |
- time (&now;;
|
|
|
3604df |
|
|
|
3604df |
LOCK (&mdc->lock);
|
|
|
3604df |
{
|
|
|
3604df |
- if (now >= (mdc->ia_time + conf->timeout))
|
|
|
3604df |
- ret = _gf_false;
|
|
|
3604df |
+ ret = __is_cache_valid (this, mdc->ia_time);
|
|
|
3604df |
+ if (ret == _gf_false)
|
|
|
3604df |
+ mdc->ia_time = 0;
|
|
|
3604df |
}
|
|
|
3604df |
UNLOCK (&mdc->lock);
|
|
|
3604df |
|
|
|
3604df |
@@ -352,18 +395,13 @@ is_md_cache_iatt_valid (xlator_t *this, struct md_cache *mdc)
|
|
|
3604df |
static gf_boolean_t
|
|
|
3604df |
is_md_cache_xatt_valid (xlator_t *this, struct md_cache *mdc)
|
|
|
3604df |
{
|
|
|
3604df |
- struct mdc_conf *conf = NULL;
|
|
|
3604df |
- time_t now = 0;
|
|
|
3604df |
gf_boolean_t ret = _gf_true;
|
|
|
3604df |
|
|
|
3604df |
- conf = this->private;
|
|
|
3604df |
-
|
|
|
3604df |
- time (&now;;
|
|
|
3604df |
-
|
|
|
3604df |
LOCK (&mdc->lock);
|
|
|
3604df |
{
|
|
|
3604df |
- if (now >= (mdc->xa_time + conf->timeout))
|
|
|
3604df |
- ret = _gf_false;
|
|
|
3604df |
+ ret = __is_cache_valid (this, mdc->xa_time);
|
|
|
3604df |
+ if (ret == _gf_false)
|
|
|
3604df |
+ mdc->xa_time = 0;
|
|
|
3604df |
}
|
|
|
3604df |
UNLOCK (&mdc->lock);
|
|
|
3604df |
|
|
|
3604df |
@@ -413,12 +451,14 @@ int
|
|
|
3604df |
mdc_inode_iatt_set_validate(xlator_t *this, inode_t *inode, struct iatt *prebuf,
|
|
|
3604df |
struct iatt *iatt)
|
|
|
3604df |
{
|
|
|
3604df |
- int ret = -1;
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
struct md_cache *mdc = NULL;
|
|
|
3604df |
|
|
|
3604df |
mdc = mdc_inode_prep (this, inode);
|
|
|
3604df |
- if (!mdc)
|
|
|
3604df |
+ if (!mdc) {
|
|
|
3604df |
+ ret = -1;
|
|
|
3604df |
goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
|
|
|
3604df |
LOCK (&mdc->lock);
|
|
|
3604df |
{
|
|
|
3604df |
@@ -427,6 +467,33 @@ mdc_inode_iatt_set_validate(xlator_t *this, inode_t *inode, struct iatt *prebuf,
|
|
|
3604df |
goto unlock;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
+ /* There could be a race in invalidation, where the
|
|
|
3604df |
+ * invalidations in order A, B reaches md-cache in the order
|
|
|
3604df |
+ * B, A. Hence, make sure the invalidation A is discarded if
|
|
|
3604df |
+ * it comes after B. ctime of a file is always in ascending
|
|
|
3604df |
+ * order unlike atime and mtime(which can be changed by user
|
|
|
3604df |
+ * to any date), also ctime gets updates when atime/mtime
|
|
|
3604df |
+ * changes, hence check for ctime only.
|
|
|
3604df |
+ */
|
|
|
3604df |
+ if (mdc->md_ctime > iatt->ia_ctime) {
|
|
|
3604df |
+ gf_msg_callingfn (this->name, GF_LOG_DEBUG, EINVAL,
|
|
|
3604df |
+ MD_CACHE_MSG_DISCARD_UPDATE,
|
|
|
3604df |
+ "discarding the iatt validate "
|
|
|
3604df |
+ "request");
|
|
|
3604df |
+ ret = -1;
|
|
|
3604df |
+ goto unlock;
|
|
|
3604df |
+
|
|
|
3604df |
+ }
|
|
|
3604df |
+ if ((mdc->md_ctime == iatt->ia_ctime) &&
|
|
|
3604df |
+ (mdc->md_ctime_nsec > iatt->ia_ctime_nsec)) {
|
|
|
3604df |
+ gf_msg_callingfn (this->name, GF_LOG_DEBUG, EINVAL,
|
|
|
3604df |
+ MD_CACHE_MSG_DISCARD_UPDATE,
|
|
|
3604df |
+ "discarding the iatt validate "
|
|
|
3604df |
+ "request(ctime_nsec)");
|
|
|
3604df |
+ ret = -1;
|
|
|
3604df |
+ goto unlock;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
/*
|
|
|
3604df |
* Invalidate the inode if the mtime or ctime has changed
|
|
|
3604df |
* and the prebuf doesn't match the value we have cached.
|
|
|
3604df |
@@ -450,7 +517,7 @@ mdc_inode_iatt_set_validate(xlator_t *this, inode_t *inode, struct iatt *prebuf,
|
|
|
3604df |
}
|
|
|
3604df |
unlock:
|
|
|
3604df |
UNLOCK (&mdc->lock);
|
|
|
3604df |
- ret = 0;
|
|
|
3604df |
+
|
|
|
3604df |
out:
|
|
|
3604df |
return ret;
|
|
|
3604df |
}
|
|
|
3604df |
@@ -2300,15 +2367,81 @@ mdc_key_load_set (struct mdc_key *keys, char *pattern, gf_boolean_t val)
|
|
|
3604df |
return 0;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
+struct set {
|
|
|
3604df |
+ inode_t *inode;
|
|
|
3604df |
+ xlator_t *this;
|
|
|
3604df |
+};
|
|
|
3604df |
+
|
|
|
3604df |
+static int
|
|
|
3604df |
+mdc_inval_xatt (dict_t *d, char *k, data_t *v, void *tmp)
|
|
|
3604df |
+{
|
|
|
3604df |
+ struct set *tmp1 = NULL;
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+
|
|
|
3604df |
+ tmp1 = (struct set *)tmp;
|
|
|
3604df |
+ ret = mdc_inode_xatt_unset (tmp1->this, tmp1->inode, k);
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+static int
|
|
|
3604df |
+mdc_invalidate (xlator_t *this, void *data)
|
|
|
3604df |
+{
|
|
|
3604df |
+ struct gf_upcall *up_data = NULL;
|
|
|
3604df |
+ struct gf_upcall_cache_invalidation *up_ci = NULL;
|
|
|
3604df |
+ inode_t *inode = NULL;
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+ struct set tmp = {0, };
|
|
|
3604df |
+ inode_table_t *itable = NULL;
|
|
|
3604df |
+
|
|
|
3604df |
+ up_data = (struct gf_upcall *)data;
|
|
|
3604df |
+
|
|
|
3604df |
+ if (up_data->event_type != GF_UPCALL_CACHE_INVALIDATION)
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+
|
|
|
3604df |
+ up_ci = (struct gf_upcall_cache_invalidation *)up_data->data;
|
|
|
3604df |
+
|
|
|
3604df |
+ itable = ((xlator_t *)this->graph->top)->itable;
|
|
|
3604df |
+ inode = inode_find (itable, up_data->gfid);
|
|
|
3604df |
+ if (!inode) {
|
|
|
3604df |
+ ret = -1;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+ if (up_ci->flags & IATT_UPDATE_FLAGS) {
|
|
|
3604df |
+ ret = mdc_inode_iatt_set_validate (this, inode, NULL,
|
|
|
3604df |
+ &up_ci->stat);
|
|
|
3604df |
+ /* one of the scenarios where ret < 0 is when this invalidate
|
|
|
3604df |
+ * is older than the current stat, in that case do not
|
|
|
3604df |
+ * update the xattrs as well
|
|
|
3604df |
+ */
|
|
|
3604df |
+ if (ret < 0)
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ if (up_ci->flags & UP_XATTR) {
|
|
|
3604df |
+ ret = mdc_inode_xatt_update (this, inode, up_ci->dict);
|
|
|
3604df |
+ } else if (up_ci->flags & UP_XATTR_RM) {
|
|
|
3604df |
+ tmp.inode = inode;
|
|
|
3604df |
+ tmp.this = this;
|
|
|
3604df |
+ ret = dict_foreach (up_ci->dict, mdc_inval_xatt, &tmp);
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+out:
|
|
|
3604df |
+ if (inode)
|
|
|
3604df |
+ inode_unref (inode);
|
|
|
3604df |
+
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
|
|
|
3604df |
int
|
|
|
3604df |
reconfigure (xlator_t *this, dict_t *options)
|
|
|
3604df |
{
|
|
|
3604df |
struct mdc_conf *conf = NULL;
|
|
|
3604df |
+ int timeout = 0;
|
|
|
3604df |
|
|
|
3604df |
conf = this->private;
|
|
|
3604df |
|
|
|
3604df |
- GF_OPTION_RECONF ("md-cache-timeout", conf->timeout, options, int32, out);
|
|
|
3604df |
+ GF_OPTION_RECONF ("md-cache-timeout", timeout, options, int32, out);
|
|
|
3604df |
|
|
|
3604df |
GF_OPTION_RECONF ("cache-selinux", conf->cache_selinux, options, bool, out);
|
|
|
3604df |
mdc_key_load_set (mdc_keys, "security.", conf->cache_selinux);
|
|
|
3604df |
@@ -2330,7 +2463,19 @@ reconfigure (xlator_t *this, dict_t *options)
|
|
|
3604df |
conf->cache_samba_metadata);
|
|
|
3604df |
|
|
|
3604df |
GF_OPTION_RECONF("force-readdirp", conf->force_readdirp, options, bool, out);
|
|
|
3604df |
-
|
|
|
3604df |
+ GF_OPTION_RECONF("cache-invalidation", conf->mdc_invalidation, options,
|
|
|
3604df |
+ bool, out);
|
|
|
3604df |
+
|
|
|
3604df |
+ /* If timeout is greater than 60s (default before the patch that added
|
|
|
3604df |
+ * cache invalidation support was added) then, cache invalidation
|
|
|
3604df |
+ * feature for md-cache needs to be enabled, if not set timeout to the
|
|
|
3604df |
+ * previous max which is 60s
|
|
|
3604df |
+ */
|
|
|
3604df |
+ if ((timeout > 60) && (!conf->mdc_invalidation)) {
|
|
|
3604df |
+ conf->timeout = 60;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ conf->timeout = timeout;
|
|
|
3604df |
out:
|
|
|
3604df |
return 0;
|
|
|
3604df |
}
|
|
|
3604df |
@@ -2348,6 +2493,7 @@ int
|
|
|
3604df |
init (xlator_t *this)
|
|
|
3604df |
{
|
|
|
3604df |
struct mdc_conf *conf = NULL;
|
|
|
3604df |
+ int timeout = 0;
|
|
|
3604df |
|
|
|
3604df |
conf = GF_CALLOC (sizeof (*conf), 1, gf_mdc_mt_mdc_conf_t);
|
|
|
3604df |
if (!conf) {
|
|
|
3604df |
@@ -2356,7 +2502,7 @@ init (xlator_t *this)
|
|
|
3604df |
return -1;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
- GF_OPTION_INIT ("md-cache-timeout", conf->timeout, int32, out);
|
|
|
3604df |
+ GF_OPTION_INIT ("md-cache-timeout", timeout, int32, out);
|
|
|
3604df |
|
|
|
3604df |
GF_OPTION_INIT ("cache-selinux", conf->cache_selinux, bool, out);
|
|
|
3604df |
mdc_key_load_set (mdc_keys, "security.", conf->cache_selinux);
|
|
|
3604df |
@@ -2378,6 +2524,22 @@ init (xlator_t *this)
|
|
|
3604df |
conf->cache_samba_metadata);
|
|
|
3604df |
|
|
|
3604df |
GF_OPTION_INIT("force-readdirp", conf->force_readdirp, bool, out);
|
|
|
3604df |
+ GF_OPTION_INIT("cache-invalidation", conf->mdc_invalidation, bool, out);
|
|
|
3604df |
+
|
|
|
3604df |
+ LOCK_INIT (&conf->lock);
|
|
|
3604df |
+ time (&conf->last_child_down);
|
|
|
3604df |
+
|
|
|
3604df |
+ /* If timeout is greater than 60s (default before the patch that added
|
|
|
3604df |
+ * cache invalidation support was added) then, cache invalidation
|
|
|
3604df |
+ * feature for md-cache needs to be enabled, if not set timeout to the
|
|
|
3604df |
+ * previous max which is 60s
|
|
|
3604df |
+ */
|
|
|
3604df |
+ if ((timeout > 60) && (!conf->mdc_invalidation)) {
|
|
|
3604df |
+ conf->timeout = 60;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ conf->timeout = timeout;
|
|
|
3604df |
+
|
|
|
3604df |
out:
|
|
|
3604df |
this->private = conf;
|
|
|
3604df |
|
|
|
3604df |
@@ -2386,6 +2548,52 @@ out:
|
|
|
3604df |
|
|
|
3604df |
|
|
|
3604df |
void
|
|
|
3604df |
+mdc_update_child_down_time (xlator_t *this, time_t *now)
|
|
|
3604df |
+{
|
|
|
3604df |
+ struct mdc_conf *conf = NULL;
|
|
|
3604df |
+
|
|
|
3604df |
+ conf = this->private;
|
|
|
3604df |
+
|
|
|
3604df |
+ LOCK (&conf->lock);
|
|
|
3604df |
+ {
|
|
|
3604df |
+ conf->last_child_down = *now;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ UNLOCK (&conf->lock);
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+
|
|
|
3604df |
+int
|
|
|
3604df |
+notify (xlator_t *this, int event, void *data, ...)
|
|
|
3604df |
+{
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+ struct mdc_conf *conf = NULL;
|
|
|
3604df |
+ time_t now = 0;
|
|
|
3604df |
+
|
|
|
3604df |
+ conf = this->private;
|
|
|
3604df |
+ switch (event) {
|
|
|
3604df |
+ case GF_EVENT_CHILD_DOWN:
|
|
|
3604df |
+ case GF_EVENT_SOME_CHILD_DOWN:
|
|
|
3604df |
+ case GF_EVENT_CHILD_MODIFIED:
|
|
|
3604df |
+ time (&now;;
|
|
|
3604df |
+ mdc_update_child_down_time (this, &now;;
|
|
|
3604df |
+ ret = default_notify (this, event, data);
|
|
|
3604df |
+ break;
|
|
|
3604df |
+ case GF_EVENT_UPCALL:
|
|
|
3604df |
+ if (conf->mdc_invalidation)
|
|
|
3604df |
+ ret = mdc_invalidate (this, data);
|
|
|
3604df |
+ if (default_notify (this, event, data) != 0)
|
|
|
3604df |
+ ret = -1;
|
|
|
3604df |
+ break;
|
|
|
3604df |
+ default:
|
|
|
3604df |
+ ret = default_notify (this, event, data);
|
|
|
3604df |
+ break;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+
|
|
|
3604df |
+void
|
|
|
3604df |
fini (xlator_t *this)
|
|
|
3604df |
{
|
|
|
3604df |
return;
|
|
|
3604df |
@@ -2453,7 +2661,7 @@ struct volume_options options[] = {
|
|
|
3604df |
{ .key = {"md-cache-timeout"},
|
|
|
3604df |
.type = GF_OPTION_TYPE_INT,
|
|
|
3604df |
.min = 0,
|
|
|
3604df |
- .max = 60,
|
|
|
3604df |
+ .max = 600,
|
|
|
3604df |
.default_value = "1",
|
|
|
3604df |
.description = "Time period after which cache has to be refreshed",
|
|
|
3604df |
},
|
|
|
3604df |
@@ -2463,5 +2671,11 @@ struct volume_options options[] = {
|
|
|
3604df |
.description = "Convert all readdir requests to readdirplus to "
|
|
|
3604df |
"collect stat info on each entry.",
|
|
|
3604df |
},
|
|
|
3604df |
+ { .key = {"cache-invalidation"},
|
|
|
3604df |
+ .type = GF_OPTION_TYPE_BOOL,
|
|
|
3604df |
+ .default_value = "false",
|
|
|
3604df |
+ .description = "When \"on\", invalidates/updates the metadata cache "
|
|
|
3604df |
+ "on receiving of the cache-invalidation notifications",
|
|
|
3604df |
+ },
|
|
|
3604df |
{ .key = {NULL} },
|
|
|
3604df |
};
|
|
|
3604df |
--
|
|
|
3604df |
1.7.1
|
|
|
3604df |
|