From c78998c39f0857ea7aacba360632c148afc54a55 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Thu, 22 Jan 2015 13:53:47 +0530 Subject: cluster/afr: When parent and entry read subvols are different, set entry->inode to NULL That way a lookup would be forced on the entry, and its attributes will always be selected from its read subvol. Change-Id: Iaba25e2cd5f83e983fc8b1a1f48da3850808e6b8 BUG: 1179169 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/9477 Reviewed-by: Pranith Kumar Karampuri Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/cluster/afr/src/afr-common.c | 56 +++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'xlators/cluster/afr/src/afr-common.c') diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 533a7b5d5a1..04e4ca315f2 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1219,6 +1219,50 @@ afr_xattrs_are_equal (dict_t *dict1, dict_t *dict2) return _gf_true; } +static int +afr_get_parent_read_subvol (xlator_t *this, inode_t *parent, + struct afr_reply *replies, unsigned char *readable) +{ + int i = 0; + int par_read_subvol = -1; + int par_read_subvol_iter = -1; + afr_private_t *priv = NULL; + + priv = this->private; + + if (parent) + par_read_subvol = afr_data_subvol_get (parent, this, 0, 0); + + for (i = 0; i < priv->child_count; i++) { + if (!replies[i].valid) + continue; + + if (replies[i].op_ret < 0) + continue; + + if (par_read_subvol_iter == -1) { + par_read_subvol_iter = i; + continue; + } + + if ((i != par_read_subvol) && readable[i]) + par_read_subvol_iter = i; + + if (i == par_read_subvol) + par_read_subvol_iter = i; + } + /* At the end of the for-loop, the only reason why @par_read_subvol_iter + * could be -1 is when this LOOKUP has failed on all sub-volumes. + * So it is okay to send an arbitrary subvolume (0 in this case) + * as parent read subvol. + */ + if (par_read_subvol_iter == -1) + par_read_subvol_iter = 0; + + return par_read_subvol_iter; + +} + static void afr_lookup_done (call_frame_t *frame, xlator_t *this) { @@ -1227,23 +1271,25 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) int i = -1; int op_errno = 0; int read_subvol = 0; + int par_read_subvol = 0; unsigned char *readable = NULL; int event = 0; struct afr_reply *replies = NULL; uuid_t read_gfid = {0, }; gf_boolean_t locked_entry = _gf_false; gf_boolean_t can_interpret = _gf_true; + inode_t *parent = NULL; priv = this->private; local = frame->local; replies = local->replies; + parent = local->loc.parent; locked_entry = afr_is_entry_possibly_under_txn (local, this); readable = alloca0 (priv->child_count); - afr_inode_read_subvol_get (local->loc.parent, this, readable, - NULL, &event); + afr_inode_read_subvol_get (parent, this, readable, NULL, &event); /* First, check if we have a gfid-change from somewhere, If so, propagate that so that a fresh lookup can be @@ -1269,7 +1315,6 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) "underway" in creation */ local->op_ret = -1; local->op_errno = ENOENT; - read_subvol = i; goto unwind; } @@ -1347,10 +1392,13 @@ unwind: if (read_subvol == -1) read_subvol = 0; + par_read_subvol = afr_get_parent_read_subvol (this, parent, replies, + readable); + AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, local->inode, &local->replies[read_subvol].poststat, local->replies[read_subvol].xdata, - &local->replies[read_subvol].postparent); + &local->replies[par_read_subvol].postparent); } /* -- cgit