Blob Blame History Raw
From c58fcc9cfff6d7858febcc53847cda7624c2d982 Mon Sep 17 00:00:00 2001
From: Ashish Pandey <aspandey@redhat.com>
Date: Thu, 22 Jun 2017 17:06:40 +0530
Subject: [PATCH 532/539] ec: Increase notification in all the cases

Problem:
"gluster v heal <volname> info" is taking
long time to respond when a brick is down.

RCA:
Heal info command does virtual mount.
EC wait for 10 seconds, before sending UP call to upper xlator,
to get notification (DOWN or UP) from all the bricks.

Currently, we are increasing ec->xl_notify_count based on
the current status of the brick. So, if a DOWN event notification
has come and brick is already down, we are not increasing
ec->xl_notify_count in ec_handle_down.

Solution:
Handle DOWN even as notification irrespective of what
is the current status of brick.

>Change-Id: I0acac0db7ec7622d4c0584692e88ad52f45a910f
>BUG: 1464091
>Signed-off-by: Ashish Pandey <aspandey@redhat.com>
>Reviewed-on: https://review.gluster.org/17606
>Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
>Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
>Smoke: Gluster Build System <jenkins@build.gluster.org>
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
>Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
>Signed-off-by: Ashish Pandey <aspandey@redhat.com>

Change-Id: I0acac0db7ec7622d4c0584692e88ad52f45a910f
BUG: 1463108
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/110286
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
---
 xlators/cluster/ec/src/ec.c | 51 ++++++++++++++++++---------------------------
 1 file changed, 20 insertions(+), 31 deletions(-)

diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
index bad5578..f1aeea7 100644
--- a/xlators/cluster/ec/src/ec.c
+++ b/xlators/cluster/ec/src/ec.c
@@ -401,35 +401,6 @@ ec_launch_notify_timer (xlator_t *this, ec_t *ec)
         }
 }
 
-void
-ec_handle_up (xlator_t *this, ec_t *ec, int32_t idx)
-{
-        if (((ec->xl_up >> idx) & 1) == 0) { /* Duplicate event */
-                if (((ec->xl_notify >> idx) & 1) == 0) {
-                        ec->xl_notify |= 1ULL << idx;
-                        ec->xl_notify_count++;
-                }
-                ec->xl_up |= 1ULL << idx;
-                ec->xl_up_count++;
-        }
-}
-
-void
-ec_handle_down (xlator_t *this, ec_t *ec, int32_t idx)
-{
-        if (((ec->xl_up >> idx) & 1) != 0) { /* Duplicate event */
-                gf_msg_debug (this->name, 0, "Child %d is DOWN", idx);
-
-                if (((ec->xl_notify >> idx) & 1) == 0) {
-                        ec->xl_notify |= 1ULL << idx;
-                        ec->xl_notify_count++;
-                }
-
-                ec->xl_up ^= 1ULL << idx;
-                ec->xl_up_count--;
-        }
-}
-
 gf_boolean_t
 ec_disable_delays(ec_t *ec)
 {
@@ -446,6 +417,22 @@ ec_pending_fops_completed(ec_t *ec)
         }
 }
 
+static void
+ec_set_up_state(ec_t *ec, uintptr_t index_mask, uintptr_t new_state)
+{
+        uintptr_t current_state = 0;
+
+        if ((ec->xl_notify & index_mask) == 0) {
+                ec->xl_notify |= index_mask;
+                ec->xl_notify_count++;
+        }
+        current_state = ec->xl_up & index_mask;
+        if (current_state != new_state) {
+                ec->xl_up ^= index_mask;
+                ec->xl_up_count += (current_state ? -1 : 1);
+        }
+}
+
 int32_t
 ec_notify (xlator_t *this, int32_t event, void *data, void *data2)
 {
@@ -459,6 +446,7 @@ ec_notify (xlator_t *this, int32_t event, void *data, void *data2)
         int32_t           orig_event = event;
         struct gf_upcall *up_data   = NULL;
         struct gf_upcall_cache_invalidation *up_ci = NULL;
+        uintptr_t mask = 0;
 
         gf_msg_trace (this->name, 0, "NOTIFY(%d): %p, %p",
                 event, data, data2);
@@ -510,10 +498,11 @@ ec_notify (xlator_t *this, int32_t event, void *data, void *data2)
         if (idx < ec->nodes) { /* CHILD_* events */
                 old_event = ec_get_event_from_state (ec);
 
+                mask = 1ULL << idx;
                 if (event == GF_EVENT_CHILD_UP) {
-                        ec_handle_up (this, ec, idx);
+                    ec_set_up_state(ec, mask, mask);
                 } else if (event == GF_EVENT_CHILD_DOWN) {
-                        ec_handle_down (this, ec, idx);
+                    ec_set_up_state(ec, mask, 0);
                 }
 
                 event = ec_get_event_from_state (ec);
-- 
1.8.3.1