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 /xlators/cluster/ha | |
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>
Diffstat (limited to 'xlators/cluster/ha')
-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 e7391eeade1..b938071edde 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 7e4898ceb90..d47d965355e 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; |