From 2bf35da812016c8adb05b0aa90c9f0b25e50a878 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Wed, 18 Nov 2009 01:19:37 +0000 Subject: libglusterfsclient: fix memory leak. - glusterfs_glh_getxattr was implemented using libgf_client_lookup. Hence the inode corresponding to the path on which getxattr was done was refed twice - one during path_lookup and the other in libgf_client_lookup - but unrefed only once. - with inode generation number changes the inode returned by inode_link may not be the same as the input argument. Hence the inode returned by inode_link should be used, not the one returned in libgf_client_lookup_cbk. Signed-off-by: Raghavendra G Signed-off-by: Anand V. Avati BUG: 369 (Samba does not work with booster.) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=369 --- libglusterfsclient/src/libglusterfsclient.c | 60 ++++++++--------------------- 1 file changed, 16 insertions(+), 44 deletions(-) (limited to 'libglusterfsclient') diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c index 3cc1d505f..a298bd332 100755 --- a/libglusterfsclient/src/libglusterfsclient.c +++ b/libglusterfsclient/src/libglusterfsclient.c @@ -2067,7 +2067,8 @@ libgf_client_lookup_cbk (call_frame_t *frame, parent = local->fop.lookup.loc->parent; libgf_transform_iattr (ctx, inode, buf); if (inode->ino != 1) { - inode_link (inode, parent, local->fop.lookup.loc->name, buf); + inode = inode_link (inode, parent, + local->fop.lookup.loc->name, buf); } inode_lookup (inode); @@ -2179,6 +2180,12 @@ libgf_client_lookup (libglusterfs_client_ctx_t *ctx, if (dict) *dict = dict_ref (stub->args.lookup_cbk.dict); + + if (inode != loc->inode) { + inode_unref (loc->inode); + loc->inode = inode_ref (inode); + } + out: call_stub_destroy (stub); return op_ret; @@ -2571,9 +2578,12 @@ libgf_client_getxattr (libglusterfs_client_ctx_t *ctx, /* Don't return the value for '\0' */ op_ret = value_data->len; - copy_len = size < value_data->len ? - size : value_data->len; - memcpy (value, value_data->data, copy_len); + if ((size > 0) && (value != NULL)) { + copy_len = size < value_data->len ? + size : value_data->len; + memcpy (value, value_data->data, copy_len); + op_ret = copy_len; + } } else { errno = ENODATA; op_ret = -1; @@ -2594,10 +2604,8 @@ __glusterfs_glh_getxattr (glusterfs_handle_t handle, const char *path, { int32_t op_ret = -1; loc_t loc = {0, }; - dict_t *dict = NULL; libglusterfs_client_ctx_t *ctx = handle; char *file = NULL; - dict_t *xattr_req = NULL; char *pathres = NULL, *tmp = NULL; GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); @@ -2645,21 +2653,13 @@ __glusterfs_glh_getxattr (glusterfs_handle_t handle, const char *path, goto out; } - xattr_req = dict_new (); - op_ret = dict_set (xattr_req, (char *)name, - data_from_uint64 (size)); - if (op_ret == -1) { - /* TODO: set proper error code */ - goto out; - } - if (whichop == LIBGF_DO_LGETXATTR) goto do_getx; if (!S_ISLNK (loc.inode->st_mode)) goto do_getx; - libgf_client_loc_wipe (&loc); + libgf_client_loc_wipe (&loc); op_ret = libgf_realpath_loc_fill (ctx, (char *)pathres, &loc); if (op_ret == -1) { gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "realpath failed"); @@ -2667,41 +2667,13 @@ __glusterfs_glh_getxattr (glusterfs_handle_t handle, const char *path, } do_getx: - op_ret = libgf_client_lookup (ctx, &loc, NULL, &dict, xattr_req); - if (op_ret == 0) { - data_t *value_data = dict_get (dict, (char *)name); - - if (value_data) { - int32_t copy_len = 0; - - /* Don't return the value for '\0' */ - op_ret = value_data->len; - - if ((size > 0) && (value != NULL)) { - copy_len = size < value_data->len ? - size : value_data->len; - memcpy (value, value_data->data, copy_len); - op_ret = copy_len; - } - } else { - errno = ENODATA; - op_ret = -1; - } - } + op_ret = libgf_client_getxattr (ctx, &loc, name, value, size); out: if (tmp) { FREE (tmp); } - if (xattr_req) { - dict_unref (xattr_req); - } - - if (dict) { - dict_unref (dict); - } - if (pathres) FREE (pathres); -- cgit