summaryrefslogtreecommitdiff
path: root/0460-cluster-ec-Remove-stale-entries-from-indices-xattrop.patch
diff options
context:
space:
mode:
Diffstat (limited to '0460-cluster-ec-Remove-stale-entries-from-indices-xattrop.patch')
-rw-r--r--0460-cluster-ec-Remove-stale-entries-from-indices-xattrop.patch152
1 files changed, 152 insertions, 0 deletions
diff --git a/0460-cluster-ec-Remove-stale-entries-from-indices-xattrop.patch b/0460-cluster-ec-Remove-stale-entries-from-indices-xattrop.patch
new file mode 100644
index 0000000..e31349a
--- /dev/null
+++ b/0460-cluster-ec-Remove-stale-entries-from-indices-xattrop.patch
@@ -0,0 +1,152 @@
+From b166826b283d9071532174ebbec857dea600064b Mon Sep 17 00:00:00 2001
+From: Ashish Pandey <aspandey@redhat.com>
+Date: Thu, 23 Jul 2020 11:07:32 +0530
+Subject: [PATCH 460/465] cluster/ec: Remove stale entries from indices/xattrop
+ folder
+
+Problem:
+If a gfid is present in indices/xattrop folder while
+the file/dir is actaully healthy and all the xattrs are healthy,
+it causes lot of lookups by shd on an entry which does not need
+to be healed.
+This whole process eats up lot of CPU usage without doing meaningful
+work.
+
+Solution:
+Set trusted.ec.dirty xattr of the entry so that actual heal process
+happens and at the end of it, during unset of dirty, gfid enrty from
+indices/xattrop will be removed.
+
+>Upstream patch : https://review.gluster.org/#/c/glusterfs/+/24765/
+>Fixes: #1385
+
+Change-Id: Ib1b9377d8dda384bba49523e9ff6ba9f0699cc1b
+BUG: 1785714
+Signed-off-by: Ashish Pandey <aspandey@redhat.com>
+Reviewed-on: https://code.engineering.redhat.com/gerrit/208591
+Tested-by: RHGS Build Bot <nigelb@redhat.com>
+Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
+---
+ xlators/cluster/ec/src/ec-heal.c | 73 ++++++++++++++++++++++++++++++++++++++-
+ xlators/cluster/ec/src/ec-types.h | 7 +++-
+ 2 files changed, 78 insertions(+), 2 deletions(-)
+
+diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
+index e2de879..7d25853 100644
+--- a/xlators/cluster/ec/src/ec-heal.c
++++ b/xlators/cluster/ec/src/ec-heal.c
+@@ -2488,6 +2488,59 @@ out:
+ return ret;
+ }
+
++int
++ec_heal_set_dirty_without_lock(call_frame_t *frame, ec_t *ec, inode_t *inode)
++{
++ int i = 0;
++ int ret = 0;
++ dict_t **xattr = NULL;
++ loc_t loc = {0};
++ uint64_t dirty_xattr[EC_VERSION_SIZE] = {0};
++ unsigned char *on = NULL;
++ default_args_cbk_t *replies = NULL;
++ dict_t *dict = NULL;
++
++ /* Allocate the required memory */
++ loc.inode = inode_ref(inode);
++ gf_uuid_copy(loc.gfid, inode->gfid);
++ on = alloca0(ec->nodes);
++ EC_REPLIES_ALLOC(replies, ec->nodes);
++ xattr = GF_CALLOC(ec->nodes, sizeof(*xattr), gf_common_mt_pointer);
++ if (!xattr) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ dict = dict_new();
++ if (!dict) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ for (i = 0; i < ec->nodes; i++) {
++ xattr[i] = dict;
++ on[i] = 1;
++ }
++ dirty_xattr[EC_METADATA_TXN] = hton64(1);
++ ret = dict_set_static_bin(dict, EC_XATTR_DIRTY, dirty_xattr,
++ (sizeof(*dirty_xattr) * EC_VERSION_SIZE));
++ if (ret < 0) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ PARALLEL_FOP_ONLIST(ec->xl_list, on, ec->nodes, replies, frame,
++ ec_wind_xattrop_parallel, &loc, GF_XATTROP_ADD_ARRAY64,
++ xattr, NULL);
++out:
++ if (dict) {
++ dict_unref(dict);
++ }
++ if (xattr) {
++ GF_FREE(xattr);
++ }
++ cluster_replies_wipe(replies, ec->nodes);
++ loc_wipe(&loc);
++ return ret;
++}
++
+ void
+ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
+ {
+@@ -2563,7 +2616,18 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
+ ec_heal_inspect(frame, ec, loc->inode, up_subvols, _gf_false, _gf_false,
+ &need_heal);
+
+- if (need_heal == EC_HEAL_NONEED) {
++ if (need_heal == EC_HEAL_PURGE_INDEX) {
++ gf_msg(ec->xl->name, GF_LOG_INFO, 0, EC_MSG_HEAL_FAIL,
++ "Index entry needs to be purged for: %s ",
++ uuid_utoa(loc->gfid));
++ /* We need to send xattrop to set dirty flag so that it can be
++ * healed and index entry could be removed. We need not to take lock
++ * on this entry to do so as we are just setting dirty flag which
++ * actually increases the trusted.ec.dirty count and does not set
++ * the new value.
++ * This will make sure that it is not interfering in other fops.*/
++ ec_heal_set_dirty_without_lock(frame, ec, loc->inode);
++ } else if (need_heal == EC_HEAL_NONEED) {
+ gf_msg(ec->xl->name, GF_LOG_DEBUG, 0, EC_MSG_HEAL_FAIL,
+ "Heal is not required for : %s ", uuid_utoa(loc->gfid));
+ goto out;
+@@ -2958,6 +3022,13 @@ _need_heal_calculate(ec_t *ec, uint64_t *dirty, unsigned char *sources,
+ goto out;
+ }
+ }
++ /* If lock count is 0, all dirty flags are 0 and all the
++ * versions are macthing then why are we here. It looks
++ * like something went wrong while removing the index entries
++ * after completing a successful heal or fop. In this case
++ * we need to remove this index entry to avoid triggering heal
++ * in a loop and causing lookups again and again*/
++ *need_heal = EC_HEAL_PURGE_INDEX;
+ } else {
+ for (i = 0; i < ec->nodes; i++) {
+ /* Since each lock can only increment the dirty
+diff --git a/xlators/cluster/ec/src/ec-types.h b/xlators/cluster/ec/src/ec-types.h
+index f15429d..700dc39 100644
+--- a/xlators/cluster/ec/src/ec-types.h
++++ b/xlators/cluster/ec/src/ec-types.h
+@@ -130,7 +130,12 @@ typedef void (*ec_resume_f)(ec_fop_data_t *, int32_t);
+
+ enum _ec_read_policy { EC_ROUND_ROBIN, EC_GFID_HASH, EC_READ_POLICY_MAX };
+
+-enum _ec_heal_need { EC_HEAL_NONEED, EC_HEAL_MAYBE, EC_HEAL_MUST };
++enum _ec_heal_need {
++ EC_HEAL_NONEED,
++ EC_HEAL_MAYBE,
++ EC_HEAL_MUST,
++ EC_HEAL_PURGE_INDEX
++};
+
+ enum _ec_stripe_part { EC_STRIPE_HEAD, EC_STRIPE_TAIL };
+
+--
+1.8.3.1
+