From 9e4135c46455da7fe67c5ef61e098428cd238e95 Mon Sep 17 00:00:00 2001 From: Susant Palai Date: Mon, 8 Aug 2016 17:05:10 +0530 Subject: dht: udpate stbuf from servers those have layout Problem: For healing of uid/gid we check if local->stbuf.ia_ctime is lesser than stbuf->ia_ctime (received from brick). If yes then uid/gid is updated to local->prebuf(source of healing). But we merge local->stbuf also form the newly added brick. So if we receive response from the newly added brick first and update the local->stbuf, then local->prebuf will remain empty since the newly added brick will have the latest ctime among all servers. And this can result in healing wrong uid/gids to the rest of servers. Hence, we should update local->stbuf from servers with a layout which will ignore merging stbufs from newly added bricks. > Reviewed-on: http://review.gluster.org/15126 > CentOS-regression: Gluster Build System > NetBSD-regression: NetBSD Build System > Smoke: Gluster Build System > Reviewed-by: Raghavendra G (cherry picked from commit 36af81ac7cb2d459f9bfc0c436f0038a68f85235) Change-Id: If4b64f75a0ea669abdbe9f5a3d1d18ff19374c2f BUG: 1375096 Signed-off-by: Susant Palai Reviewed-on: http://review.gluster.org/15464 NetBSD-regression: NetBSD Build System Smoke: Gluster Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra G --- xlators/cluster/dht/src/dht-common.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 776dba0ee94..90db73f1f72 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1098,9 +1098,22 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } } - dht_iatt_merge (this, &local->stbuf, stbuf, prev->this); - dht_iatt_merge (this, &local->postparent, postparent, - prev->this); + + /* Update stbuf from the servers where layout is present. This + * is an indication that the server is not a newly added brick. + * Merging stbuf from newly added brick may result in the added + * brick being the source of heal for uid/gid */ + if (!is_dir || (is_dir && + dht_dir_has_layout (xattr, conf->xattr_name) >= 0) + || conf->subvolume_cnt == 1) { + + dht_iatt_merge (this, &local->stbuf, stbuf, prev->this); + dht_iatt_merge (this, &local->postparent, postparent, + prev->this); + } else { + /* copy the gfid anyway */ + gf_uuid_copy (local->stbuf.ia_gfid, stbuf->ia_gfid); + } local->op_ret = 0; @@ -1195,6 +1208,19 @@ cont: DHT_STRIP_PHASE1_FLAGS (&local->stbuf); dht_set_fixed_dir_stat (&local->postparent); + + /* local->stbuf is udpated only from subvols which have a layout + * The reason is to avoid choosing attr heal source from newly + * added bricks. In case e.g we have only one subvol and for + * some reason layout is not present on it, then local->stbuf + * will be EINVAL. This is an indication that the subvols + * active in the cluster do not have layouts on disk. + * Unwind with ESTALE to trigger a fresh lookup */ + if (is_dir && local->stbuf.ia_type == IA_INVAL) { + local->op_ret = -1; + local->op_errno = ESTALE; + } + DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); -- cgit