diff options
| author | Vikas Gorur <vikas@gluster.com> | 2009-04-02 08:30:32 -0700 | 
|---|---|---|
| committer | Anand V. Avati <avati@amp.gluster.com> | 2009-04-02 21:07:53 +0530 | 
| commit | 1e7c9fa93716844e60d41811b8b79f8605a5044c (patch) | |
| tree | 30f9bb2f177fb22dfe919dbdd5f1657e41bf1fc2 | |
| parent | 9f2ef60274dae8b302d691ba8d266cd76dcd7c4b (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>
| -rw-r--r-- | xlators/cluster/afr/src/afr.c | 70 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 17 | 
2 files changed, 76 insertions, 11 deletions
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index e8a47a6c363..4ae302deb7c 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 02c69597b0d..5db6e98092a 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);		\  | 
