summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src
diff options
context:
space:
mode:
authorVikas Gorur <vikas@gluster.com>2009-04-02 08:30:32 -0700
committerAnand V. Avati <avati@amp.gluster.com>2009-04-02 21:07:53 +0530
commit1e7c9fa93716844e60d41811b8b79f8605a5044c (patch)
tree30f9bb2f177fb22dfe919dbdd5f1657e41bf1fc2 /xlators/cluster/afr/src
parent9f2ef60274dae8b302d691ba8d266cd76dcd7c4b (diff)
Defined afr_inode_ctx_t structure.
Notification of a split-brain situation, which was earlier signalled by the mere presence of inode context is now signalled by the 'split_brain' member in the structure. Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
Diffstat (limited to 'xlators/cluster/afr/src')
-rw-r--r--xlators/cluster/afr/src/afr.c70
-rw-r--r--xlators/cluster/afr/src/afr.h17
2 files changed, 76 insertions, 11 deletions
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
index e8a47a6c3..4ae302deb 100644
--- a/xlators/cluster/afr/src/afr.c
+++ b/xlators/cluster/afr/src/afr.c
@@ -306,17 +306,24 @@ afr_self_heal_cbk (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
int ret = -1;
+ afr_inode_ctx_t * inode_ctx = NULL;
+ uint64_t ctx;
+
local = frame->local;
+ ret = inode_ctx_get (local->cont.lookup.inode, this, &ctx);
+
+ inode_ctx = (afr_inode_ctx_t *)(long) ctx;
+
if (local->govinda_gOvinda) {
- ret = inode_ctx_put (local->cont.lookup.inode, this, 1);
+ inode_ctx->split_brain = 1;
if (ret < 0) {
local->op_ret = -1;
local->op_errno = -ret;
}
} else {
- inode_ctx_del (local->cont.lookup.inode, this, NULL);
+ inode_ctx->split_brain = 0;
}
AFR_STACK_UNWIND (frame, local->op_ret, local->op_errno,
@@ -497,8 +504,11 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
+
int32_t op_errno = 0;
+ afr_inode_ctx_t *inode_ctx = NULL;
+ uint64_t ctx;
priv = this->private;
@@ -510,6 +520,30 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
loc_copy (&local->loc, loc);
+ ret = inode_ctx_get (loc->inode, this, &ctx);
+ inode_ctx = (afr_inode_ctx_t *)(long) ctx;
+
+ if (ret < 0) {
+ inode_ctx = CALLOC (1, sizeof (afr_inode_ctx_t));
+
+ if (!inode_ctx) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory :(");
+ goto out;
+ }
+
+ ret = inode_ctx_put (loc->inode, this,
+ (uint64_t)(long) inode_ctx);
+
+ if (ret < 0) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not set inode ctx");
+ goto out;
+ }
+ }
+
local->reval_child_index = 0;
local->call_count = priv->child_count;
@@ -556,7 +590,7 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
ret = 0;
out:
if (ret == -1)
- AFR_STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL);
return 0;
}
@@ -625,7 +659,10 @@ afr_open (call_frame_t *frame, xlator_t *this,
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
-
+
+ afr_inode_ctx_t * inode_ctx = NULL;
+ uint64_t ctx;
+
int i = 0;
int ret = -1;
@@ -638,22 +675,33 @@ afr_open (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (this->private, out);
VALIDATE_OR_GOTO (loc, out);
-
+
priv = this->private;
- ret = inode_ctx_get (loc->inode, this, NULL);
- if (ret == 0) {
- /* if ctx is set it means self-heal failed */
+ ret = inode_ctx_get (loc->inode, this, &ctx);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "inode ctx not set!");
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ inode_ctx = (afr_inode_ctx_t *)(long) ctx;
- gf_log (this->name, GF_LOG_WARNING,
+ if (inode_ctx->split_brain) {
+ /* self-heal failed */
+
+ gf_log (this->name, GF_LOG_WARNING,
"returning EIO, file has to be manually corrected "
- "in backend");
+ "in the backend");
+
op_errno = EIO;
goto out;
}
ALLOC_OR_GOTO (local, afr_local_t, out);
-
+
ret = AFR_LOCAL_INIT (local, priv);
if (ret < 0) {
op_errno = -ret;
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 02c69597b..5db6e9809 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -389,6 +389,23 @@ typedef struct _afr_local {
afr_self_heal_t self_heal;
} afr_local_t;
+
+typedef struct {
+ /*
+ split-brain situation in which afr
+ can do nothing
+ */
+ gf_boolean_t split_brain;
+
+ /*
+ subvolume from which all reads should
+ happen for this inode
+ */
+ int read_child;
+
+} afr_inode_ctx_t;
+
+
/* try alloc and if it fails, goto label */
#define ALLOC_OR_GOTO(var, type, label) do { \
var = CALLOC (sizeof (type), 1); \