From 9286a599f62289e8630ee28ea7da7308396d8fdf Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Fri, 5 Jun 2009 17:51:59 +0000 Subject: 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 --- xlators/cluster/ha/src/ha.c | 69 ++++++++++++++++++++++++++++----------------- xlators/cluster/ha/src/ha.h | 2 +- 2 files changed, 44 insertions(+), 27 deletions(-) (limited to 'xlators/cluster/ha') diff --git a/xlators/cluster/ha/src/ha.c b/xlators/cluster/ha/src/ha.c index e7391eea..b938071e 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 7e4898ce..d47d9653 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; -- cgit