summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/cluster/afr/src/afr-common.c31
-rw-r--r--xlators/cluster/afr/src/afr-read-txn.c4
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c95
-rw-r--r--xlators/cluster/afr/src/afr.h5
4 files changed, 98 insertions, 37 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 08186b0bbcb..d7bc3e29ee2 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -380,10 +380,6 @@ afr_inode_get_readable (call_frame_t *frame, inode_t *inode, xlator_t *this,
int event_generation = 0;
int ret = 0;
- /* We don't care about split-brains for entry transactions. */
- if (type == AFR_ENTRY_TRANSACTION || type == AFR_ENTRY_RENAME_TRANSACTION)
- return 0;
-
ret = afr_inode_read_subvol_get (inode, this, data, metadata,
&event_generation);
if (ret == -1)
@@ -926,7 +922,8 @@ afr_inode_refresh_subvol_with_lookup_cbk (call_frame_t *frame, void *cookie,
int
afr_inode_refresh_subvol_with_lookup (call_frame_t *frame, xlator_t *this,
- int i, inode_t *inode, dict_t *xdata)
+ int i, inode_t *inode, uuid_t gfid,
+ dict_t *xdata)
{
loc_t loc = {0, };
afr_private_t *priv = NULL;
@@ -934,7 +931,13 @@ afr_inode_refresh_subvol_with_lookup (call_frame_t *frame, xlator_t *this,
priv = this->private;
loc.inode = inode;
- gf_uuid_copy (loc.gfid, inode->gfid);
+ if (gf_uuid_is_null (inode->gfid) && gfid) {
+ /* To handle setattr/setxattr on yet to be linked inode from
+ * dht */
+ gf_uuid_copy (loc.gfid, gfid);
+ } else {
+ gf_uuid_copy (loc.gfid, inode->gfid);
+ }
STACK_WIND_COOKIE (frame, afr_inode_refresh_subvol_with_lookup_cbk,
(void *) (long) i, priv->children[i],
@@ -1048,7 +1051,8 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
xdata);
else
afr_inode_refresh_subvol_with_lookup (frame, this, i,
- local->refreshinode, xdata);
+ local->refreshinode,
+ local->refreshgfid, xdata);
if (!--call_count)
break;
@@ -1062,7 +1066,7 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
int
afr_inode_refresh (call_frame_t *frame, xlator_t *this, inode_t *inode,
- afr_inode_refresh_cbk_t refreshfn)
+ uuid_t gfid, afr_inode_refresh_cbk_t refreshfn)
{
afr_local_t *local = NULL;
@@ -1077,6 +1081,11 @@ afr_inode_refresh (call_frame_t *frame, xlator_t *this, inode_t *inode,
local->refreshinode = inode_ref (inode);
+ if (gfid)
+ gf_uuid_copy (local->refreshgfid, gfid);
+ else
+ gf_uuid_clear (local->refreshgfid);
+
afr_inode_refresh_do (frame, this);
return 0;
@@ -2408,7 +2417,8 @@ afr_discover (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req
AFR_DATA_TRANSACTION, NULL);
if (event != local->event_generation)
- afr_inode_refresh (frame, this, loc->inode, afr_discover_do);
+ afr_inode_refresh (frame, this, loc->inode, NULL,
+ afr_discover_do);
else
afr_discover_do (frame, this, 0);
@@ -2558,7 +2568,8 @@ afr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
AFR_DATA_TRANSACTION, NULL);
if (event != local->event_generation)
- afr_inode_refresh (frame, this, loc->parent, afr_lookup_do);
+ afr_inode_refresh (frame, this, loc->parent, NULL,
+ afr_lookup_do);
else
afr_lookup_do (frame, this, 0);
diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c
index a70565c37a1..32ad6a46d17 100644
--- a/xlators/cluster/afr/src/afr-read-txn.c
+++ b/xlators/cluster/afr/src/afr-read-txn.c
@@ -121,7 +121,7 @@ afr_read_txn_continue (call_frame_t *frame, xlator_t *this, int subvol)
if (!local->refreshed) {
local->refreshed = _gf_true;
- afr_inode_refresh (frame, this, local->inode,
+ afr_inode_refresh (frame, this, local->inode, NULL,
afr_read_txn_refresh_done);
} else {
afr_read_txn_next_subvol (frame, this);
@@ -268,7 +268,7 @@ read:
return 0;
refresh:
- afr_inode_refresh (frame, this, inode, afr_read_txn_refresh_done);
+ afr_inode_refresh (frame, this, inode, NULL, afr_read_txn_refresh_done);
return 0;
}
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index ff2b58c032d..22b6997f2f7 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -2086,32 +2086,13 @@ unlock:
UNLOCK (&local->fd->lock);
}
-
-int
-afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type)
+void
+afr_transaction_start (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- fd_t *fd = NULL;
- int ret = -1;
-
- local = frame->local;
- priv = this->private;
-
- local->transaction.resume = afr_transaction_resume;
- local->transaction.type = type;
-
- ret = afr_transaction_local_init (local, this);
- if (ret < 0)
- goto out;
+ afr_local_t *local = frame->local;
+ afr_private_t *priv = this->private;
+ fd_t *fd = NULL;
- ret = afr_inode_get_readable (frame, local->inode, this, 0, 0, type);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, EIO, AFR_MSG_SPLIT_BRAIN,
- "Failing %s on gfid %s: split-brain observed.",
- gf_fop_list[local->op], uuid_utoa (local->inode->gfid));
- goto out;
- }
afr_transaction_eager_lock_init (local, this);
if (local->fd && local->transaction.eager_lock_on)
@@ -2135,6 +2116,72 @@ afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type)
} else {
afr_lock (frame, this);
}
+}
+
+int
+afr_write_txn_refresh_done (call_frame_t *frame, xlator_t *this, int err)
+{
+ afr_local_t *local = frame->local;
+ afr_private_t *priv = this->private;
+ int ret = 0;
+
+ if (err) {
+ local->op_errno = -err;
+ local->op_ret = -1;
+ goto fail;
+ }
+ ret = afr_inode_get_readable (frame, local->inode, this,
+ local->readable, NULL,
+ local->transaction.type);
+ if (ret < 0) {
+ gf_msg (this->name, GF_LOG_ERROR, -ret, AFR_MSG_SPLIT_BRAIN,
+ "Failing %s on gfid %s: split-brain observed.",
+ gf_fop_list[local->op], uuid_utoa (local->inode->gfid));
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ goto fail;
+ }
+ afr_transaction_start (frame, this);
+ return 0;
+fail:
+ local->transaction.unwind (frame, this);
+ AFR_STACK_DESTROY (frame);
+ return 0;
+}
+
+int
+afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int ret = -1;
+ int event_generation = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ local->transaction.resume = afr_transaction_resume;
+ local->transaction.type = type;
+
+ ret = afr_transaction_local_init (local, this);
+ if (ret < 0)
+ goto out;
+
+ if (type == AFR_ENTRY_TRANSACTION ||
+ type == AFR_ENTRY_RENAME_TRANSACTION) {
+ afr_transaction_start (frame, this);
+ ret = 0;
+ goto out;
+ }
+
+ ret = afr_inode_get_readable (frame, local->inode, this,
+ local->readable, &event_generation, type);
+ if (ret < 0 || event_generation != priv->event_generation) {
+ afr_inode_refresh (frame, this, local->inode, local->loc.gfid,
+ afr_write_txn_refresh_done);
+ } else {
+ afr_transaction_start (frame, this);
+ }
ret = 0;
out:
return ret;
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index f16f9b4b4ac..7d270ea94e7 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -422,6 +422,9 @@ typedef struct _afr_local {
*/
inode_t *refreshinode;
+ /*To handle setattr/setxattr on yet to be linked inode from dht*/
+ uuid_t refreshgfid;
+
/*
@pre_op_compat:
@@ -855,7 +858,7 @@ afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p,
int
afr_inode_refresh (call_frame_t *frame, xlator_t *this, inode_t *inode,
- afr_inode_refresh_cbk_t cbk);
+ uuid_t gfid, afr_inode_refresh_cbk_t cbk);
int32_t
afr_notify (xlator_t *this, int32_t event, void *data, void *data2);