From 630d3d8c8466228e1764c1c0962b9db40548fffb Mon Sep 17 00:00:00 2001 From: Ashish Pandey Date: Thu, 22 Jun 2017 17:06:40 +0530 Subject: ec: Increase notification in all the cases Problem: "gluster v heal 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 Reviewed-on: https://review.gluster.org/17606 Tested-by: Pranith Kumar Karampuri Reviewed-by: Pranith Kumar Karampuri Smoke: Gluster Build System CentOS-regression: Gluster Build System Reviewed-by: Xavier Hernandez NetBSD-regression: NetBSD Build System --- xlators/cluster/ec/src/ec.c | 51 ++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) (limited to 'xlators/cluster/ec/src/ec.c') diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index 3d40b111819..c32f4ef21dd 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); -- cgit