|
|
a3470f |
From 46a4c05ce998a72a006f79ddac4e1ad2384e66bb Mon Sep 17 00:00:00 2001
|
|
|
a3470f |
From: Pranith Kumar K <pkarampu@redhat.com>
|
|
|
a3470f |
Date: Mon, 4 Sep 2017 16:57:25 +0530
|
|
|
a3470f |
Subject: [PATCH 094/128] cluster/afr: Fail open on split-brain
|
|
|
a3470f |
|
|
|
a3470f |
Problem:
|
|
|
a3470f |
Append on a file with split-brain succeeds. Open is intercepted by open-behind,
|
|
|
a3470f |
when write comes on the file, open-behind does open+write. Open succeeds
|
|
|
a3470f |
because afr doesn't fail it. Then write succeeds because write-behind
|
|
|
a3470f |
intercepts it. Flush is also intercepted by write-behind, so the application
|
|
|
a3470f |
never gets to know that the write failed.
|
|
|
a3470f |
|
|
|
a3470f |
Fix:
|
|
|
a3470f |
Fail open on split-brain, so that when open-behind does open+write open fails
|
|
|
a3470f |
which leads to write failure. Application will know about this failure.
|
|
|
a3470f |
|
|
|
a3470f |
> Change-Id: I4bff1c747c97bb2925d6987f4ced5f1ce75dbc15
|
|
|
a3470f |
> BUG: 1294051
|
|
|
a3470f |
> Upstream-patch: https://review.gluster.org/13075
|
|
|
a3470f |
> Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
|
|
|
a3470f |
|
|
|
a3470f |
Change-Id: I4bff1c747c97bb2925d6987f4ced5f1ce75dbc15
|
|
|
a3470f |
BUG: 1277924
|
|
|
a3470f |
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
|
|
|
a3470f |
Reviewed-on: https://code.engineering.redhat.com/gerrit/124882
|
|
|
a3470f |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
a3470f |
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
|
|
|
a3470f |
---
|
|
|
a3470f |
tests/basic/afr/split-brain-open.t | 38 ++++++++++
|
|
|
a3470f |
tests/bugs/nfs/bug-974972.t | 1 +
|
|
|
a3470f |
xlators/cluster/afr/src/afr-common.c | 77 ++++++++++++++++++--
|
|
|
a3470f |
xlators/cluster/afr/src/afr-inode-write.c | 2 +-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-open.c | 93 +++++++++++++++++-------
|
|
|
a3470f |
xlators/cluster/afr/src/afr-self-heal-common.c | 11 ++-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-self-heal-data.c | 58 ++++++++++++++-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-self-heal-metadata.c | 4 +-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-self-heal-name.c | 2 +-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-self-heal.h | 2 +-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-self-heald.c | 6 +-
|
|
|
a3470f |
xlators/cluster/afr/src/afr-transaction.c | 43 +----------
|
|
|
a3470f |
xlators/cluster/afr/src/afr.h | 6 +-
|
|
|
a3470f |
13 files changed, 248 insertions(+), 95 deletions(-)
|
|
|
a3470f |
create mode 100644 tests/basic/afr/split-brain-open.t
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/tests/basic/afr/split-brain-open.t b/tests/basic/afr/split-brain-open.t
|
|
|
a3470f |
new file mode 100644
|
|
|
a3470f |
index 0000000..9b2f285
|
|
|
a3470f |
--- /dev/null
|
|
|
a3470f |
+++ b/tests/basic/afr/split-brain-open.t
|
|
|
a3470f |
@@ -0,0 +1,38 @@
|
|
|
a3470f |
+#!/bin/bash
|
|
|
a3470f |
+. $(dirname $0)/../../include.rc
|
|
|
a3470f |
+. $(dirname $0)/../../volume.rc
|
|
|
a3470f |
+cleanup;
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST glusterd
|
|
|
a3470f |
+TEST pidof glusterd
|
|
|
a3470f |
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1}
|
|
|
a3470f |
+TEST $CLI volume start $V0
|
|
|
a3470f |
+
|
|
|
a3470f |
+#Disable self-heal-daemon
|
|
|
a3470f |
+TEST $CLI volume heal $V0 disable
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0;
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST touch $M0/data-split-brain.txt
|
|
|
a3470f |
+
|
|
|
a3470f |
+#Create data split-brain
|
|
|
a3470f |
+TEST kill_brick $V0 $H0 $B0/${V0}0
|
|
|
a3470f |
+
|
|
|
a3470f |
+`echo "brick1_alive" > $M0/data-split-brain.txt`
|
|
|
a3470f |
+TEST [ $? == 0 ];
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST $CLI volume start $V0 force
|
|
|
a3470f |
+TEST kill_brick $V0 $H0 $B0/${V0}1
|
|
|
a3470f |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
a3470f |
+
|
|
|
a3470f |
+`echo "brick0_alive" > $M0/data-split-brain.txt`
|
|
|
a3470f |
+TEST [ $? == 0 ];
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST $CLI volume start $V0 force
|
|
|
a3470f |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
a3470f |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
|
|
|
a3470f |
+
|
|
|
a3470f |
+echo "all-alive" >> $M0/data-split-brain.txt
|
|
|
a3470f |
+TEST [ $? != 0 ];
|
|
|
a3470f |
+
|
|
|
a3470f |
+cleanup;
|
|
|
a3470f |
diff --git a/tests/bugs/nfs/bug-974972.t b/tests/bugs/nfs/bug-974972.t
|
|
|
a3470f |
index d05e7df..7047825 100755
|
|
|
a3470f |
--- a/tests/bugs/nfs/bug-974972.t
|
|
|
a3470f |
+++ b/tests/bugs/nfs/bug-974972.t
|
|
|
a3470f |
@@ -11,6 +11,7 @@ TEST glusterd
|
|
|
a3470f |
TEST pidof glusterd
|
|
|
a3470f |
TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1}
|
|
|
a3470f |
TEST $CLI volume set $V0 self-heal-daemon off
|
|
|
a3470f |
+TEST $CLI volume set $V0 cluster.eager-lock off
|
|
|
a3470f |
TEST $CLI volume set $V0 nfs.disable false
|
|
|
a3470f |
TEST $CLI volume start $V0
|
|
|
a3470f |
EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available;
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
|
|
|
a3470f |
index a8ba5a0..692f198 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-common.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-common.c
|
|
|
a3470f |
@@ -254,8 +254,9 @@ __afr_set_in_flight_sb_status (xlator_t *this, afr_local_t *local,
|
|
|
a3470f |
local->transaction.in_flight_sb = _gf_true;
|
|
|
a3470f |
metadatamap |= (1 << index);
|
|
|
a3470f |
}
|
|
|
a3470f |
- if (metadatamap_old != metadatamap)
|
|
|
a3470f |
+ if (metadatamap_old != metadatamap) {
|
|
|
a3470f |
event = 0;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
break;
|
|
|
a3470f |
|
|
|
a3470f |
case AFR_DATA_TRANSACTION:
|
|
|
a3470f |
@@ -283,19 +284,71 @@ __afr_set_in_flight_sb_status (xlator_t *this, afr_local_t *local,
|
|
|
a3470f |
return ret;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
-int
|
|
|
a3470f |
-afr_set_in_flight_sb_status (xlator_t *this, afr_local_t *local, inode_t *inode)
|
|
|
a3470f |
+gf_boolean_t
|
|
|
a3470f |
+afr_is_symmetric_error (call_frame_t *frame, xlator_t *this)
|
|
|
a3470f |
{
|
|
|
a3470f |
- int ret = -1;
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
afr_private_t *priv = NULL;
|
|
|
a3470f |
+ int op_errno = 0;
|
|
|
a3470f |
+ int i_errno = 0;
|
|
|
a3470f |
+ gf_boolean_t matching_errors = _gf_true;
|
|
|
a3470f |
+ int i = 0;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ priv = this->private;
|
|
|
a3470f |
+ local = frame->local;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ for (i = 0; i < priv->child_count; i++) {
|
|
|
a3470f |
+ if (!local->replies[i].valid)
|
|
|
a3470f |
+ continue;
|
|
|
a3470f |
+ if (local->replies[i].op_ret != -1) {
|
|
|
a3470f |
+ /* Operation succeeded on at least one subvol,
|
|
|
a3470f |
+ so it is not a failed-everywhere situation.
|
|
|
a3470f |
+ */
|
|
|
a3470f |
+ matching_errors = _gf_false;
|
|
|
a3470f |
+ break;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ i_errno = local->replies[i].op_errno;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if (i_errno == ENOTCONN) {
|
|
|
a3470f |
+ /* ENOTCONN is not a symmetric error. We do not
|
|
|
a3470f |
+ know if the operation was performed on the
|
|
|
a3470f |
+ backend or not.
|
|
|
a3470f |
+ */
|
|
|
a3470f |
+ matching_errors = _gf_false;
|
|
|
a3470f |
+ break;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if (!op_errno) {
|
|
|
a3470f |
+ op_errno = i_errno;
|
|
|
a3470f |
+ } else if (op_errno != i_errno) {
|
|
|
a3470f |
+ /* Mismatching op_errno's */
|
|
|
a3470f |
+ matching_errors = _gf_false;
|
|
|
a3470f |
+ break;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+
|
|
|
a3470f |
+ return matching_errors;
|
|
|
a3470f |
+}
|
|
|
a3470f |
+
|
|
|
a3470f |
+int
|
|
|
a3470f |
+afr_set_in_flight_sb_status (xlator_t *this, call_frame_t *frame,
|
|
|
a3470f |
+ inode_t *inode)
|
|
|
a3470f |
+{
|
|
|
a3470f |
+ int ret = -1;
|
|
|
a3470f |
+ afr_private_t *priv = NULL;
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
|
|
|
a3470f |
priv = this->private;
|
|
|
a3470f |
+ local = frame->local;
|
|
|
a3470f |
|
|
|
a3470f |
/* If this transaction saw no failures, then exit. */
|
|
|
a3470f |
if (AFR_COUNT (local->transaction.failed_subvols,
|
|
|
a3470f |
priv->child_count) == 0)
|
|
|
a3470f |
return 0;
|
|
|
a3470f |
|
|
|
a3470f |
+ if (afr_is_symmetric_error (frame, this))
|
|
|
a3470f |
+ return 0;
|
|
|
a3470f |
+
|
|
|
a3470f |
LOCK (&inode->lock);
|
|
|
a3470f |
{
|
|
|
a3470f |
ret = __afr_set_in_flight_sb_status (this, local, inode);
|
|
|
a3470f |
@@ -548,8 +601,9 @@ afr_inode_get_readable (call_frame_t *frame, inode_t *inode, xlator_t *this,
|
|
|
a3470f |
}
|
|
|
a3470f |
} else {
|
|
|
a3470f |
/* For files, abort in case of data/metadata split-brain. */
|
|
|
a3470f |
- if (!data_count || !metadata_count)
|
|
|
a3470f |
+ if (!data_count || !metadata_count) {
|
|
|
a3470f |
return -EIO;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
if (type == AFR_METADATA_TRANSACTION && readable)
|
|
|
a3470f |
@@ -1958,6 +2012,11 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
|
|
|
a3470f |
GF_FREE (local->cont.opendir.checksum);
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
+ { /* open */
|
|
|
a3470f |
+ if (local->cont.open.fd)
|
|
|
a3470f |
+ fd_unref (local->cont.open.fd);
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+
|
|
|
a3470f |
{ /* readdirp */
|
|
|
a3470f |
if (local->cont.readdir.dict)
|
|
|
a3470f |
dict_unref (local->cont.readdir.dict);
|
|
|
a3470f |
@@ -2535,9 +2594,11 @@ afr_lookup_metadata_heal_check (call_frame_t *frame, xlator_t *this)
|
|
|
a3470f |
if (!afr_can_start_metadata_self_heal (frame, this))
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
|
|
|
a3470f |
- heal = afr_frame_create (this);
|
|
|
a3470f |
- if (!heal)
|
|
|
a3470f |
+ heal = afr_frame_create (this, &ret;;
|
|
|
a3470f |
+ if (!heal) {
|
|
|
a3470f |
+ ret = -ret;
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
|
|
|
a3470f |
ret = synctask_new (this->ctx->env, afr_lookup_sh_metadata_wrap,
|
|
|
a3470f |
afr_refresh_selfheal_done, heal, frame);
|
|
|
a3470f |
@@ -2630,7 +2691,7 @@ afr_lookup_entry_heal (call_frame_t *frame, xlator_t *this)
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
if (need_heal) {
|
|
|
a3470f |
- heal = afr_frame_create (this);
|
|
|
a3470f |
+ heal = afr_frame_create (this, NULL);
|
|
|
a3470f |
if (!heal)
|
|
|
a3470f |
goto metadata_heal;
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
|
|
|
a3470f |
index 6651e92..97397f9 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-inode-write.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-inode-write.c
|
|
|
a3470f |
@@ -131,7 +131,7 @@ __afr_inode_write_finalize (call_frame_t *frame, xlator_t *this)
|
|
|
a3470f |
}
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
- afr_set_in_flight_sb_status (this, local, local->inode);
|
|
|
a3470f |
+ afr_set_in_flight_sb_status (this, frame, local->inode);
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-open.c b/xlators/cluster/afr/src/afr-open.c
|
|
|
a3470f |
index 7a62835..6c625cc 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-open.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-open.c
|
|
|
a3470f |
@@ -66,16 +66,15 @@ afr_open_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
a3470f |
return 0;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
-
|
|
|
a3470f |
int
|
|
|
a3470f |
afr_open_cbk (call_frame_t *frame, void *cookie,
|
|
|
a3470f |
xlator_t *this, int32_t op_ret, int32_t op_errno,
|
|
|
a3470f |
fd_t *fd, dict_t *xdata)
|
|
|
a3470f |
{
|
|
|
a3470f |
- afr_local_t * local = NULL;
|
|
|
a3470f |
- int call_count = -1;
|
|
|
a3470f |
- int child_index = (long) cookie;
|
|
|
a3470f |
- afr_fd_ctx_t *fd_ctx = NULL;
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
+ int call_count = -1;
|
|
|
a3470f |
+ int child_index = (long) cookie;
|
|
|
a3470f |
+ afr_fd_ctx_t *fd_ctx = NULL;
|
|
|
a3470f |
|
|
|
a3470f |
local = frame->local;
|
|
|
a3470f |
fd_ctx = local->fd_ctx;
|
|
|
a3470f |
@@ -103,24 +102,62 @@ afr_open_cbk (call_frame_t *frame, void *cookie,
|
|
|
a3470f |
fd, 0, NULL);
|
|
|
a3470f |
} else {
|
|
|
a3470f |
AFR_STACK_UNWIND (open, frame, local->op_ret,
|
|
|
a3470f |
- local->op_errno, local->fd,
|
|
|
a3470f |
- local->xdata_rsp);
|
|
|
a3470f |
+ local->op_errno, local->cont.open.fd,
|
|
|
a3470f |
+ local->xdata_rsp);
|
|
|
a3470f |
}
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
return 0;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
+
|
|
|
a3470f |
+int
|
|
|
a3470f |
+afr_open_continue (call_frame_t *frame, xlator_t *this, int err)
|
|
|
a3470f |
+{
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
+ afr_private_t *priv = NULL;
|
|
|
a3470f |
+ int call_count = 0;
|
|
|
a3470f |
+ int i = 0;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ local = frame->local;
|
|
|
a3470f |
+ priv = this->private;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if (err) {
|
|
|
a3470f |
+ AFR_STACK_UNWIND (open, frame, -1, -err, NULL, NULL);
|
|
|
a3470f |
+ } else {
|
|
|
a3470f |
+ local->call_count = AFR_COUNT (local->child_up,
|
|
|
a3470f |
+ priv->child_count);
|
|
|
a3470f |
+ call_count = local->call_count;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ for (i = 0; i < priv->child_count; i++) {
|
|
|
a3470f |
+ if (local->child_up[i]) {
|
|
|
a3470f |
+ STACK_WIND_COOKIE (frame, afr_open_cbk,
|
|
|
a3470f |
+ (void *)(long)i,
|
|
|
a3470f |
+ priv->children[i],
|
|
|
a3470f |
+ priv->children[i]->fops->open,
|
|
|
a3470f |
+ &local->loc,
|
|
|
a3470f |
+ (local->cont.open.flags & ~O_TRUNC),
|
|
|
a3470f |
+ local->cont.open.fd,
|
|
|
a3470f |
+ local->xdata_req);
|
|
|
a3470f |
+ if (!--call_count)
|
|
|
a3470f |
+ break;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ return 0;
|
|
|
a3470f |
+}
|
|
|
a3470f |
+
|
|
|
a3470f |
int
|
|
|
a3470f |
afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
|
|
|
a3470f |
fd_t *fd, dict_t *xdata)
|
|
|
a3470f |
{
|
|
|
a3470f |
- afr_private_t * priv = NULL;
|
|
|
a3470f |
- afr_local_t * local = NULL;
|
|
|
a3470f |
- int i = 0;
|
|
|
a3470f |
- int32_t call_count = 0;
|
|
|
a3470f |
- int32_t op_errno = 0;
|
|
|
a3470f |
- afr_fd_ctx_t *fd_ctx = NULL;
|
|
|
a3470f |
+ afr_private_t *priv = NULL;
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
+ int spb_choice = 0;
|
|
|
a3470f |
+ int event_generation = 0;
|
|
|
a3470f |
+ int ret = 0;
|
|
|
a3470f |
+ int32_t op_errno = 0;
|
|
|
a3470f |
+ afr_fd_ctx_t *fd_ctx = NULL;
|
|
|
a3470f |
|
|
|
a3470f |
//We can't let truncation to happen outside transaction.
|
|
|
a3470f |
|
|
|
a3470f |
@@ -140,23 +177,27 @@ afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
|
|
|
a3470f |
if (!afr_is_consistent_io_possible (local, priv, &op_errno))
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
|
|
|
a3470f |
- local->fd = fd_ref (fd);
|
|
|
a3470f |
+ local->inode = inode_ref (loc->inode);
|
|
|
a3470f |
+ loc_copy (&local->loc, loc);
|
|
|
a3470f |
local->fd_ctx = fd_ctx;
|
|
|
a3470f |
fd_ctx->flags = flags;
|
|
|
a3470f |
-
|
|
|
a3470f |
- call_count = local->call_count;
|
|
|
a3470f |
+ if (xdata)
|
|
|
a3470f |
+ local->xdata_req = dict_ref (xdata);
|
|
|
a3470f |
|
|
|
a3470f |
local->cont.open.flags = flags;
|
|
|
a3470f |
-
|
|
|
a3470f |
- for (i = 0; i < priv->child_count; i++) {
|
|
|
a3470f |
- if (local->child_up[i]) {
|
|
|
a3470f |
- STACK_WIND_COOKIE (frame, afr_open_cbk, (void *) (long) i,
|
|
|
a3470f |
- priv->children[i],
|
|
|
a3470f |
- priv->children[i]->fops->open,
|
|
|
a3470f |
- loc, (flags & ~O_TRUNC), fd, xdata);
|
|
|
a3470f |
- if (!--call_count)
|
|
|
a3470f |
- break;
|
|
|
a3470f |
- }
|
|
|
a3470f |
+ local->cont.open.fd = fd_ref (fd);
|
|
|
a3470f |
+
|
|
|
a3470f |
+ ret = afr_inode_get_readable (frame, local->inode, this,
|
|
|
a3470f |
+ NULL, &event_generation,
|
|
|
a3470f |
+ AFR_DATA_TRANSACTION);
|
|
|
a3470f |
+ if ((ret < 0) &&
|
|
|
a3470f |
+ (afr_inode_split_brain_choice_get (local->inode,
|
|
|
a3470f |
+ this, &spb_choice) == 0) &&
|
|
|
a3470f |
+ spb_choice < 0) {
|
|
|
a3470f |
+ afr_inode_refresh (frame, this, local->inode,
|
|
|
a3470f |
+ local->inode->gfid, afr_open_continue);
|
|
|
a3470f |
+ } else {
|
|
|
a3470f |
+ afr_open_continue (frame, this, 0);
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
return 0;
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
|
|
|
a3470f |
index 20e81dd..26d3860 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
|
|
|
a3470f |
@@ -66,9 +66,9 @@ afr_lookup_and_heal_gfid (xlator_t *this, inode_t *parent, const char *name,
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
- frame = afr_frame_create (this);
|
|
|
a3470f |
+ frame = afr_frame_create (this, &ret;;
|
|
|
a3470f |
if (!frame) {
|
|
|
a3470f |
- ret = -ENOMEM;
|
|
|
a3470f |
+ ret = -ret;
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
@@ -2349,18 +2349,17 @@ afr_inode_find (xlator_t *this, uuid_t gfid)
|
|
|
a3470f |
|
|
|
a3470f |
|
|
|
a3470f |
call_frame_t *
|
|
|
a3470f |
-afr_frame_create (xlator_t *this)
|
|
|
a3470f |
+afr_frame_create (xlator_t *this, int32_t *op_errno)
|
|
|
a3470f |
{
|
|
|
a3470f |
call_frame_t *frame = NULL;
|
|
|
a3470f |
afr_local_t *local = NULL;
|
|
|
a3470f |
- int op_errno = 0;
|
|
|
a3470f |
pid_t pid = GF_CLIENT_PID_SELF_HEALD;
|
|
|
a3470f |
|
|
|
a3470f |
frame = create_frame (this, this->ctx->pool);
|
|
|
a3470f |
if (!frame)
|
|
|
a3470f |
return NULL;
|
|
|
a3470f |
|
|
|
a3470f |
- local = AFR_FRAME_INIT (frame, op_errno);
|
|
|
a3470f |
+ local = AFR_FRAME_INIT (frame, (*op_errno));
|
|
|
a3470f |
if (!local) {
|
|
|
a3470f |
STACK_DESTROY (frame->root);
|
|
|
a3470f |
return NULL;
|
|
|
a3470f |
@@ -2490,7 +2489,7 @@ afr_selfheal (xlator_t *this, uuid_t gfid)
|
|
|
a3470f |
call_frame_t *frame = NULL;
|
|
|
a3470f |
afr_local_t *local = NULL;
|
|
|
a3470f |
|
|
|
a3470f |
- frame = afr_frame_create (this);
|
|
|
a3470f |
+ frame = afr_frame_create (this, NULL);
|
|
|
a3470f |
if (!frame)
|
|
|
a3470f |
return ret;
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
|
|
|
a3470f |
index 2c254e8..8cf43f2 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
|
|
|
a3470f |
@@ -776,13 +776,37 @@ out:
|
|
|
a3470f |
return ret;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
+int
|
|
|
a3470f |
+afr_selfheal_data_open_cbk (call_frame_t *frame, void *cookie,
|
|
|
a3470f |
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
|
|
|
a3470f |
+ fd_t *fd, dict_t *xdata)
|
|
|
a3470f |
+{
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
+ int i = (long) cookie;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ local = frame->local;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ local->replies[i].valid = 1;
|
|
|
a3470f |
+ local->replies[i].op_ret = op_ret;
|
|
|
a3470f |
+ local->replies[i].op_errno = op_errno;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ syncbarrier_wake (&local->barrier);
|
|
|
a3470f |
+
|
|
|
a3470f |
+ return 0;
|
|
|
a3470f |
+}
|
|
|
a3470f |
|
|
|
a3470f |
int
|
|
|
a3470f |
afr_selfheal_data_open (xlator_t *this, inode_t *inode, fd_t **fd)
|
|
|
a3470f |
{
|
|
|
a3470f |
- int ret = 0;
|
|
|
a3470f |
- fd_t *fd_tmp = NULL;
|
|
|
a3470f |
- loc_t loc = {0,};
|
|
|
a3470f |
+ int ret = 0;
|
|
|
a3470f |
+ fd_t *fd_tmp = NULL;
|
|
|
a3470f |
+ loc_t loc = {0,};
|
|
|
a3470f |
+ call_frame_t *frame = NULL;
|
|
|
a3470f |
+ afr_local_t *local = NULL;
|
|
|
a3470f |
+ afr_private_t *priv = NULL;
|
|
|
a3470f |
+ int i = 0;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ priv = this->private;
|
|
|
a3470f |
|
|
|
a3470f |
fd_tmp = fd_create (inode, 0);
|
|
|
a3470f |
if (!fd_tmp)
|
|
|
a3470f |
@@ -791,7 +815,31 @@ afr_selfheal_data_open (xlator_t *this, inode_t *inode, fd_t **fd)
|
|
|
a3470f |
loc.inode = inode_ref (inode);
|
|
|
a3470f |
gf_uuid_copy (loc.gfid, inode->gfid);
|
|
|
a3470f |
|
|
|
a3470f |
- ret = syncop_open (this, &loc, O_RDWR|O_LARGEFILE, fd_tmp, NULL, NULL);
|
|
|
a3470f |
+ frame = afr_frame_create (this, &ret;;
|
|
|
a3470f |
+ if (!frame) {
|
|
|
a3470f |
+ ret = -ret;
|
|
|
a3470f |
+ fd_unref (fd_tmp);
|
|
|
a3470f |
+ goto out;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ local = frame->local;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ AFR_ONLIST (local->child_up, frame, afr_selfheal_data_open_cbk, open,
|
|
|
a3470f |
+ &loc, O_RDWR|O_LARGEFILE, fd_tmp, NULL);
|
|
|
a3470f |
+
|
|
|
a3470f |
+ ret = -ENOTCONN;
|
|
|
a3470f |
+ for (i = 0; i < priv->child_count; i++) {
|
|
|
a3470f |
+ if (!local->replies[i].valid)
|
|
|
a3470f |
+ continue;
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if (local->replies[i].op_ret < 0) {
|
|
|
a3470f |
+ ret = -local->replies[i].op_errno;
|
|
|
a3470f |
+ continue;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+
|
|
|
a3470f |
+ ret = 0;
|
|
|
a3470f |
+ break;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+
|
|
|
a3470f |
if (ret < 0) {
|
|
|
a3470f |
fd_unref (fd_tmp);
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
@@ -802,6 +850,8 @@ afr_selfheal_data_open (xlator_t *this, inode_t *inode, fd_t **fd)
|
|
|
a3470f |
*fd = fd_tmp;
|
|
|
a3470f |
out:
|
|
|
a3470f |
loc_wipe (&loc;;
|
|
|
a3470f |
+ if (frame)
|
|
|
a3470f |
+ AFR_STACK_DESTROY (frame);
|
|
|
a3470f |
return ret;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c
|
|
|
a3470f |
index f23cf8e..199f896 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
|
|
|
a3470f |
@@ -486,9 +486,9 @@ afr_selfheal_metadata_by_stbuf (xlator_t *this, struct iatt *stbuf)
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
- frame = afr_frame_create (this);
|
|
|
a3470f |
+ frame = afr_frame_create (this, &ret;;
|
|
|
a3470f |
if (!frame) {
|
|
|
a3470f |
- ret = -ENOMEM;
|
|
|
a3470f |
+ ret = -ret;
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c
|
|
|
a3470f |
index 352d151..556d14b 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-self-heal-name.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-self-heal-name.c
|
|
|
a3470f |
@@ -670,7 +670,7 @@ afr_selfheal_name (xlator_t *this, uuid_t pargfid, const char *bname,
|
|
|
a3470f |
if (!parent)
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
|
|
|
a3470f |
- frame = afr_frame_create (this);
|
|
|
a3470f |
+ frame = afr_frame_create (this, NULL);
|
|
|
a3470f |
if (!frame)
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
|
|
|
a3470f |
index a1da433..188a334 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-self-heal.h
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-self-heal.h
|
|
|
a3470f |
@@ -209,7 +209,7 @@ afr_selfheal_post_op (call_frame_t *frame, xlator_t *this, inode_t *inode,
|
|
|
a3470f |
int subvol, dict_t *xattr, dict_t *xdata);
|
|
|
a3470f |
|
|
|
a3470f |
call_frame_t *
|
|
|
a3470f |
-afr_frame_create (xlator_t *this);
|
|
|
a3470f |
+afr_frame_create (xlator_t *this, int32_t *op_errno);
|
|
|
a3470f |
|
|
|
a3470f |
inode_t *
|
|
|
a3470f |
afr_inode_find (xlator_t *this, uuid_t gfid);
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
|
|
|
a3470f |
index 74c9bb6..19cde88 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-self-heald.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-self-heald.c
|
|
|
a3470f |
@@ -260,7 +260,7 @@ afr_shd_zero_xattrop (xlator_t *this, uuid_t gfid)
|
|
|
a3470f |
int raw[AFR_NUM_CHANGE_LOGS] = {0};
|
|
|
a3470f |
|
|
|
a3470f |
priv = this->private;
|
|
|
a3470f |
- frame = afr_frame_create (this);
|
|
|
a3470f |
+ frame = afr_frame_create (this, NULL);
|
|
|
a3470f |
if (!frame)
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
inode = afr_inode_find (this, gfid);
|
|
|
a3470f |
@@ -457,9 +457,9 @@ afr_shd_index_sweep (struct subvol_healer *healer, char *vgfid)
|
|
|
a3470f |
priv = healer->this->private;
|
|
|
a3470f |
subvol = priv->children[healer->subvol];
|
|
|
a3470f |
|
|
|
a3470f |
- frame = afr_frame_create (healer->this);
|
|
|
a3470f |
+ frame = afr_frame_create (healer->this, &ret;;
|
|
|
a3470f |
if (!frame) {
|
|
|
a3470f |
- ret = -ENOMEM;
|
|
|
a3470f |
+ ret = -ret;
|
|
|
a3470f |
goto out;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
|
|
|
a3470f |
index 91c4f78..a04636f 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr-transaction.c
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr-transaction.c
|
|
|
a3470f |
@@ -626,51 +626,10 @@ afr_txn_nothing_failed (call_frame_t *frame, xlator_t *this)
|
|
|
a3470f |
return _gf_true;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
-
|
|
|
a3470f |
void
|
|
|
a3470f |
afr_handle_symmetric_errors (call_frame_t *frame, xlator_t *this)
|
|
|
a3470f |
{
|
|
|
a3470f |
- afr_local_t *local = NULL;
|
|
|
a3470f |
- afr_private_t *priv = NULL;
|
|
|
a3470f |
- int op_errno = 0;
|
|
|
a3470f |
- int i_errno = 0;
|
|
|
a3470f |
- gf_boolean_t matching_errors = _gf_true;
|
|
|
a3470f |
- int i = 0;
|
|
|
a3470f |
-
|
|
|
a3470f |
- priv = this->private;
|
|
|
a3470f |
- local = frame->local;
|
|
|
a3470f |
-
|
|
|
a3470f |
- for (i = 0; i < priv->child_count; i++) {
|
|
|
a3470f |
- if (!local->replies[i].valid)
|
|
|
a3470f |
- continue;
|
|
|
a3470f |
- if (local->replies[i].op_ret != -1) {
|
|
|
a3470f |
- /* Operation succeeded on at least on subvol,
|
|
|
a3470f |
- so it is not a failed-everywhere situation.
|
|
|
a3470f |
- */
|
|
|
a3470f |
- matching_errors = _gf_false;
|
|
|
a3470f |
- break;
|
|
|
a3470f |
- }
|
|
|
a3470f |
- i_errno = local->replies[i].op_errno;
|
|
|
a3470f |
-
|
|
|
a3470f |
- if (i_errno == ENOTCONN) {
|
|
|
a3470f |
- /* ENOTCONN is not a symmetric error. We do not
|
|
|
a3470f |
- know if the operation was performed on the
|
|
|
a3470f |
- backend or not.
|
|
|
a3470f |
- */
|
|
|
a3470f |
- matching_errors = _gf_false;
|
|
|
a3470f |
- break;
|
|
|
a3470f |
- }
|
|
|
a3470f |
-
|
|
|
a3470f |
- if (!op_errno) {
|
|
|
a3470f |
- op_errno = i_errno;
|
|
|
a3470f |
- } else if (op_errno != i_errno) {
|
|
|
a3470f |
- /* Mismatching op_errno's */
|
|
|
a3470f |
- matching_errors = _gf_false;
|
|
|
a3470f |
- break;
|
|
|
a3470f |
- }
|
|
|
a3470f |
- }
|
|
|
a3470f |
-
|
|
|
a3470f |
- if (matching_errors)
|
|
|
a3470f |
+ if (afr_is_symmetric_error (frame, this))
|
|
|
a3470f |
__mark_all_success (frame, this);
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
|
|
|
a3470f |
index 672d053..0a06eb6 100644
|
|
|
a3470f |
--- a/xlators/cluster/afr/src/afr.h
|
|
|
a3470f |
+++ b/xlators/cluster/afr/src/afr.h
|
|
|
a3470f |
@@ -519,6 +519,7 @@ typedef struct _afr_local {
|
|
|
a3470f |
|
|
|
a3470f |
struct {
|
|
|
a3470f |
int32_t flags;
|
|
|
a3470f |
+ fd_t *fd;
|
|
|
a3470f |
} open;
|
|
|
a3470f |
|
|
|
a3470f |
struct {
|
|
|
a3470f |
@@ -1214,7 +1215,7 @@ int
|
|
|
a3470f |
afr_get_msg_id (char *op_type);
|
|
|
a3470f |
|
|
|
a3470f |
int
|
|
|
a3470f |
-afr_set_in_flight_sb_status (xlator_t *this, afr_local_t *local,
|
|
|
a3470f |
+afr_set_in_flight_sb_status (xlator_t *this, call_frame_t *frame,
|
|
|
a3470f |
inode_t *inode);
|
|
|
a3470f |
|
|
|
a3470f |
int32_t
|
|
|
a3470f |
@@ -1272,4 +1273,7 @@ afr_write_subvol_set (call_frame_t *frame, xlator_t *this);
|
|
|
a3470f |
|
|
|
a3470f |
int
|
|
|
a3470f |
afr_write_subvol_reset (call_frame_t *frame, xlator_t *this);
|
|
|
a3470f |
+
|
|
|
a3470f |
+gf_boolean_t
|
|
|
a3470f |
+afr_is_symmetric_error (call_frame_t *frame, xlator_t *this);
|
|
|
a3470f |
#endif /* __AFR_H__ */
|
|
|
a3470f |
--
|
|
|
a3470f |
1.8.3.1
|
|
|
a3470f |
|