diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2013-08-27 13:42:41 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-08-28 17:42:59 -0700 |
commit | db0b19a5420d417cf4da70bf886b53619e17a739 (patch) | |
tree | 07dcdd05912fecc438a13c2d3e634768ebd157e3 /xlators/cluster/afr | |
parent | b880b6b2908ad4e4afc8e26613bd0db8f0b28750 (diff) |
cluster/afr: Add special handling for failure postops
Idea is to not leave the file in FOOL-FOOL scenario in case on
all the bricks data transaction failed with EDQUOT to avoid
increasing un-necessary load of self-heals in the system.
For directory transactions don't leave pending changelog in case
the failures are seen on all the subvolumes.
Change-Id: I38a5561d1d581a78347a76a4a509514e4a0c3fb7
BUG: 969461
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/5709
Reviewed-by: Anand Avati <avati@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators/cluster/afr')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 8 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-write.c | 21 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.c | 12 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 56 |
4 files changed, 71 insertions, 26 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 691c1d4d7b3..840025e793c 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -2908,8 +2908,10 @@ afr_fallocate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->read_child_returned = _gf_true; } - if (afr_fop_failed (op_ret, op_errno)) + if (afr_fop_failed (op_ret, op_errno)) { afr_transaction_fop_failed (frame, this, child_index); + local->child_errno[child_index] = op_errno; + } if (op_ret != -1) { if (local->success_count == 0) { @@ -3152,8 +3154,10 @@ afr_discard_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, local->read_child_returned = _gf_true; } - if (afr_fop_failed (op_ret, op_errno)) + if (afr_fop_failed (op_ret, op_errno)) { afr_transaction_fop_failed (frame, this, child_index); + local->child_errno[child_index] = op_errno; + } if (op_ret != -1) { if (local->success_count == 0) { diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c index 5a22696ce39..1943b719bb5 100644 --- a/xlators/cluster/afr/src/afr-dir-write.c +++ b/xlators/cluster/afr/src/afr-dir-write.c @@ -235,26 +235,6 @@ out: } void -afr_dir_fop_handle_all_fop_failures (call_frame_t *frame) -{ - xlator_t *this = NULL; - afr_local_t *local = NULL; - afr_private_t *priv = NULL; - - this = frame->this; - local = frame->local; - priv = this->private; - - if (local->op_ret >= 0) - goto out; - - __mark_all_success (local->pending, priv->child_count, - local->transaction.type); -out: - return; -} - -void afr_dir_fop_done (call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; @@ -273,7 +253,6 @@ afr_dir_fop_done (call_frame_t *frame, xlator_t *this) done: local->transaction.unwind (frame, this); afr_dir_fop_mark_entry_pending_changelog (frame, this); - afr_dir_fop_handle_all_fop_failures (frame); local->transaction.resume (frame, this); } diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index 27107439606..18ea323f176 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -157,8 +157,10 @@ afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; - if (afr_fop_failed (op_ret, op_errno)) + if (afr_fop_failed (op_ret, op_errno)) { afr_transaction_fop_failed (frame, this, child_index); + local->child_errno[child_index] = op_errno; + } /* stage the best case return value for unwind */ if ((local->success_count == 0) || (op_ret > local->op_ret)) { @@ -599,8 +601,10 @@ afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->read_child_returned = _gf_true; } - if (afr_fop_failed (op_ret, op_errno) && op_errno != EFBIG) + if (afr_fop_failed (op_ret, op_errno) && op_errno != EFBIG) { afr_transaction_fop_failed (frame, this, child_index); + local->child_errno[child_index] = op_errno; + } if (op_ret != -1) { if (local->success_count == 0) { @@ -798,8 +802,10 @@ afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->read_child_returned = _gf_true; } - if (afr_fop_failed (op_ret, op_errno)) + if (afr_fop_failed (op_ret, op_errno)) { afr_transaction_fop_failed (frame, this, child_index); + local->child_errno[child_index] = op_errno; + } if (op_ret != -1) { if (local->success_count == 0) { diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 35547a2315a..0b91f466e11 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -586,6 +586,59 @@ afr_txn_nothing_failed (call_frame_t *frame, xlator_t *this) return _gf_true; } +static void +afr_dir_fop_handle_all_fop_failures (call_frame_t *frame) +{ + xlator_t *this = NULL; + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + + this = frame->this; + local = frame->local; + priv = this->private; + + if ((local->transaction.type != AFR_ENTRY_TRANSACTION) && + (local->transaction.type != AFR_ENTRY_RENAME_TRANSACTION)) + return; + + if (local->op_ret >= 0) + goto out; + + __mark_all_success (local->pending, priv->child_count, + local->transaction.type); +out: + return; +} + +static void +afr_data_handle_quota_errors (call_frame_t *frame, xlator_t *this) +{ + int i = 0; + afr_private_t *priv = NULL; + afr_local_t *local = NULL; + gf_boolean_t all_quota_failures = _gf_false; + + local = frame->local; + priv = this->private; + if (local->transaction.type != AFR_DATA_TRANSACTION) + return; + /* + * Idea is to not leave the file in FOOL-FOOL scenario in case on + * all the bricks data transaction failed with EDQUOT to avoid + * increasing un-necessary load of self-heals in the system. + */ + all_quota_failures = _gf_true; + for (i = 0; i < priv->child_count; i++) { + if (local->transaction.pre_op[i] && + (local->child_errno[i] != EDQUOT)) { + all_quota_failures = _gf_false; + break; + } + } + if (all_quota_failures) + __mark_all_success (local->pending, priv->child_count, + local->transaction.type); +} int afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this) @@ -608,6 +661,9 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this) local->transaction.pre_op, local->transaction.type); + afr_data_handle_quota_errors (frame, this); + afr_dir_fop_handle_all_fop_failures (frame); + if (local->fd) afr_transaction_rm_stale_children (frame, this, local->fd->inode, |