summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Pandey <aspandey@redhat.com>2017-06-22 17:06:40 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2017-07-03 12:43:49 +0000
commit1764ba4654bcdac9155e81727e1467b024e4a01b (patch)
tree520a4afcbda8168dd644595e62f6e665f77257a0
parentcf3030cf115cf9603afd1d631c20c127c811958e (diff)
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: 1465854 Signed-off-by: Ashish Pandey <aspandey@redhat.com> Reviewed-on: https://review.gluster.org/17642 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Xavier Hernandez <xhernandez@datalab.es> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
-rw-r--r--xlators/cluster/ec/src/ec.c51
1 files changed, 20 insertions, 31 deletions
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
index 3d40b11..c32f4ef 100644
--- a/xlators/cluster/ec/src/ec.c
+++ b/xlators/cluster/ec/src/ec.c
@@ -422,35 +422,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)
{
@@ -467,6 +438,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)
{
@@ -480,6 +467,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);
@@ -531,10 +519,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);