17b94a
From c2b1c50f06cc59b47c9c834617dff2aed7177a78 Mon Sep 17 00:00:00 2001
17b94a
From: Ashish Pandey <aspandey@redhat.com>
17b94a
Date: Mon, 18 Mar 2019 12:54:54 +0530
17b94a
Subject: [PATCH 164/169] cluster/ec: Fix handling of heal info cases without
17b94a
 locks
17b94a
17b94a
When we use heal info command, it takes lot of time as in
17b94a
some cases it takes lock on entries to find out if the
17b94a
entry actually needs heal or not.
17b94a
17b94a
There are some cases where we can avoid these locks and
17b94a
can conclude if the entry needs heal or not.
17b94a
17b94a
1 - We do a lookup (without lock) on an entry, which we found in
17b94a
.glusterfs/indices/xattrop, and find that lock count is
17b94a
zero. Now if the file contains dirty bit set on all or any
17b94a
brick, we can say that this entry needs heal.
17b94a
17b94a
2 - If the lock count is one and dirty is greater than 1,
17b94a
then it also means that some fop had left the dirty bit set
17b94a
which made the dirty count of current fop (which has taken lock)
17b94a
more than one. At this point also we can definitely say that
17b94a
this entry needs heal.
17b94a
17b94a
This patch is modifying code to take into consideration above two
17b94a
points.
17b94a
It is also changing code to not to call ec_heal_inspect if ec_heal_do
17b94a
was called from client side heal. Client side heal triggeres heal
17b94a
only when it is sure that it requires heal.
17b94a
17b94a
[We have changed the code to not to call heal for lookup]
17b94a
17b94a
Upstream patch -
17b94a
https://review.gluster.org/#/c/glusterfs/+/22372/
17b94a
17b94a
Fixes: bz#1716385
17b94a
Change-Id: I7f09f0ecd12f65a353297aefd57026fd2bebdf9c
17b94a
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
17b94a
Reviewed-on: https://code.engineering.redhat.com/gerrit/172579
17b94a
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
17b94a
Tested-by: RHGS Build Bot <nigelb@redhat.com>
17b94a
---
17b94a
 xlators/cluster/ec/src/ec-heal.c | 42 ++++++++++++++++------------------------
17b94a
 1 file changed, 17 insertions(+), 25 deletions(-)
17b94a
17b94a
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
17b94a
index 3aa04fb..2fa1f11 100644
17b94a
--- a/xlators/cluster/ec/src/ec-heal.c
17b94a
+++ b/xlators/cluster/ec/src/ec-heal.c
17b94a
@@ -2541,13 +2541,15 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
17b94a
 
17b94a
     /* Mount triggers heal only when it detects that it must need heal, shd
17b94a
      * triggers heals periodically which need not be thorough*/
17b94a
-    ec_heal_inspect(frame, ec, loc->inode, up_subvols, _gf_false,
17b94a
-                    !ec->shd.iamshd, &need_heal);
17b94a
+    if (ec->shd.iamshd) {
17b94a
+        ec_heal_inspect(frame, ec, loc->inode, up_subvols, _gf_false, _gf_false,
17b94a
+                        &need_heal);
17b94a
 
17b94a
-    if (need_heal == EC_HEAL_NONEED) {
17b94a
-        gf_msg(ec->xl->name, GF_LOG_DEBUG, 0, EC_MSG_HEAL_FAIL,
17b94a
-               "Heal is not required for : %s ", uuid_utoa(loc->gfid));
17b94a
-        goto out;
17b94a
+        if (need_heal == EC_HEAL_NONEED) {
17b94a
+            gf_msg(ec->xl->name, GF_LOG_DEBUG, 0, EC_MSG_HEAL_FAIL,
17b94a
+                   "Heal is not required for : %s ", uuid_utoa(loc->gfid));
17b94a
+            goto out;
17b94a
+        }
17b94a
     }
17b94a
     sources = alloca0(ec->nodes);
17b94a
     healed_sinks = alloca0(ec->nodes);
17b94a
@@ -2902,7 +2904,7 @@ out:
17b94a
 static int32_t
17b94a
 _need_heal_calculate(ec_t *ec, uint64_t *dirty, unsigned char *sources,
17b94a
                      gf_boolean_t self_locked, int32_t lock_count,
17b94a
-                     ec_heal_need_t *need_heal)
17b94a
+                     ec_heal_need_t *need_heal, uint64_t *versions)
17b94a
 {
17b94a
     int i = 0;
17b94a
     int source_count = 0;
17b94a
@@ -2912,7 +2914,7 @@ _need_heal_calculate(ec_t *ec, uint64_t *dirty, unsigned char *sources,
17b94a
         *need_heal = EC_HEAL_NONEED;
17b94a
         if (self_locked || lock_count == 0) {
17b94a
             for (i = 0; i < ec->nodes; i++) {
17b94a
-                if (dirty[i]) {
17b94a
+                if (dirty[i] || (versions[i] != versions[0])) {
17b94a
                     *need_heal = EC_HEAL_MUST;
17b94a
                     goto out;
17b94a
                 }
17b94a
@@ -2928,6 +2930,9 @@ _need_heal_calculate(ec_t *ec, uint64_t *dirty, unsigned char *sources,
17b94a
                     *need_heal = EC_HEAL_MUST;
17b94a
                     goto out;
17b94a
                 }
17b94a
+                if (dirty[i] != dirty[0] || (versions[i] != versions[0])) {
17b94a
+                    *need_heal = EC_HEAL_MAYBE;
17b94a
+                }
17b94a
             }
17b94a
         }
17b94a
     } else {
17b94a
@@ -2948,7 +2953,6 @@ ec_need_metadata_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies,
17b94a
     unsigned char *healed_sinks = NULL;
17b94a
     uint64_t *meta_versions = NULL;
17b94a
     int ret = 0;
17b94a
-    int i = 0;
17b94a
 
17b94a
     sources = alloca0(ec->nodes);
17b94a
     healed_sinks = alloca0(ec->nodes);
17b94a
@@ -2961,15 +2965,7 @@ ec_need_metadata_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies,
17b94a
     }
17b94a
 
17b94a
     ret = _need_heal_calculate(ec, dirty, sources, self_locked, lock_count,
17b94a
-                               need_heal);
17b94a
-    if (ret == ec->nodes && *need_heal == EC_HEAL_NONEED) {
17b94a
-        for (i = 1; i < ec->nodes; i++) {
17b94a
-            if (meta_versions[i] != meta_versions[0]) {
17b94a
-                *need_heal = EC_HEAL_MUST;
17b94a
-                goto out;
17b94a
-            }
17b94a
-        }
17b94a
-    }
17b94a
+                               need_heal, meta_versions);
17b94a
 out:
17b94a
     return ret;
17b94a
 }
17b94a
@@ -3005,7 +3001,7 @@ ec_need_data_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies,
17b94a
     }
17b94a
 
17b94a
     ret = _need_heal_calculate(ec, dirty, sources, self_locked, lock_count,
17b94a
-                               need_heal);
17b94a
+                               need_heal, data_versions);
17b94a
 out:
17b94a
     return ret;
17b94a
 }
17b94a
@@ -3033,7 +3029,7 @@ ec_need_entry_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies,
17b94a
     }
17b94a
 
17b94a
     ret = _need_heal_calculate(ec, dirty, sources, self_locked, lock_count,
17b94a
-                               need_heal);
17b94a
+                               need_heal, data_versions);
17b94a
 out:
17b94a
     return ret;
17b94a
 }
17b94a
@@ -3131,10 +3127,6 @@ ec_heal_inspect(call_frame_t *frame, ec_t *ec, inode_t *inode,
17b94a
 need_heal:
17b94a
     ret = ec_need_heal(ec, inode, replies, lock_count, self_locked, thorough,
17b94a
                        need_heal);
17b94a
-
17b94a
-    if (!self_locked && *need_heal == EC_HEAL_MUST) {
17b94a
-        *need_heal = EC_HEAL_MAYBE;
17b94a
-    }
17b94a
 out:
17b94a
     cluster_replies_wipe(replies, ec->nodes);
17b94a
     loc_wipe(&loc;;
17b94a
@@ -3220,7 +3212,7 @@ ec_get_heal_info(xlator_t *this, loc_t *entry_loc, dict_t **dict_rsp)
17b94a
 
17b94a
     ret = ec_heal_inspect(frame, ec, loc.inode, up_subvols, _gf_false,
17b94a
                           _gf_false, &need_heal);
17b94a
-    if (ret == ec->nodes && need_heal == EC_HEAL_NONEED) {
17b94a
+    if (ret == ec->nodes && need_heal != EC_HEAL_MAYBE) {
17b94a
         goto set_heal;
17b94a
     }
17b94a
     need_heal = EC_HEAL_NONEED;
17b94a
-- 
17b94a
1.8.3.1
17b94a