summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/afr/src/afr-common.c')
-rw-r--r--xlators/cluster/afr/src/afr-common.c184
1 files changed, 168 insertions, 16 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index f7cc202d4d1..0af46993a34 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -67,6 +67,37 @@ afr_copy_frame (call_frame_t *base)
return frame;
}
+int
+__afr_inode_ctx_get (xlator_t *this, inode_t *inode, afr_inode_ctx_t **ctx)
+{
+ uint64_t ctx_int = 0;
+ int ret = -1;
+ afr_inode_ctx_t *tmp_ctx = NULL;
+
+ ret = __inode_ctx_get (inode, this, &ctx_int);
+ if (ret) {
+ tmp_ctx = GF_CALLOC (1, sizeof (afr_inode_ctx_t),
+ gf_afr_mt_inode_ctx_t);
+ if (!tmp_ctx)
+ goto out;
+
+ ctx_int = (long) tmp_ctx;
+ ret = __inode_ctx_set (inode, this, &ctx_int);
+ if (ret) {
+ GF_FREE (tmp_ctx);
+ goto out;
+ }
+ tmp_ctx->spb_choice = -1;
+ tmp_ctx->read_subvol = 0;
+ } else {
+ tmp_ctx = (afr_inode_ctx_t *) ctx_int;
+ }
+
+ *ctx = tmp_ctx;
+ ret = 0;
+out:
+ return ret;
+}
/*
* INODE CTX 64-bit VALUE FORMAT FOR SMALL (<= 16) SUBVOL COUNTS:
*
@@ -109,13 +140,16 @@ __afr_inode_read_subvol_get_small (inode_t *inode, xlator_t *this,
uint32_t event = 0;
uint64_t val = 0;
int i = 0;
+ afr_inode_ctx_t *ctx = NULL;
priv = this->private;
- ret = __inode_ctx_get (inode, this, &val);
+ ret = __afr_inode_ctx_get (this, inode, &ctx);
if (ret < 0)
return ret;
+ val = ctx->read_subvol;
+
metadatamap = (val & 0x000000000000ffff);
datamap = (val & 0x00000000ffff0000) >> 16;
event = (val & 0xffffffff00000000) >> 32;
@@ -143,9 +177,15 @@ __afr_inode_read_subvol_set_small (inode_t *inode, xlator_t *this,
uint16_t metadatamap = 0;
uint64_t val = 0;
int i = 0;
+ int ret = -1;
+ afr_inode_ctx_t *ctx = NULL;
priv = this->private;
+ ret = __afr_inode_ctx_get (this, inode, &ctx);
+ if (ret)
+ goto out;
+
for (i = 0; i < priv->child_count; i++) {
if (data[i])
datamap |= (1 << i);
@@ -157,9 +197,12 @@ __afr_inode_read_subvol_set_small (inode_t *inode, xlator_t *this,
(((uint64_t) datamap) << 16) |
(((uint64_t) event) << 32);
- return __inode_ctx_set (inode, this, &val);
-}
+ ctx->read_subvol = val;
+ ret = 0;
+out:
+ return ret;
+}
int
__afr_inode_read_subvol_reset_small (inode_t *inode, xlator_t *this)
@@ -169,9 +212,13 @@ __afr_inode_read_subvol_reset_small (inode_t *inode, xlator_t *this)
uint16_t metadatamap = 0;
uint32_t event = 0;
uint64_t val = 0;
+ afr_inode_ctx_t *ctx = NULL;
+
+ ret = __afr_inode_ctx_get (this, inode, &ctx);
+ if (ret)
+ return ret;
- ret = __inode_ctx_get (inode, this, &val);
- (void) ret;
+ val = ctx->read_subvol;
metadatamap = (val & 0x000000000000ffff) >> 0;
datamap = (val & 0x00000000ffff0000) >> 16;
@@ -181,7 +228,9 @@ __afr_inode_read_subvol_reset_small (inode_t *inode, xlator_t *this)
(((uint64_t) datamap) << 16) |
(((uint64_t) event) << 32);
- return __inode_ctx_set (inode, this, &val);
+ ctx->read_subvol = val;
+
+ return ret;
}
@@ -205,6 +254,20 @@ __afr_inode_read_subvol_get (inode_t *inode, xlator_t *this,
return ret;
}
+int
+__afr_inode_split_brain_choice_get (inode_t *inode, xlator_t *this,
+ int *spb_choice)
+{
+ afr_inode_ctx_t *ctx = NULL;
+ int ret = -1;
+
+ ret = __afr_inode_ctx_get (this, inode, &ctx);
+ if (ret < 0)
+ return ret;
+
+ *spb_choice = ctx->spb_choice;
+ return 0;
+}
int
__afr_inode_read_subvol_set (inode_t *inode, xlator_t *this, unsigned char *data,
@@ -224,6 +287,23 @@ __afr_inode_read_subvol_set (inode_t *inode, xlator_t *this, unsigned char *data
return ret;
}
+int
+__afr_inode_split_brain_choice_set (inode_t *inode, xlator_t *this,
+ int spb_choice)
+{
+ afr_inode_ctx_t *ctx = NULL;
+ int ret = -1;
+
+ ret = __afr_inode_ctx_get (this, inode, &ctx);
+ if (ret)
+ goto out;
+
+ ctx->spb_choice = spb_choice;
+
+ ret = 0;
+out:
+ return ret;
+}
int
__afr_inode_read_subvol_reset (inode_t *inode, xlator_t *this)
@@ -258,6 +338,22 @@ afr_inode_read_subvol_get (inode_t *inode, xlator_t *this, unsigned char *data,
return ret;
}
+int
+afr_inode_split_brain_choice_get (inode_t *inode, xlator_t *this,
+ int *spb_choice)
+{
+ int ret = -1;
+
+ LOCK(&inode->lock);
+ {
+ ret = __afr_inode_split_brain_choice_get (inode, this,
+ spb_choice);
+ }
+ UNLOCK(&inode->lock);
+
+ return ret;
+}
+
int
afr_inode_read_subvol_set (inode_t *inode, xlator_t *this, unsigned char *data,
@@ -275,6 +371,22 @@ afr_inode_read_subvol_set (inode_t *inode, xlator_t *this, unsigned char *data,
return ret;
}
+int
+afr_inode_split_brain_choice_set (inode_t *inode, xlator_t *this,
+ int spb_choice)
+{
+ int ret = -1;
+
+ LOCK(&inode->lock);
+ {
+ ret = __afr_inode_split_brain_choice_set (inode, this,
+ spb_choice);
+ }
+ UNLOCK(&inode->lock);
+
+ return ret;
+}
+
int
afr_inode_read_subvol_reset (inode_t *inode, xlator_t *this)
@@ -1220,6 +1332,7 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
gf_boolean_t locked_entry = _gf_false;
gf_boolean_t can_interpret = _gf_true;
inode_t *parent = NULL;
+ int spb_choice = -1;
priv = this->private;
local = frame->local;
@@ -1232,6 +1345,8 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
afr_inode_read_subvol_get (parent, this, readable, NULL, &event);
+ afr_inode_split_brain_choice_get (local->inode, this,
+ &spb_choice);
/* First, check if we have a gfid-change from somewhere,
If so, propagate that so that a fresh lookup can be
issued
@@ -1321,18 +1436,24 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
}
} else {
cant_interpret:
- if (read_subvol == -1)
- dict_del (replies[0].xdata, GF_CONTENT_KEY);
- else
- dict_del (replies[read_subvol].xdata, GF_CONTENT_KEY);
+ if (read_subvol == -1) {
+ if (spb_choice >= 0)
+ read_subvol = spb_choice;
+ else
+ read_subvol = 0;
+ }
+ dict_del (replies[read_subvol].xdata, GF_CONTENT_KEY);
}
afr_handle_quota_size (frame, this);
unwind:
- if (read_subvol == -1)
- read_subvol = 0;
-
+ if (read_subvol == -1) {
+ if (spb_choice >= 0)
+ read_subvol = spb_choice;
+ else
+ read_subvol = 0;
+ }
par_read_subvol = afr_get_parent_read_subvol (this, parent, replies,
readable);
@@ -1741,8 +1862,12 @@ afr_discover_done (call_frame_t *frame, xlator_t *this)
}
unwind:
- if (read_subvol == -1)
- read_subvol = 0;
+ if (read_subvol == -1) {
+ afr_inode_split_brain_choice_get (local->inode, this,
+ &read_subvol);
+ if (read_subvol == -1)
+ read_subvol = 0;
+ }
AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
local->inode, &local->replies[read_subvol].poststat,
@@ -3468,6 +3593,15 @@ out:
int
afr_forget (xlator_t *this, inode_t *inode)
{
+ uint64_t ctx_int = 0;
+ afr_inode_ctx_t *ctx = NULL;
+
+ inode_ctx_del (inode, this, &ctx_int);
+ if (!ctx_int)
+ return 0;
+
+ ctx = (afr_inode_ctx_t *)ctx_int;
+ GF_FREE (ctx);
return 0;
}
@@ -4594,8 +4728,26 @@ afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc)
}
out:
- AFR_STACK_UNWIND (getxattr, frame, ret, op_errno, dict, NULL);
+ if (local->op == GF_FOP_GETXATTR)
+ AFR_STACK_UNWIND (getxattr, frame, ret, op_errno, dict, NULL);
+ else if (local->op == GF_FOP_SETXATTR)
+ AFR_STACK_UNWIND (setxattr, frame, ret, op_errno, NULL);
if (dict)
dict_unref(dict);
return ret;
}
+
+int
+afr_get_child_index_from_name (xlator_t *this, char *name)
+{
+ afr_private_t *priv = this->private;
+ int index = -1;
+
+ for (index = 0; index < priv->child_count; index++) {
+ if (!strcmp (priv->children[index]->name, name))
+ goto out;
+ }
+ index = -1;
+out:
+ return index;
+}