diff options
| author | Amar Tumballi <amar@gluster.com> | 2009-06-05 17:51:59 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-06-17 16:04:32 -0700 | 
| commit | 9286a599f62289e8630ee28ea7da7308396d8fdf (patch) | |
| tree | 4d9151ec5cb717718346ed7f01f9aa66bf2fcfaf | |
| parent | bb4e14b213a39e9d403be9790ef0a75388496dee (diff) | |
change ha-statfs() to handle the case of loc->inode being NULL
This fix is needed in ha_statfs(), as the current code doesn't handle
the case of loc->inode being NULL, which is a valid case in statfs()
[Remember its stateless call]. This was causing 100% disk full logs in
distribute or nufa as the logic of checking whether the subvolumes have
enough disk space on them used to fail.
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
| -rw-r--r-- | xlators/cluster/ha/src/ha.c | 69 | ||||
| -rw-r--r-- | xlators/cluster/ha/src/ha.h | 2 | 
2 files changed, 44 insertions, 27 deletions
diff --git a/xlators/cluster/ha/src/ha.c b/xlators/cluster/ha/src/ha.c index e7391eead..b938071ed 100644 --- a/xlators/cluster/ha/src/ha.c +++ b/xlators/cluster/ha/src/ha.c @@ -2365,15 +2365,27 @@ ha_statfs_cbk (call_frame_t *frame,  	       int32_t op_errno,  	       struct statvfs *buf)  { -	int ret = -1; - -	ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); -	if (ret == 0) { -		STACK_UNWIND (frame, -			      op_ret, -			      op_errno, -			      buf); -	} +        ha_local_t   *local = NULL; +        ha_private_t *priv  = NULL; + +        local = frame->local; +        if (-1 == op_ret) { +                local->active = (local->active + 1) % priv->child_count; +                local->tries--; +                if (!local->tries) +                        goto out; +                 +                STACK_WIND (frame, ha_statfs_cbk, +                            HA_ACTIVE_CHILD(this, local), +                            HA_ACTIVE_CHILD(this, local)->fops->statfs,  +                            &local->loc); +                return 0; +        } + + out: +        loc_wipe (&local->loc); +        STACK_UNWIND (frame, op_ret, op_errno, buf); +          	return 0;  } @@ -2382,23 +2394,28 @@ ha_statfs (call_frame_t *frame,  	   xlator_t *this,  	   loc_t *loc)  { -	ha_local_t *local = NULL; -	int op_errno = 0; - -	op_errno = ha_alloc_init_inode (frame, loc->inode); -	if (op_errno < 0) { -		op_errno = -op_errno; -		goto err; -	} -	local = frame->local; - -	local->stub = fop_statfs_stub (frame, ha_statfs, loc); -	STACK_WIND_COOKIE (frame, -			   ha_statfs_cbk, -			   (void *)(long)local->active, -			   HA_ACTIVE_CHILD(this, local), -			   HA_ACTIVE_CHILD(this, local)->fops->statfs, -			   loc); +        ha_private_t *priv = NULL; +	ha_local_t   *local = NULL; +	int           op_errno = 0; + +        /* The normal way of handling failover doesn't work here +         * as loc->inode may be null in this case. +         */ +        local = CALLOC (1, sizeof (*local)); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } +        priv = this->private; +        frame->local  = local; +        local->active = priv->pref_subvol; +        if (-1 == local->active) +                local->active = 0; +        local->tries  = priv->child_count; +        loc_copy (&local->loc, loc); + +	STACK_WIND (frame, ha_statfs_cbk, HA_ACTIVE_CHILD(this, local), +                    HA_ACTIVE_CHILD(this, local)->fops->statfs, loc);  	return 0;  err:  	STACK_UNWIND (frame, -1, op_errno, NULL); diff --git a/xlators/cluster/ha/src/ha.h b/xlators/cluster/ha/src/ha.h index 7e4898ceb..d47d96535 100644 --- a/xlators/cluster/ha/src/ha.h +++ b/xlators/cluster/ha/src/ha.h @@ -27,7 +27,7 @@ typedef struct {  	int32_t call_count;  	char *state, *pattern;  	dict_t *dict; -	loc_t *loc; +	loc_t loc;  	struct stat buf;  	fd_t *fd;  	inode_t *inode;  | 
