diff options
author | Pranith Kumar K <pranithk@gluster.com> | 2011-08-19 15:56:49 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2011-08-19 23:18:53 -0700 |
commit | d9c6513289ca33204cdc110112ff8e45cbc8970a (patch) | |
tree | d68097996f3dd9b0882343be1c5d0b7bf6758315 /xlators/cluster/afr/src/afr-transaction.c | |
parent | 5e89fda5180e66b1757bc620dfdb5701ce4d43f1 (diff) |
cluster/afr: Update fresh_children in lookup if no other ops in progress
If write/truncate fails we should remove the child that failed the fop
from the fresh children. The previous code assumes that the children
that succeeded the fop are fresh children, which is wrong. Fixed that
in this patch.
Change-Id: I1e6e21e20faea00516a0fdd2e95f2d7e9cf9076d
BUG: 3411
Reviewed-on: http://review.gluster.com/263
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'xlators/cluster/afr/src/afr-transaction.c')
-rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 1fb0781d8b7..fc030433b69 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -404,53 +404,67 @@ afr_changelog_post_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this, void -afr_update_read_child (call_frame_t *frame, xlator_t *this, inode_t *inode, - afr_transaction_type type) +afr_transaction_rm_stale_children (call_frame_t *frame, xlator_t *this, + inode_t *inode, afr_transaction_type type) { - int curr_read_child = -1; - int new_read_child = -1; + int i = -1; + int count = 0; + int read_child = -1; afr_private_t *priv = NULL; afr_local_t *local = NULL; int **pending = NULL; int idx = 0; + int32_t *stale_children = NULL; int32_t *fresh_children = NULL; - size_t success_count = 0; + gf_boolean_t rm_stale_children = _gf_false; idx = afr_index_for_transaction_type (type); priv = this->private; local = frame->local; - curr_read_child = afr_inode_get_read_ctx (this, inode, NULL); pending = local->pending; - GF_ASSERT (curr_read_child >= 0); - - if (pending[curr_read_child][idx] != 0) + stale_children = afr_children_create (priv->child_count); + if (!stale_children) goto out; - fresh_children = afr_fresh_children_create (priv->child_count); - if (!fresh_children) - goto out; + fresh_children = local->fresh_children; + read_child = afr_inode_get_read_ctx (this, inode, fresh_children); - for (new_read_child = 0; new_read_child < priv->child_count; - new_read_child++) { + GF_ASSERT (read_child >= 0); - if (!priv->child_up[new_read_child]) - /* child is down */ - continue; + if (pending[read_child][idx] == 0) + read_child = -1; - if (pending[new_read_child][idx] == 0) - /* op just failed */ + for (i = 0; i < priv->child_count; i++) { + if (!afr_is_child_present (fresh_children, + priv->child_count, i)) continue; - fresh_children[success_count] = new_read_child; - success_count++; + if ((!priv->child_up[i]) || (pending[i][idx] == 0)) { + /* child is down or op failed on it */ + rm_stale_children = _gf_true; + afr_children_rm_child (fresh_children, i, + priv->child_count); + stale_children[count++] = i; + } + } + + if (!rm_stale_children) { + GF_ASSERT (read_child >= 0); + goto out; + } + + if (fresh_children[0] == -1) { + //All children failed. leave as-is + goto out; } - afr_inode_set_read_ctx (this, inode, fresh_children[0], - fresh_children); + if (read_child == -1) + read_child = fresh_children[0]; + afr_inode_rm_stale_children (this, inode, read_child, stale_children); out: - if (fresh_children) - GF_FREE (fresh_children); + if (stale_children) + GF_FREE (stale_children); return; } @@ -478,8 +492,9 @@ afr_changelog_post_op (call_frame_t *frame, xlator_t *this) local->child_up, local->transaction.type); if (local->fd) - afr_update_read_child (frame, this, local->fd->inode, - local->transaction.type); + afr_transaction_rm_stale_children (frame, this, + local->fd->inode, + local->transaction.type); xattr = alloca (priv->child_count * sizeof (*xattr)); memset (xattr, 0, (priv->child_count * sizeof (*xattr))); |