summaryrefslogtreecommitdiffstats
path: root/xlators/cluster
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2013-08-27 13:42:41 +0530
committerAnand Avati <avati@redhat.com>2013-08-28 17:42:59 -0700
commitdb0b19a5420d417cf4da70bf886b53619e17a739 (patch)
tree07dcdd05912fecc438a13c2d3e634768ebd157e3 /xlators/cluster
parentb880b6b2908ad4e4afc8e26613bd0db8f0b28750 (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')
-rw-r--r--xlators/cluster/afr/src/afr-common.c8
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c21
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c12
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c56
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,