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