diff options
Diffstat (limited to 'xlators/cluster/ha/src/ha.c')
| -rw-r--r-- | xlators/cluster/ha/src/ha.c | 1333 |
1 files changed, 927 insertions, 406 deletions
diff --git a/xlators/cluster/ha/src/ha.c b/xlators/cluster/ha/src/ha.c index e7391eead..3eccb516b 100644 --- a/xlators/cluster/ha/src/ha.c +++ b/xlators/cluster/ha/src/ha.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2008-2009 Z RESEARCH, Inc. <http://www.zresearch.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ /* generate errors randomly, code is simple now, better alogorithm * can be written to decide what error to be returned and when */ @@ -41,6 +31,41 @@ * - do not alloc the call-stub in case only one subvol is up. */ +void +ha_local_wipe (ha_local_t *local) +{ + if (local->stub) { + call_stub_destroy (local->stub); + local->stub = NULL; + } + + if (local->state) { + GF_FREE (local->state); + local->state = NULL; + } + + if (local->dict) { + dict_unref (local->dict); + local->dict = NULL; + } + + loc_wipe (&local->loc); + + if (local->fd) { + fd_unref (local->fd); + local->fd = NULL; + } + + if (local->inode) { + inode_unref (local->inode); + local->inode = NULL; + } + + GF_FREE (local); + return; +} + + int ha_forget (xlator_t *this, inode_t *inode) @@ -49,7 +74,7 @@ ha_forget (xlator_t *this, char *state = NULL; if (!inode_ctx_del (inode, this, &stateino)) { state = ((char *)(long)stateino); - FREE (state); + GF_FREE (state); } return 0; @@ -63,8 +88,9 @@ ha_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - dict_t *dict) + struct iatt *buf, + dict_t *dict, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -106,6 +132,7 @@ ha_lookup_cbk (call_frame_t *frame, if (local->op_ret == -1 && op_ret == 0) { local->op_ret = 0; local->buf = *buf; + local->postparent = *postparent; if (dict) local->dict = dict_ref (dict); } @@ -127,7 +154,8 @@ ha_lookup_cbk (call_frame_t *frame, local->op_errno, inode, &local->buf, - ctx); + ctx, + &local->postparent); if (inode) inode_unref (inode); if (ctx) @@ -148,19 +176,33 @@ ha_lookup (call_frame_t *frame, char *state = NULL; xlator_t **children = NULL; int ret = -1; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; child_count = pvt->child_count; children = pvt->children; - frame->local = local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto unwind; + } + child_count = pvt->child_count; local->inode = inode_ref (loc->inode); ret = inode_ctx_get (loc->inode, this, NULL); if (ret) { - state = CALLOC (1, child_count); + state = GF_CALLOC (1, child_count, gf_ha_mt_child_count); + if (state == NULL) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto unwind; + } + inode_ctx_put (loc->inode, this, (uint64_t)(long)state); } else local->revalidate = 1; @@ -178,6 +220,14 @@ ha_lookup (call_frame_t *frame, xattr_req); } return 0; + +unwind: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL); + + ha_local_wipe (local); + return 0; } int32_t @@ -186,7 +236,7 @@ ha_stat_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf) + struct iatt *buf) { int ret = -1; @@ -229,135 +279,25 @@ err: return 0; } - int32_t -ha_chmod_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *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); - } - return 0; -} - int32_t -ha_chmod (call_frame_t *frame, - xlator_t *this, - loc_t *loc, - mode_t mode) -{ - 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_chmod_stub (frame, ha_chmod, loc, mode); - - STACK_WIND_COOKIE (frame, - ha_chmod_cbk, - (void *)(long)local->active, - HA_ACTIVE_CHILD(this, local), - HA_ACTIVE_CHILD(this, local)->fops->chmod, - loc, - mode); - return 0; -err: - STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; -} - - int32_t -ha_fchmod_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) +ha_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *statpre, + struct iatt *statpost) { int ret = -1; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); if (ret == 0) { - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); + STACK_UNWIND (frame, op_ret, op_errno, statpre, statpost); } return 0; } -int32_t -ha_fchmod (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - mode_t mode) -{ - ha_local_t *local = NULL; - int op_errno = 0; - - op_errno = ha_alloc_init_fd (frame, fd); - if (op_errno < 0) { - op_errno = -op_errno; - goto err; - } - local = frame->local; - local->stub = fop_fchmod_stub (frame, ha_fchmod, fd, mode); - - STACK_WIND_COOKIE (frame, - ha_fchmod_cbk, - (void *)(long)local->active, - HA_ACTIVE_CHILD(this, local), - HA_ACTIVE_CHILD(this, local)->fops->fchmod, - fd, - mode); - return 0; -err: - STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; -} - - int32_t -ha_chown_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *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); - } - return 0; -} int32_t -ha_chown (call_frame_t *frame, - xlator_t *this, - loc_t *loc, - uid_t uid, - gid_t gid) +ha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, + int32_t valid) { ha_local_t *local = NULL; int op_errno = 0; @@ -368,49 +308,24 @@ ha_chown (call_frame_t *frame, goto err; } local = frame->local; - local->stub = fop_chown_stub (frame, ha_chown, loc, uid, gid); + local->stub = fop_setattr_stub (frame, ha_setattr, loc, stbuf, valid); - STACK_WIND_COOKIE (frame, - ha_chown_cbk, + STACK_WIND_COOKIE (frame, + ha_setattr_cbk, (void *)(long)local->active, HA_ACTIVE_CHILD(this, local), - HA_ACTIVE_CHILD(this, local)->fops->chown, - loc, - uid, - gid); + HA_ACTIVE_CHILD(this, local)->fops->setattr, + loc, stbuf, valid); return 0; err: - STACK_UNWIND (frame, -1, ENOTCONN, NULL); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); return 0; } - int32_t -ha_fchown_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *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); - } - return 0; -} - -int32_t -ha_fchown (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - uid_t uid, - gid_t gid) +int32_t +ha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, + int32_t valid) { ha_local_t *local = NULL; int op_errno = 0; @@ -421,29 +336,29 @@ ha_fchown (call_frame_t *frame, goto err; } local = frame->local; - local->stub = fop_fchown_stub (frame, ha_fchown, fd, uid, gid); + local->stub = fop_fsetattr_stub (frame, ha_fsetattr, fd, stbuf, valid); STACK_WIND_COOKIE (frame, - ha_fchown_cbk, + ha_setattr_cbk, (void *)(long)local->active, HA_ACTIVE_CHILD(this, local), - HA_ACTIVE_CHILD(this, local)->fops->fchown, - fd, - uid, - gid); + HA_ACTIVE_CHILD(this, local)->fops->fsetattr, + fd, stbuf, valid); return 0; err: - STACK_UNWIND (frame, -1, op_errno, NULL); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); return 0; } - int32_t + +int32_t ha_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = -1; @@ -452,7 +367,8 @@ ha_truncate_cbk (call_frame_t *frame, STACK_UNWIND (frame, op_ret, op_errno, - buf); + prebuf, + postbuf); } return 0; } @@ -473,6 +389,11 @@ ha_truncate (call_frame_t *frame, } local = frame->local; local->stub = fop_truncate_stub (frame, ha_truncate, loc, offset); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_truncate_cbk, @@ -483,7 +404,7 @@ ha_truncate (call_frame_t *frame, offset); return 0; err: - STACK_UNWIND (frame, -1, op_errno, NULL); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); return 0; } @@ -493,7 +414,8 @@ ha_ftruncate_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = -1; @@ -503,7 +425,7 @@ ha_ftruncate_cbk (call_frame_t *frame, STACK_UNWIND (frame, op_ret, op_errno, - buf); + prebuf, postbuf); } return 0; } @@ -524,6 +446,11 @@ ha_ftruncate (call_frame_t *frame, } local = frame->local; local->stub = fop_ftruncate_stub (frame, ha_ftruncate, fd, offset); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_ftruncate_cbk, @@ -534,58 +461,12 @@ ha_ftruncate (call_frame_t *frame, offset); return 0; err: - STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; -} - -int32_t -ha_utimens_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - int ret = -1; + local = frame->local; + frame->local = NULL; - ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); - - if (ret == 0) { - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - } - return 0; -} - -int32_t -ha_utimens (call_frame_t *frame, - xlator_t *this, - loc_t *loc, - struct timespec tv[2]) -{ - 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_utimens_stub (frame, ha_utimens, loc, tv); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); - STACK_WIND_COOKIE (frame, - ha_utimens_cbk, - (void *)(long)local->active, - HA_ACTIVE_CHILD(this, local), - HA_ACTIVE_CHILD(this, local)->fops->utimens, - loc, - tv); - return 0; -err: - STACK_UNWIND (frame, -1, op_errno, NULL); + ha_local_wipe (local); return 0; } @@ -624,6 +505,11 @@ ha_access (call_frame_t *frame, } local = frame->local; local->stub = fop_access_stub (frame, ha_access, loc, mask); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_access_cbk, @@ -634,7 +520,12 @@ ha_access (call_frame_t *frame, mask); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno); + + ha_local_wipe (local); return 0; } @@ -645,7 +536,8 @@ ha_readlink_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - const char *path) + const char *path, + struct iatt *sbuf) { int ret = -1; @@ -655,7 +547,8 @@ ha_readlink_cbk (call_frame_t *frame, STACK_UNWIND (frame, op_ret, op_errno, - path); + path, + sbuf); } return 0; } @@ -686,7 +579,7 @@ ha_readlink (call_frame_t *frame, size); return 0; err: - STACK_UNWIND (frame, -1, op_errno, NULL); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); return 0; } @@ -697,8 +590,9 @@ ha_mknod_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - dict_t *dict) + struct iatt *buf, + dict_t *dict, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -742,12 +636,13 @@ ha_mknod_lookup_cbk (call_frame_t *frame, if (cnt == 0) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); STACK_UNWIND (frame, local->op_ret, local->op_errno, local->stub->args.mknod.loc.inode, - &local->buf); + &local->buf, &local->preparent, + &local->postparent); call_stub_destroy (stub); } return 0; @@ -760,7 +655,9 @@ ha_mknod_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -798,6 +695,8 @@ ha_mknod_cbk (call_frame_t *frame, local->op_ret = 0; local->first_success = 1; local->buf = *buf; + local->preparent = *preparent; + local->postparent = *postparent; } cnt = --local->call_count; for (i = local->active + 1; i < child_count; i++) { @@ -807,9 +706,11 @@ ha_mknod_cbk (call_frame_t *frame, if (cnt == 0 || i == child_count) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); stub = local->stub; - STACK_UNWIND (frame, local->op_ret, local->op_errno, local->stub->args.mknod.loc.inode, &local->buf); + STACK_UNWIND (frame, local->op_ret, local->op_errno, + local->stub->args.mknod.loc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); return 0; } @@ -854,20 +755,46 @@ ha_mknod (call_frame_t *frame, ha_private_t *pvt = NULL; int child_count = 0, i = 0; char *stateino = NULL; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; child_count = pvt->child_count; - frame->local = local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + local->stub = fop_mknod_stub (frame, ha_mknod, loc, mode, rdev); + if (!local->stub) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + local->op_ret = -1; local->op_errno = ENOTCONN; - local->state = CALLOC (1, child_count); + local->state = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!local->state) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + memcpy (local->state, pvt->state, child_count); local->active = -1; - stateino = CALLOC (1, child_count); + stateino = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!stateino) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + inode_ctx_put (loc->inode, this, (uint64_t)(long)stateino); for (i = 0; i < child_count; i++) { @@ -884,6 +811,14 @@ ha_mknod (call_frame_t *frame, HA_ACTIVE_CHILD(this, local)->fops->mknod, loc, mode, rdev); return 0; + +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL); + ha_local_wipe (local); + return 0; } @@ -894,8 +829,9 @@ ha_mkdir_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - dict_t *dict) + struct iatt *buf, + dict_t *dict, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -931,12 +867,12 @@ ha_mkdir_lookup_cbk (call_frame_t *frame, if (cnt == 0) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); STACK_UNWIND (frame, local->op_ret, local->op_errno, - local->stub->args.mkdir.loc.inode, - &local->buf); + local->stub->args.mkdir.loc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); } return 0; @@ -949,7 +885,9 @@ ha_mkdir_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -983,6 +921,8 @@ ha_mkdir_cbk (call_frame_t *frame, local->op_ret = 0; local->first_success = 1; local->buf = *buf; + local->preparent = *preparent; + local->postparent = *postparent; } cnt = --local->call_count; for (i = local->active + 1; i < child_count; i++) { @@ -992,9 +932,11 @@ ha_mkdir_cbk (call_frame_t *frame, if (cnt == 0 || i == child_count) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); stub = local->stub; - STACK_UNWIND (frame, local->op_ret, local->op_errno, local->stub->args.mkdir.loc.inode, &local->buf); + STACK_UNWIND (frame, local->op_ret, local->op_errno, + local->stub->args.mkdir.loc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); return 0; } @@ -1037,20 +979,46 @@ ha_mkdir (call_frame_t *frame, ha_private_t *pvt = NULL; int child_count = 0, i = 0; char *stateino = NULL; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; child_count = pvt->child_count; - frame->local = local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!frame->local) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + local->stub = fop_mkdir_stub (frame, ha_mkdir, loc, mode); + if (!local->stub) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + local->op_ret = -1; local->op_errno = ENOTCONN; - local->state = CALLOC (1, child_count); + local->state = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!local->state) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + memcpy (local->state, pvt->state, child_count); local->active = -1; - stateino = CALLOC (1, child_count); + stateino = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!stateino) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + inode_ctx_put (loc->inode, this, (uint64_t)(long)stateino); for (i = 0; i < child_count; i++) { if (local->state[i]) { @@ -1066,6 +1034,13 @@ ha_mkdir (call_frame_t *frame, HA_ACTIVE_CHILD(this, local)->fops->mkdir, loc, mode); return 0; +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL); + ha_local_wipe (local); + return 0; } int32_t @@ -1073,13 +1048,15 @@ ha_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, - int32_t op_errno) + int32_t op_errno, + struct iatt *preparent, + struct iatt *postparent) { int ret = -1; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); if (ret == 0) { - STACK_UNWIND (frame, op_ret, op_errno); + STACK_UNWIND (frame, op_ret, op_errno, preparent, postparent); } return 0; } @@ -1100,6 +1077,11 @@ ha_unlink (call_frame_t *frame, } local = frame->local; local->stub = fop_unlink_stub (frame, ha_unlink, loc); + if (!local->stub) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } STACK_WIND_COOKIE (frame, ha_unlink_cbk, @@ -1109,7 +1091,7 @@ ha_unlink (call_frame_t *frame, loc); return 0; err: - STACK_UNWIND (frame, -1, op_errno); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); return 0; } @@ -1118,7 +1100,9 @@ ha_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, - int32_t op_errno) + int32_t op_errno, + struct iatt *preparent, + struct iatt *postparent) { int ret = -1; @@ -1127,7 +1111,9 @@ ha_rmdir_cbk (call_frame_t *frame, if (ret == 0) { STACK_UNWIND (frame, op_ret, - op_errno); + op_errno, + preparent, + postparent); } return 0; } @@ -1147,6 +1133,11 @@ ha_rmdir (call_frame_t *frame, } local = frame->local; local->stub = fop_rmdir_stub (frame, ha_rmdir, loc); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_rmdir_cbk, @@ -1156,7 +1147,7 @@ ha_rmdir (call_frame_t *frame, loc); return 0; err: - STACK_UNWIND (frame, -1, op_errno); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); return 0; } @@ -1168,8 +1159,9 @@ ha_symlink_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - dict_t *dict) + struct iatt *buf, + dict_t *dict, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1205,12 +1197,12 @@ ha_symlink_lookup_cbk (call_frame_t *frame, if (cnt == 0) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); STACK_UNWIND (frame, local->op_ret, local->op_errno, - local->stub->args.symlink.loc.inode, - &local->buf); + local->stub->args.symlink.loc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); } return 0; @@ -1223,7 +1215,9 @@ ha_symlink_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1256,6 +1250,8 @@ ha_symlink_cbk (call_frame_t *frame, local->op_ret = 0; local->first_success = 1; local->buf = *buf; + local->preparent = *preparent; + local->postparent = *postparent; } cnt = --local->call_count; for (i = local->active + 1; i < child_count; i++) { @@ -1265,10 +1261,11 @@ ha_symlink_cbk (call_frame_t *frame, if (cnt == 0 || i == child_count) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); stub = local->stub; STACK_UNWIND (frame, local->op_ret, local->op_errno, - local->stub->args.symlink.loc.inode, &local->buf); + local->stub->args.symlink.loc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); return 0; } @@ -1311,20 +1308,46 @@ ha_symlink (call_frame_t *frame, ha_private_t *pvt = NULL; int child_count = 0, i = 0; char *stateino = NULL; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; child_count = pvt->child_count; - frame->local = local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->stub = fop_symlink_stub (frame, ha_symlink, linkname, loc); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->op_ret = -1; local->op_errno = ENOTCONN; - local->state = CALLOC (1, child_count); + local->state = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!local->state) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + memcpy (local->state, pvt->state, child_count); local->active = -1; - stateino = CALLOC (1, child_count); + stateino = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!stateino) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + inode_ctx_put (loc->inode, this, (uint64_t)(long)stateino); for (i = 0; i < child_count; i++) { @@ -1342,6 +1365,12 @@ ha_symlink (call_frame_t *frame, HA_ACTIVE_CHILD(this, local)->fops->symlink, linkname, loc); return 0; +err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL); + ha_local_wipe (local); + return 0; } int32_t @@ -1350,14 +1379,19 @@ ha_rename_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf) + struct iatt *buf, + struct iatt *preoldparent, + struct iatt *postoldparent, + struct iatt *prenewparent, + struct iatt *postnewparent) { int ret = -1; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); if (ret == 0) { - STACK_UNWIND (frame, op_ret, op_errno, buf); + STACK_UNWIND (frame, op_ret, op_errno, buf, preoldparent, + postoldparent, prenewparent, postnewparent); } return 0; } @@ -1378,6 +1412,12 @@ ha_rename (call_frame_t *frame, } local = frame->local; local->stub = fop_rename_stub (frame, ha_rename, oldloc, newloc); + if (!local->stub) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + STACK_WIND_COOKIE (frame, ha_rename_cbk, (void *)(long)local->active, @@ -1386,7 +1426,7 @@ ha_rename (call_frame_t *frame, oldloc, newloc); return 0; err: - STACK_UNWIND (frame, -1, op_errno, NULL); + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } @@ -1397,8 +1437,9 @@ ha_link_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - dict_t *dict) + struct iatt *buf, + dict_t *dict, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1434,12 +1475,12 @@ ha_link_lookup_cbk (call_frame_t *frame, if (cnt == 0) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); STACK_UNWIND (frame, local->op_ret, local->op_errno, - local->stub->args.link.oldloc.inode, - &local->buf); + local->stub->args.link.oldloc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); } return 0; @@ -1452,7 +1493,9 @@ ha_link_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1485,6 +1528,8 @@ ha_link_cbk (call_frame_t *frame, local->op_ret = 0; local->first_success = 1; local->buf = *buf; + local->preparent = *preparent; + local->postparent = *postparent; } cnt = --local->call_count; for (i = local->active + 1; i < child_count; i++) { @@ -1494,9 +1539,11 @@ ha_link_cbk (call_frame_t *frame, if (cnt == 0 || i == child_count) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); stub = local->stub; - STACK_UNWIND (frame, local->op_ret, local->op_errno, local->stub->args.link.oldloc.inode, &local->buf); + STACK_UNWIND (frame, local->op_ret, local->op_errno, + local->stub->args.link.oldloc.inode, &local->buf, + &local->preparent, &local->postparent); call_stub_destroy (stub); return 0; } @@ -1539,7 +1586,7 @@ ha_link (call_frame_t *frame, ha_private_t *pvt = NULL; int child_count = 0, i = 0; char *stateino = NULL; - int32_t ret = 0; + int32_t ret = 0, op_errno = 0; uint64_t tmp_stateino = 0; ret = inode_ctx_get (newloc->inode, this, &tmp_stateino); @@ -1551,7 +1598,8 @@ ha_link (call_frame_t *frame, if (stateino == NULL) { gf_log (this->name, GF_LOG_ERROR, "newloc->inode's ctx is NULL, returning EINVAL"); - STACK_UNWIND (frame, -1, EINVAL, oldloc->inode, NULL); + STACK_UNWIND (frame, -1, EINVAL, oldloc->inode, NULL, NULL, + NULL); return 0; } @@ -1559,11 +1607,30 @@ ha_link (call_frame_t *frame, pvt = this->private; child_count = pvt->child_count; - frame->local = local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!frame->local) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + local->stub = fop_link_stub (frame, ha_link, oldloc, newloc); + if (!local->stub) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + local->op_ret = -1; local->op_errno = ENOTCONN; - local->state = CALLOC (1, child_count); + local->state = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!local->state) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + memcpy (local->state, pvt->state, child_count); local->active = -1; @@ -1582,6 +1649,11 @@ ha_link (call_frame_t *frame, oldloc, newloc); return 0; +err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL); + return 0; } int32_t @@ -1592,7 +1664,9 @@ ha_create_cbk (call_frame_t *frame, int32_t op_errno, fd_t *fd, inode_t *inode, - struct stat *buf) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1640,6 +1714,8 @@ ha_create_cbk (call_frame_t *frame, if (local->op_ret == -1) { local->op_ret = 0; local->buf = *buf; + local->preparent = *preparent; + local->postparent = *postparent; local->first_success = 1; } local->stub->args.create.flags &= (~O_EXCL); @@ -1658,8 +1734,9 @@ ha_create_cbk (call_frame_t *frame, call_stub_t *stub = local->stub; STACK_UNWIND (frame, local->op_ret, local->op_errno, stub->args.create.fd, - stub->args.create.loc.inode, &local->buf); - FREE (state); + stub->args.create.loc.inode, &local->buf, + &local->preparent, &local->postparent); + GF_FREE (state); call_stub_destroy (stub); return 0; } @@ -1695,6 +1772,7 @@ ha_create (call_frame_t *frame, char *stateino = NULL; xlator_t **children = NULL; hafd_t *hafdp = NULL; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; @@ -1702,9 +1780,28 @@ ha_create (call_frame_t *frame, children = pvt->children; if (local == NULL) { - local = frame->local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->stub = fop_create_stub (frame, ha_create, loc, flags, mode, fd); - local->state = CALLOC (1, child_count); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + local->state = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!local->state) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->active = -1; local->op_ret = -1; local->op_errno = ENOTCONN; @@ -1718,10 +1815,34 @@ ha_create (call_frame_t *frame, } } /* FIXME handle active -1 */ - stateino = CALLOC (1, child_count); - hafdp = CALLOC (1, sizeof (*hafdp)); - hafdp->fdstate = CALLOC (1, child_count); - hafdp->path = strdup(loc->path); + stateino = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!stateino) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp = GF_CALLOC (1, sizeof (*hafdp), gf_ha_mt_hafd_t); + if (!hafdp) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp->fdstate = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!hafdp->fdstate) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp->path = gf_strdup(loc->path); + if (!hafdp->path) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + LOCK_INIT (&hafdp->lock); fd_ctx_set (fd, this, (uint64_t)(long)hafdp); inode_ctx_put (loc->inode, this, (uint64_t)(long)stateino); @@ -1733,6 +1854,26 @@ ha_create (call_frame_t *frame, children[local->active]->fops->create, loc, flags, mode, fd); return 0; +err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); + ha_local_wipe (local); + + if (stateino) { + GF_FREE (stateino); + stateino = NULL; + } + + if (hafdp) { + GF_FREE (hafdp->fdstate); + + GF_FREE (hafdp->path); + + GF_FREE (hafdp); + } + + return 0; } int32_t @@ -1789,7 +1930,7 @@ int32_t ha_open (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flags, fd_t *fd) + int32_t flags, fd_t *fd, int wbflags) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1798,6 +1939,7 @@ ha_open (call_frame_t *frame, int cnt = 0, i, child_count = 0, ret = 0; hafd_t *hafdp = NULL; uint64_t tmp_stateino = 0; + int32_t op_errno = ENOMEM; local = frame->local; pvt = this->private; @@ -1805,14 +1947,39 @@ ha_open (call_frame_t *frame, child_count = pvt->child_count; - local = frame->local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->op_ret = -1; local->op_errno = ENOTCONN; local->fd = fd; - hafdp = CALLOC (1, sizeof (*hafdp)); - hafdp->fdstate = CALLOC (1, child_count); - hafdp->path = strdup (loc->path); + hafdp = GF_CALLOC (1, sizeof (*hafdp), gf_ha_mt_hafd_t); + if (!hafdp) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp->fdstate = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!hafdp->fdstate) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp->path = gf_strdup (loc->path); + if (!hafdp->path) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + hafdp->active = -1; if (pvt->pref_subvol == -1) { hafdp->active = fd->inode->ino % child_count; @@ -1833,12 +2000,33 @@ ha_open (call_frame_t *frame, ha_open_cbk, children[i], children[i]->fops->open, - loc, flags, fd); + loc, flags, fd, wbflags); if (--cnt == 0) break; } } return 0; +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, fd); + if (hafdp) { + if (hafdp->fdstate) { + GF_FREE (hafdp->fdstate); + hafdp->fdstate = NULL; + } + + if (hafdp->path) { + GF_FREE (hafdp->path); + hafdp->path = NULL; + } + + GF_FREE (hafdp); + } + + ha_local_wipe (local); + return 0; } int32_t @@ -1849,7 +2037,7 @@ ha_readv_cbk (call_frame_t *frame, int32_t op_errno, struct iovec *vector, int32_t count, - struct stat *stbuf, + struct iatt *stbuf, struct iobref *iobref) { int ret = 0; @@ -1885,6 +2073,11 @@ ha_readv (call_frame_t *frame, } local = frame->local; local->stub = fop_readv_stub (frame, ha_readv, fd, size, offset); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_readv_cbk, @@ -1896,7 +2089,12 @@ ha_readv (call_frame_t *frame, offset); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, 0, NULL, NULL); + + ha_local_wipe (local); return 0; } @@ -1906,7 +2104,8 @@ ha_writev_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *stbuf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = 0; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); @@ -1915,7 +2114,8 @@ ha_writev_cbk (call_frame_t *frame, STACK_UNWIND (frame, op_ret, op_errno, - stbuf); + prebuf, + postbuf); } return 0; } @@ -1938,7 +2138,13 @@ ha_writev (call_frame_t *frame, goto err; } local = frame->local; - local->stub = fop_writev_stub (frame, ha_writev, fd, vector, count, off, iobref); + local->stub = fop_writev_stub (frame, ha_writev, fd, vector, count, off, + iobref); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_writev_cbk, @@ -1952,7 +2158,12 @@ ha_writev (call_frame_t *frame, iobref); return 0; err: - STACK_UNWIND (frame, -1, op_errno, NULL); + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); + + ha_local_wipe (local); return 0; } @@ -1989,6 +2200,12 @@ ha_flush (call_frame_t *frame, } local = frame->local; local->stub = fop_flush_stub (frame, ha_flush, fd); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + STACK_WIND_COOKIE (frame, ha_flush_cbk, (void *)(long)local->active, @@ -1997,7 +2214,12 @@ ha_flush (call_frame_t *frame, fd); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno); + + ha_local_wipe (local); return 0; } @@ -2007,7 +2229,9 @@ ha_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, - int32_t op_errno) + int32_t op_errno, + struct iatt *prebuf, + struct iatt *postbuf) { int ret = 0; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); @@ -2036,6 +2260,12 @@ ha_fsync (call_frame_t *frame, } local = frame->local; local->stub = fop_fsync_stub (frame, ha_fsync, fd, flags); + if (!local->stub) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + op_errno = ENOMEM; + goto err; + } + STACK_WIND_COOKIE (frame, ha_fsync_cbk, (void *)(long)local->active, @@ -2045,7 +2275,12 @@ ha_fsync (call_frame_t *frame, flags); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno); + + ha_local_wipe (local); return 0; } @@ -2055,7 +2290,7 @@ ha_fstat_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf) + struct iatt *buf) { int ret = 0; @@ -2086,6 +2321,12 @@ ha_fstat (call_frame_t *frame, } local = frame->local; local->stub = fop_fstat_stub (frame, ha_fstat, fd); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + STACK_WIND_COOKIE (frame, ha_fstat_cbk, (void *)(long)local->active, @@ -2094,7 +2335,12 @@ ha_fstat (call_frame_t *frame, fd); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL); + + ha_local_wipe (local); return 0; } @@ -2160,20 +2406,46 @@ ha_opendir (call_frame_t *frame, int cnt = 0, i, child_count = 0, ret = 0; hafd_t *hafdp = NULL; uint64_t tmp_stateino = 0; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; children = pvt->children; child_count = pvt->child_count; - local = frame->local = CALLOC (1, sizeof (*local)); + frame->local = local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->op_ret = -1; local->op_errno = ENOTCONN; local->fd = fd; - hafdp = CALLOC (1, sizeof (*hafdp)); - hafdp->fdstate = CALLOC (1, child_count); - hafdp->path = strdup (loc->path); + hafdp = GF_CALLOC (1, sizeof (*hafdp), gf_ha_mt_hafd_t); + if (!hafdp) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp->fdstate = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!hafdp->fdstate) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + hafdp->path = gf_strdup (loc->path); + if (!hafdp->path) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + LOCK_INIT (&hafdp->lock); fd_ctx_set (fd, this, (uint64_t)(long)hafdp); ret = inode_ctx_get (loc->inode, this, &tmp_stateino); @@ -2198,6 +2470,26 @@ ha_opendir (call_frame_t *frame, } } return 0; +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, NULL); + ha_local_wipe (local); + if (hafdp) { + if (hafdp->fdstate) { + GF_FREE (hafdp->fdstate); + hafdp->fdstate = NULL; + } + + if (hafdp->path) { + GF_FREE (hafdp->path); + hafdp->path = NULL; + } + + GF_FREE (hafdp); + } + return 0; } int32_t @@ -2239,7 +2531,14 @@ ha_getdents (call_frame_t *frame, goto err; } local = frame->local; - local->stub = fop_getdents_stub (frame, ha_getdents, fd, size, offset, flag); + local->stub = fop_getdents_stub (frame, ha_getdents, fd, size, offset, + flag); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + STACK_WIND_COOKIE (frame, ha_getdents_cbk, (void *)(long)local->active, @@ -2251,7 +2550,12 @@ ha_getdents (call_frame_t *frame, flag); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, 0); + + ha_local_wipe (local); return 0; } @@ -2292,7 +2596,13 @@ ha_setdents (call_frame_t *frame, } local = frame->local; - local->stub = fop_setdents_stub (frame, ha_setdents, fd, flags, entries, count); + local->stub = fop_setdents_stub (frame, ha_setdents, fd, flags, entries, + count); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_setdents_cbk, @@ -2305,7 +2615,12 @@ ha_setdents (call_frame_t *frame, count); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno); + + ha_local_wipe (local); return 0; } @@ -2343,6 +2658,12 @@ ha_fsyncdir (call_frame_t *frame, } local = frame->local; local->stub = fop_fsyncdir_stub (frame, ha_fsyncdir, fd, flags); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + STACK_WIND_COOKIE (frame, ha_fsyncdir_cbk, (void *)(long)local->active, @@ -2352,7 +2673,12 @@ ha_fsyncdir (call_frame_t *frame, flags); return 0; err: - STACK_UNWIND (frame, -1, op_errno); + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); + + ha_local_wipe (local); return 0; } @@ -2365,15 +2691,27 @@ ha_statfs_cbk (call_frame_t *frame, int32_t op_errno, struct statvfs *buf) { - int ret = -1; + ha_local_t *local = NULL; + ha_private_t *priv = NULL; - ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); - if (ret == 0) { - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - } + 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 +2720,29 @@ 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 = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + 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); @@ -2441,6 +2785,12 @@ ha_setxattr (call_frame_t *frame, } local = frame->local; local->stub = fop_setxattr_stub (frame, ha_setxattr, loc, dict, flags); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + STACK_WIND_COOKIE (frame, ha_setxattr_cbk, (void *)(long)local->active, @@ -2451,7 +2801,12 @@ ha_setxattr (call_frame_t *frame, flags); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno); + + ha_local_wipe (local); return 0; } @@ -2492,6 +2847,12 @@ ha_getxattr (call_frame_t *frame, } local = frame->local; local->stub = fop_getxattr_stub (frame, ha_getxattr, loc, name); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + STACK_WIND_COOKIE (frame, ha_getxattr_cbk, (void *)(long)local->active, @@ -2501,7 +2862,12 @@ ha_getxattr (call_frame_t *frame, name); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL); + + ha_local_wipe (local); return 0; } @@ -2540,6 +2906,11 @@ ha_xattrop (call_frame_t *frame, local = frame->local; local->stub = fop_xattrop_stub (frame, ha_xattrop, loc, flags, dict); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_xattrop_cbk, @@ -2551,7 +2922,12 @@ ha_xattrop (call_frame_t *frame, dict); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, dict); + + ha_local_wipe (local); return 0; } @@ -2587,6 +2963,11 @@ ha_fxattrop (call_frame_t *frame, } local = frame->local; local->stub = fop_fxattrop_stub (frame, ha_fxattrop, fd, flags, dict); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_fxattrop_cbk, @@ -2598,7 +2979,12 @@ ha_fxattrop (call_frame_t *frame, dict); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, dict); + + ha_local_wipe (local); return 0; } @@ -2636,6 +3022,11 @@ ha_removexattr (call_frame_t *frame, local = frame->local; local->stub = fop_removexattr_stub (frame, ha_removexattr, loc, name); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_removexattr_cbk, @@ -2646,7 +3037,12 @@ ha_removexattr (call_frame_t *frame, name); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno); + + ha_local_wipe (local); return 0; } @@ -2656,7 +3052,7 @@ ha_lk_setlk_unlck_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct flock *lock) + struct gf_flock *lock) { ha_local_t *local = NULL; int cnt = 0; @@ -2672,7 +3068,7 @@ ha_lk_setlk_unlck_cbk (call_frame_t *frame, if (cnt == 0) { stub = local->stub; - FREE (local->state); + GF_FREE (local->state); if (stub->args.lk.lock.l_type == F_UNLCK) { STACK_UNWIND (frame, local->op_ret, local->op_errno, &stub->args.lk.lock); } else { @@ -2689,7 +3085,7 @@ ha_lk_setlk_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct flock *lock) + struct gf_flock *lock) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -2721,7 +3117,7 @@ ha_lk_setlk_cbk (call_frame_t *frame, } if (i == child_count) { call_stub_t *stub = local->stub; - FREE (local->state); + GF_FREE (local->state); STACK_UNWIND (frame, 0, op_errno, &stub->args.lk.lock); call_stub_destroy (stub); return 0; @@ -2745,7 +3141,7 @@ ha_lk_setlk_cbk (call_frame_t *frame, cnt++; } if (cnt) { - struct flock lock; + struct gf_flock lock; lock = local->stub->args.lk.lock; for (i = 0; i < child_count; i++) { if (state[i]) { @@ -2762,7 +3158,7 @@ ha_lk_setlk_cbk (call_frame_t *frame, } return 0; } else { - FREE (local->state); + GF_FREE (local->state); call_stub_destroy (local->stub); STACK_UNWIND (frame, op_ret, @@ -2779,7 +3175,7 @@ ha_lk_getlk_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct flock *lock) + struct gf_flock *lock) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -2796,7 +3192,7 @@ ha_lk_getlk_cbk (call_frame_t *frame, prev_frame = cookie; if (op_ret == 0) { - FREE (local->state); + GF_FREE (local->state); call_stub_destroy (local->stub); STACK_UNWIND (frame, 0, 0, lock); return 0; @@ -2813,7 +3209,7 @@ ha_lk_getlk_cbk (call_frame_t *frame, } if (i == child_count) { - FREE (local->state); + GF_FREE (local->state); call_stub_destroy (local->stub); STACK_UNWIND (frame, op_ret, op_errno, lock); return 0; @@ -2834,7 +3230,7 @@ ha_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, - struct flock *lock) + struct gf_flock *lock) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -2843,6 +3239,7 @@ ha_lk (call_frame_t *frame, int child_count = 0, i = 0, cnt = 0, ret = 0; xlator_t **children = NULL; uint64_t tmp_hafdp = 0; + int32_t op_errno = EINVAL; local = frame->local; pvt = this->private; @@ -2853,7 +3250,14 @@ ha_lk (call_frame_t *frame, gf_log (this->name, GF_LOG_ERROR, "fd_ctx_get failed"); if (local == NULL) { - local = frame->local = CALLOC (1, sizeof (*local)); + local = frame->local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + local->active = -1; local->op_ret = -1; local->op_errno = ENOTCONN; @@ -2861,12 +3265,24 @@ ha_lk (call_frame_t *frame, hafdp = (hafd_t *)(long)tmp_hafdp; if (local->active == -1) { - STACK_UNWIND (frame, -1, ENOTCONN, NULL); - return 0; + op_errno = ENOTCONN; + goto err; } local->stub = fop_lk_stub (frame, ha_lk, fd, cmd, lock); - local->state = CALLOC (1, child_count); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + local->state = GF_CALLOC (1, child_count, gf_ha_mt_char); + if (!local->state) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + state = hafdp->fdstate; LOCK (&hafdp->lock); memcpy (local->state, state, child_count); @@ -2914,6 +3330,14 @@ ha_lk (call_frame_t *frame, lock); } return 0; +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, op_errno, NULL); + + ha_local_wipe (local); + return 0; } int32_t @@ -2940,7 +3364,7 @@ ha_inodelk (call_frame_t *frame, const char *volume, loc_t *loc, int32_t cmd, - struct flock *lock) + struct gf_flock *lock) { ha_local_t *local = NULL; int op_errno = 0; @@ -3038,6 +3462,11 @@ ha_checksum (call_frame_t *frame, } local = frame->local; local->stub = fop_checksum_stub (frame, ha_checksum, loc, flag); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } STACK_WIND_COOKIE (frame, ha_checksum_cbk, @@ -3048,17 +3477,18 @@ ha_checksum (call_frame_t *frame, flag); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, op_errno, NULL, NULL); + + ha_local_wipe (local); return 0; } int32_t -ha_readdir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - gf_dirent_t *entries) +ha_common_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) { int ret = 0; @@ -3069,11 +3499,15 @@ ha_readdir_cbk (call_frame_t *frame, } int32_t -ha_readdir (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - size_t size, - off_t off) +ha_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off); + +int32_t +ha_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off); +int32_t +ha_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, int whichop) { ha_local_t *local = NULL; int op_errno = 0; @@ -3084,19 +3518,58 @@ ha_readdir (call_frame_t *frame, goto err; } local = frame->local; - local->stub = fop_readdir_stub (frame, ha_readdir, fd, size, off); - STACK_WIND_COOKIE (frame, - ha_readdir_cbk, - (void *)(long)local->active, - HA_ACTIVE_CHILD(this, local), - HA_ACTIVE_CHILD(this, local)->fops->readdir, - fd, size, off); + if (whichop == GF_FOP_READDIR) + local->stub = fop_readdir_stub (frame, ha_readdir, fd, size, + off); + else + local->stub = fop_readdirp_stub (frame, ha_readdirp, fd, size, + off); + if (!local->stub) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } + + if (whichop == GF_FOP_READDIR) + STACK_WIND_COOKIE (frame, ha_common_readdir_cbk, + (void *)(long)local->active, + HA_ACTIVE_CHILD(this, local), + HA_ACTIVE_CHILD(this, local)->fops->readdir, + fd, size, off); + else + STACK_WIND_COOKIE (frame, ha_common_readdir_cbk, + (void *)(long)local->active, + HA_ACTIVE_CHILD(this, local), + HA_ACTIVE_CHILD(this, local)->fops->readdirp, + fd, size, off); return 0; err: + local = frame->local; + frame->local = NULL; + STACK_UNWIND (frame, -1, ENOTCONN, NULL); + + ha_local_wipe (local); return 0; } + +int32_t +ha_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off) +{ + ha_do_readdir (frame, this, fd, size, off, GF_FOP_READDIR); + return 0; +} + +int32_t +ha_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off) +{ + ha_do_readdir (frame, this, fd, size, off, GF_FOP_READDIRP); + return 0; +} + /* Management operations */ int32_t @@ -3157,8 +3630,16 @@ ha_stats (call_frame_t *frame, ha_private_t *pvt = NULL; xlator_t **children = NULL; int i = 0; + int32_t op_errno = EINVAL; + + local = frame->local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } - local = frame->local = CALLOC (1, sizeof (*local)); pvt = this->private; children = pvt->children; for (i = 0; i < pvt->child_count; i++) { @@ -3167,8 +3648,8 @@ ha_stats (call_frame_t *frame, } if (i == pvt->child_count) { - STACK_UNWIND (frame, -1, ENOTCONN, NULL); - return 0; + op_errno = ENOTCONN; + goto err; } local->flags = flags; @@ -3178,6 +3659,16 @@ ha_stats (call_frame_t *frame, children[i]->mops->stats, flags); return 0; + +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, ENOTCONN, NULL); + + ha_local_wipe (local); + return 0; + } @@ -3241,20 +3732,27 @@ ha_getspec (call_frame_t *frame, ha_private_t *pvt = NULL; xlator_t **children = NULL; int i = 0; + int32_t op_errno = EINVAL; + + local = frame->local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); + if (!local) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto err; + } - local = frame->local = CALLOC (1, sizeof (*local)); pvt = this->private; children = pvt->children; - local = frame->local = CALLOC (1, sizeof (*local)); for (i = 0; i < pvt->child_count; i++) { if (pvt->state[i]) break; } if (i == pvt->child_count) { - STACK_UNWIND (frame, -1, ENOTCONN, NULL); - return 0; + op_errno = ENOTCONN; + goto err; } local->flags = flags; local->pattern = (char *)key; @@ -3265,6 +3763,15 @@ ha_getspec (call_frame_t *frame, children[i]->mops->getspec, key, flags); return 0; +err: + local = frame->local; + frame->local = NULL; + + STACK_UNWIND (frame, -1, ENOTCONN, NULL); + + ha_local_wipe (local); + return 0; + } int32_t @@ -3282,8 +3789,8 @@ ha_closedir (xlator_t *this, } hafdp = (hafd_t *)(long)tmp_hafdp; - FREE (hafdp->fdstate); - FREE (hafdp->path); + GF_FREE (hafdp->fdstate); + GF_FREE (hafdp->path); LOCK_DESTROY (&hafdp->lock); return 0; } @@ -3303,8 +3810,8 @@ ha_close (xlator_t *this, } hafdp = (hafd_t *)(long)tmp_hafdp; - FREE (hafdp->fdstate); - FREE (hafdp->path); + GF_FREE (hafdp->fdstate); + GF_FREE (hafdp->path); LOCK_DESTROY (&hafdp->lock); return 0; } @@ -3375,6 +3882,25 @@ notify (xlator_t *this, return 0; } +int32_t +mem_acct_init (xlator_t *this) +{ + int ret = -1; + + if (!this) + return ret; + + ret = xlator_mem_acct_init (this, gf_ha_mt_end + 1); + + if (ret != 0) { + gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" + "failed"); + return ret; + } + + return ret; +} + int init (xlator_t *this) { @@ -3382,6 +3908,7 @@ init (xlator_t *this) xlator_list_t *trav = NULL; int count = 0, ret = 0; + if (!this->children) { gf_log (this->name,GF_LOG_ERROR, "FATAL: ha should have one or more child defined"); @@ -3394,7 +3921,7 @@ init (xlator_t *this) } trav = this->children; - pvt = CALLOC (1, sizeof (ha_private_t)); + pvt = GF_CALLOC (1, sizeof (ha_private_t), gf_ha_mt_ha_private_t); ret = dict_get_int32 (this->options, "preferred-subvolume", &pvt->pref_subvol); @@ -3409,7 +3936,8 @@ init (xlator_t *this) } pvt->child_count = count; - pvt->children = CALLOC (count, sizeof (xlator_t*)); + pvt->children = GF_CALLOC (count, sizeof (xlator_t*), + gf_ha_mt_xlator_t); trav = this->children; count = 0; @@ -3419,7 +3947,7 @@ init (xlator_t *this) trav = trav->next; } - pvt->state = CALLOC (1, count); + pvt->state = GF_CALLOC (1, count, gf_ha_mt_char); this->private = pvt; return 0; } @@ -3429,7 +3957,7 @@ fini (xlator_t *this) { ha_private_t *priv = NULL; priv = this->private; - FREE (priv); + GF_FREE (priv); return; } @@ -3445,10 +3973,7 @@ struct xlator_fops fops = { .symlink = ha_symlink, .rename = ha_rename, .link = ha_link, - .chmod = ha_chmod, - .chown = ha_chown, .truncate = ha_truncate, - .utimens = ha_utimens, .create = ha_create, .open = ha_open, .readv = ha_readv, @@ -3461,24 +3986,20 @@ struct xlator_fops fops = { .removexattr = ha_removexattr, .opendir = ha_opendir, .readdir = ha_readdir, + .readdirp = ha_readdirp, .getdents = ha_getdents, .fsyncdir = ha_fsyncdir, .access = ha_access, .ftruncate = ha_ftruncate, .fstat = ha_fstat, .lk = ha_lk, - .fchmod = ha_fchmod, - .fchown = ha_fchown, .setdents = ha_setdents, .lookup_cbk = ha_lookup_cbk, .checksum = ha_checksum, .xattrop = ha_xattrop, - .fxattrop = ha_fxattrop -}; - -struct xlator_mops mops = { - .stats = ha_stats, - .getspec = ha_getspec, + .fxattrop = ha_fxattrop, + .setattr = ha_setattr, + .fsetattr = ha_fsetattr, }; struct xlator_cbks cbks = { |
