diff options
Diffstat (limited to 'xlators/cluster/afr/src/afr.c')
-rw-r--r-- | xlators/cluster/afr/src/afr.c | 70 |
1 files changed, 59 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; |