diff options
author | Ravishankar N <ravishankar@redhat.com> | 2015-09-01 15:54:39 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2015-09-02 03:18:54 -0700 |
commit | 78e89fb0a70a053e85bba0f68ff4e8841818dd54 (patch) | |
tree | 887a0afaebdc0ebfe20eaf1fd9c8d3004cf80a1a /xlators/cluster | |
parent | d46d571d86c86bd387de323522cfcb8a013f28ad (diff) |
afr: Unset dirty xattr after setting pending xattr during post-op
In AFR transaction, in the pre-op, the dirty xattr is set. In the
post-op, if the transaction fails on one of the bricks, then on the
healthy brick, the dirty xattr is unset and then the pending xattr (for
the brick that went down) is set in that order. If the brick crashes
after unsetting the dirty xattr, we have lost information about a
pending heal. Hence we need to reverse the order, i.e. set pending xattr
first followed by unsetting the dirty.
Change-Id: I0b8a872cb4579a1bad602f70c76f09691bd582b2
BUG: 1258801
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: http://review.gluster.org/12078
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Reviewed-by: Anuradha Talur <atalur@redhat.com>
Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index d773b5ace7a..915b68ef07d 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -731,27 +731,27 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this) goto out; } - if (need_undirty) - local->dirty[idx] = hton32(-1); - else - local->dirty[idx] = hton32(0); + for (i = 0; i < priv->child_count; i++) { + if (local->transaction.failed_subvols[i]) + local->pending[i][idx] = hton32(1); + } - ret = dict_set_static_bin (xattr, AFR_DIRTY, local->dirty, - sizeof(int) * AFR_NUM_CHANGE_LOGS); - if (ret) { + ret = afr_set_pending_dict (priv, xattr, local->pending); + if (ret < 0) { local->op_ret = -1; local->op_errno = ENOMEM; afr_changelog_post_op_done (frame, this); goto out; } - for (i = 0; i < priv->child_count; i++) { - if (local->transaction.failed_subvols[i]) - local->pending[i][idx] = hton32(1); - } + if (need_undirty) + local->dirty[idx] = hton32(-1); + else + local->dirty[idx] = hton32(0); - ret = afr_set_pending_dict (priv, xattr, local->pending); - if (ret < 0) { + ret = dict_set_static_bin (xattr, AFR_DIRTY, local->dirty, + sizeof(int) * AFR_NUM_CHANGE_LOGS); + if (ret) { local->op_ret = -1; local->op_errno = ENOMEM; afr_changelog_post_op_done (frame, this); |