summaryrefslogtreecommitdiffstats
path: root/xlators/cluster
diff options
context:
space:
mode:
authorAmar Tumballi <amar@gluster.com>2009-06-05 17:51:59 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-06-17 16:04:32 -0700
commit9286a599f62289e8630ee28ea7da7308396d8fdf (patch)
tree4d9151ec5cb717718346ed7f01f9aa66bf2fcfaf /xlators/cluster
parentbb4e14b213a39e9d403be9790ef0a75388496dee (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')
-rw-r--r--xlators/cluster/ha/src/ha.c69
-rw-r--r--xlators/cluster/ha/src/ha.h2
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;