diff options
Diffstat (limited to 'xlators/cluster/ha/src')
| -rw-r--r-- | xlators/cluster/ha/src/Makefile.am | 7 | ||||
| -rw-r--r-- | xlators/cluster/ha/src/ha-helpers.c | 43 | ||||
| -rw-r--r-- | xlators/cluster/ha/src/ha-mem-types.h | 26 | ||||
| -rw-r--r-- | xlators/cluster/ha/src/ha.c | 1036 | ||||
| -rw-r--r-- | xlators/cluster/ha/src/ha.h | 30 |
5 files changed, 912 insertions, 230 deletions
diff --git a/xlators/cluster/ha/src/Makefile.am b/xlators/cluster/ha/src/Makefile.am index 5f78a2965..5c1364b7f 100644 --- a/xlators/cluster/ha/src/Makefile.am +++ b/xlators/cluster/ha/src/Makefile.am @@ -1,15 +1,16 @@ xlator_LTLIBRARIES = ha.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/cluster -ha_la_LDFLAGS = -module -avoidversion +ha_la_LDFLAGS = -module -avoid-version ha_la_SOURCES = ha-helpers.c ha.c ha_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = ha.h -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = diff --git a/xlators/cluster/ha/src/ha-helpers.c b/xlators/cluster/ha/src/ha-helpers.c index 4bc7d5e20..19be1ed27 100644 --- a/xlators/cluster/ha/src/ha-helpers.c +++ b/xlators/cluster/ha/src/ha-helpers.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. +*/ #include "xlator.h" #include "call-stub.h" #include "defaults.h" @@ -49,12 +39,14 @@ int ha_alloc_init_fd (call_frame_t *frame, fd_t *fd) goto out; } hafdp = (hafd_t *)(long)tmp_hafdp; - local = frame->local = CALLOC (1, sizeof (*local)); + local = frame->local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); if (local == NULL) { ret = -ENOMEM; goto out; } - local->state = CALLOC (1, child_count); + local->state = GF_CALLOC (1, child_count, + gf_ha_mt_child_count); if (local->state == NULL) { ret = -ENOMEM; goto out; @@ -141,11 +133,17 @@ int ha_handle_cbk (call_frame_t *frame, void *cookie, int op_ret, int op_errno) } } } - if (local->stub) + if (local->stub) { call_stub_destroy (local->stub); + local->stub = NULL; + } + if (local->fd) { - FREE (local->state); + GF_FREE (local->state); + local->state = NULL; + fd_unref (local->fd); + local->fd = NULL; } return 0; } @@ -164,7 +162,8 @@ int ha_alloc_init_inode (call_frame_t *frame, inode_t *inode) local = frame->local; 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 == NULL) { ret = -ENOMEM; goto out; diff --git a/xlators/cluster/ha/src/ha-mem-types.h b/xlators/cluster/ha/src/ha-mem-types.h new file mode 100644 index 000000000..e5e97d237 --- /dev/null +++ b/xlators/cluster/ha/src/ha-mem-types.h @@ -0,0 +1,26 @@ +/* + 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. +*/ + +#ifndef __HA_MEM_TYPES_H__ +#define __HA_MEM_TYPES_H__ + +#include "mem-types.h" + +enum gf_ha_mem_types_ { + gf_ha_mt_ha_local_t = gf_common_mt_end + 1, + gf_ha_mt_hafd_t, + gf_ha_mt_char, + gf_ha_mt_child_count, + gf_ha_mt_xlator_t, + gf_ha_mt_ha_private_t, + gf_ha_mt_end +}; +#endif + diff --git a/xlators/cluster/ha/src/ha.c b/xlators/cluster/ha/src/ha.c index b2ca48b10..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,9 +88,9 @@ ha_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, + struct iatt *buf, dict_t *dict, - struct stat *postparent) + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -107,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); } @@ -128,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) @@ -149,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; @@ -179,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 @@ -187,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; @@ -232,8 +281,8 @@ err: int32_t ha_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *statpre, - struct stat *statpost) + int32_t op_ret, int32_t op_errno, struct iatt *statpre, + struct iatt *statpost) { int ret = -1; @@ -247,7 +296,7 @@ ha_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t -ha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct stat *stbuf, +ha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid) { ha_local_t *local = NULL; @@ -275,7 +324,7 @@ err: int32_t -ha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct stat *stbuf, +ha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid) { ha_local_t *local = NULL; @@ -308,8 +357,8 @@ ha_truncate_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *prebuf, - struct stat *postbuf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = -1; @@ -340,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, @@ -350,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; } @@ -360,8 +414,8 @@ ha_ftruncate_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *prebuf, - struct stat *postbuf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = -1; @@ -392,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, @@ -402,7 +461,12 @@ ha_ftruncate (call_frame_t *frame, offset); 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; } @@ -441,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, @@ -451,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; } @@ -463,7 +537,7 @@ ha_readlink_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, const char *path, - struct stat *sbuf) + struct iatt *sbuf) { int ret = -1; @@ -505,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; } @@ -516,9 +590,9 @@ ha_mknod_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, + struct iatt *buf, dict_t *dict, - struct stat *postparent) + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -562,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; @@ -580,9 +655,9 @@ ha_mknod_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - struct stat *preparent, - struct stat *postparent) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -620,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++) { @@ -629,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; } @@ -676,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++) { @@ -706,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; } @@ -716,9 +829,9 @@ ha_mkdir_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, + struct iatt *buf, dict_t *dict, - struct stat *postparent) + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -754,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; @@ -772,9 +885,9 @@ ha_mkdir_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - struct stat *preparent, - struct stat *postparent) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -808,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++) { @@ -817,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; } @@ -862,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]) { @@ -891,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 @@ -899,14 +1049,14 @@ ha_unlink_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *preparent, - struct stat *postparent) + 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; } @@ -927,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, @@ -936,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; } @@ -946,8 +1101,8 @@ ha_rmdir_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *preparent, - struct stat *postparent) + struct iatt *preparent, + struct iatt *postparent) { int ret = -1; @@ -956,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; } @@ -976,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, @@ -985,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; } @@ -997,9 +1159,9 @@ ha_symlink_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, + struct iatt *buf, dict_t *dict, - struct stat *postparent) + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1035,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; @@ -1053,9 +1215,9 @@ ha_symlink_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - struct stat *preparent, - struct stat *postparent) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1088,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++) { @@ -1097,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; } @@ -1143,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++) { @@ -1174,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 @@ -1182,18 +1379,19 @@ ha_rename_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf, - struct stat *preoldparent, - struct stat *postoldparent, - struct stat *prenewparent, - struct stat *postnewparent) + 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; } @@ -1214,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, @@ -1222,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; } @@ -1233,9 +1437,9 @@ ha_link_lookup_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, + struct iatt *buf, dict_t *dict, - struct stat *postparent) + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1271,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; @@ -1289,9 +1493,9 @@ ha_link_cbk (call_frame_t *frame, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, - struct stat *preparent, - struct stat *postparent) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1324,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++) { @@ -1333,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; } @@ -1378,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); @@ -1390,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; } @@ -1398,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; @@ -1421,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 @@ -1431,9 +1664,9 @@ ha_create_cbk (call_frame_t *frame, int32_t op_errno, fd_t *fd, inode_t *inode, - struct stat *buf, - struct stat *preparent, - struct stat *postparent) + struct iatt *buf, + struct iatt *preparent, + struct iatt *postparent) { ha_local_t *local = NULL; ha_private_t *pvt = NULL; @@ -1481,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); @@ -1499,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; } @@ -1536,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; @@ -1543,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; @@ -1559,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); @@ -1574,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 @@ -1639,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; @@ -1646,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; @@ -1680,6 +2006,27 @@ ha_open (call_frame_t *frame, } } 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 @@ -1690,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; @@ -1726,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, @@ -1737,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; } @@ -1747,8 +2104,8 @@ ha_writev_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *prebuf, - struct stat *postbuf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = 0; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); @@ -1781,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, @@ -1795,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; } @@ -1832,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, @@ -1840,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; } @@ -1851,8 +2230,8 @@ ha_fsync_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *prebuf, - struct stat *postbuf) + struct iatt *prebuf, + struct iatt *postbuf) { int ret = 0; ret = ha_handle_cbk (frame, cookie, op_ret, op_errno); @@ -1881,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, @@ -1890,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; } @@ -1900,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; @@ -1931,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, @@ -1939,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; } @@ -2005,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); @@ -2043,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 @@ -2084,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, @@ -2096,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; } @@ -2137,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, @@ -2150,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; } @@ -2188,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, @@ -2197,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; } @@ -2246,7 +2727,8 @@ ha_statfs (call_frame_t *frame, /* The normal way of handling failover doesn't work here * as loc->inode may be null in this case. */ - local = CALLOC (1, sizeof (*local)); + local = GF_CALLOC (1, sizeof (*local), + gf_ha_mt_ha_local_t); if (!local) { op_errno = ENOMEM; goto err; @@ -2303,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, @@ -2313,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; } @@ -2354,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, @@ -2363,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; } @@ -2402,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, @@ -2413,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; } @@ -2449,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, @@ -2460,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; } @@ -2498,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, @@ -2508,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; } @@ -2518,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; @@ -2534,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 { @@ -2551,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; @@ -2583,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; @@ -2607,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]) { @@ -2624,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, @@ -2641,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; @@ -2658,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; @@ -2675,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; @@ -2696,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; @@ -2705,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; @@ -2715,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; @@ -2723,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); @@ -2776,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 @@ -2802,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; @@ -2900,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, @@ -2910,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; @@ -2931,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; @@ -2946,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 @@ -3019,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++) { @@ -3029,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; @@ -3040,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; + } @@ -3103,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; @@ -3127,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 @@ -3144,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; } @@ -3165,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; } @@ -3237,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) { @@ -3244,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"); @@ -3256,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); @@ -3271,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; @@ -3281,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; } @@ -3291,7 +3957,7 @@ fini (xlator_t *this) { ha_private_t *priv = NULL; priv = this->private; - FREE (priv); + GF_FREE (priv); return; } @@ -3320,6 +3986,7 @@ 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, @@ -3335,11 +4002,6 @@ struct xlator_fops fops = { .fsetattr = ha_fsetattr, }; -struct xlator_mops mops = { - .stats = ha_stats, - .getspec = ha_getspec, -}; - struct xlator_cbks cbks = { .release = ha_close, .releasedir = ha_closedir, diff --git a/xlators/cluster/ha/src/ha.h b/xlators/cluster/ha/src/ha.h index d47d96535..e2ed7eaa6 100644 --- a/xlators/cluster/ha/src/ha.h +++ b/xlators/cluster/ha/src/ha.h @@ -1,25 +1,17 @@ /* - 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. +*/ #ifndef __HA_H_ #define __HA_H_ +#include "ha-mem-types.h" + typedef struct { call_stub_t *stub; int32_t op_ret, op_errno; @@ -28,7 +20,9 @@ typedef struct { char *state, *pattern; dict_t *dict; loc_t loc; - struct stat buf; + struct iatt buf; + struct iatt postparent; + struct iatt preparent; fd_t *fd; inode_t *inode; int32_t flags; |
