From 2440dace036a4955ca60d833b2ae514bab679126 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Mon, 13 Jun 2016 12:26:24 +0530 Subject: cluster/dht: initialize cbk before attempting inode-link Otherwise inode-link failures in selfheal codepath will result in a crash. This regression was introduced in master as fix to 1334164. But, that patch never made into 3.7. Hence, in essence this patch is 3.7 version of fix to 1334164, minus the regression. > Change-Id: I9061629ae9d1eb1ac945af5f448d0d8b397a5022 > BUG: 1345748 > Signed-off-by: Raghavendra G > Reviewed-on: http://review.gluster.org/14707 > Reviewed-by: N Balachandran > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > Reviewed-by: Poornima G > Reviewed-by: Susant Palai > CentOS-regression: Gluster Build System > Reviewed-by: Jeff Darcy Signed-off-by: Raghavendra G Change-Id: I9061629ae9d1eb1ac945af5f448d0d8b397a6022 BUG: 1366483 Reviewed-on: http://review.gluster.org/15163 NetBSD-regression: NetBSD Build System Smoke: Gluster Build System CentOS-regression: Gluster Build System --- xlators/cluster/dht/src/dht-selfheal.c | 40 ++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index d14a7c7e714..1aff52506c5 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -2012,18 +2012,43 @@ int dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, loc_t *loc, dht_layout_t *layout) { - dht_local_t *local = NULL; - uint32_t down = 0; - uint32_t misc = 0; - int ret = 0; - xlator_t *this = NULL; - char gfid[GF_UUID_BUF_SIZE] = {0}; + dht_local_t *local = NULL; + uint32_t down = 0; + uint32_t misc = 0; + int ret = 0; + xlator_t *this = NULL; + inode_t *linked_inode = NULL, *inode = NULL; + char gfid[GF_UUID_BUF_SIZE] = {0}; + char pgfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; this = frame->this; gf_uuid_unparse(loc->gfid, gfid); + local->selfheal.dir_cbk = dir_cbk; + local->selfheal.layout = dht_layout_ref (this, layout); + + if (!__is_root_gfid (local->stbuf.ia_gfid)) { + gf_uuid_unparse(local->stbuf.ia_gfid, gfid); + gf_uuid_unparse(loc->parent->gfid, pgfid); + + linked_inode = inode_link (loc->inode, loc->parent, loc->name, + &local->stbuf); + if (!linked_inode) { + gf_msg (this->name, GF_LOG_WARNING, 0, + DHT_MSG_DIR_SELFHEAL_FAILED, + "linking inode failed (%s/%s) => %s", + pgfid, loc->name, gfid); + ret = 0; + goto sorry_no_fix; + } + + inode = loc->inode; + loc->inode = linked_inode; + inode_unref (inode); + } + dht_layout_anomalies (this, loc, layout, &local->selfheal.hole_cnt, &local->selfheal.overlaps_cnt, @@ -2033,9 +2058,6 @@ dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, down = local->selfheal.down; misc = local->selfheal.misc; - local->selfheal.dir_cbk = dir_cbk; - local->selfheal.layout = dht_layout_ref (this, layout); - if (down) { gf_msg (this->name, GF_LOG_WARNING, 0, DHT_MSG_DIR_SELFHEAL_FAILED, -- cgit