From e49e56c5e81e7e6a4cc4d0ac2982446dd1887ef9 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Wed, 19 Mar 2014 07:52:48 +0530 Subject: storage/posix: add list xattr capability to lookup BUG: 1078061 Change-Id: Ib84f40c84e2d66c86b1cec4a7cceb5aea189ba4a Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/7434 Tested-by: Gluster Build System Reviewed-by: Xavier Hernandez Reviewed-by: Ravishankar N Reviewed-by: Vijay Bellur --- xlators/storage/posix/src/posix-helpers.c | 92 +++++++++++++++++++++++++++---- xlators/storage/posix/src/posix.c | 19 ++++--- 2 files changed, 94 insertions(+), 17 deletions(-) (limited to 'xlators/storage/posix/src') diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 0e187e0200d..c04e06e3d6d 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -62,6 +62,12 @@ static char* posix_ignore_xattrs[] = { NULL }; +static char* list_xattr_ignore_xattrs[] = { + GF_SELINUX_XATTR_KEY, + GF_XATTR_VOL_ID_KEY, + GFID_XATTR_KEY, + NULL +}; gf_boolean_t posix_special_xattr (char **pattern, char *key) { @@ -81,21 +87,31 @@ out: return flag; } +static gf_boolean_t +_is_in_array (char **str_array, char *str) +{ + int i = 0; + + for (i = 0; str_array[i]; i++) { + if (strcmp (str, str_array[i]) == 0) + return _gf_true; + } + return _gf_false; +} + static gf_boolean_t posix_xattr_ignorable (char *key, posix_xattr_filler_t *filler) { - int i = 0; gf_boolean_t ignore = _gf_false; GF_ASSERT (key); if (!key) goto out; - for (i = 0; posix_ignore_xattrs[i]; i++) { - if (!strcmp (key, posix_ignore_xattrs[i])) { - ignore = _gf_true; - goto out; - } - } + + ignore = _is_in_array (posix_ignore_xattrs, key); + if (ignore) + goto out; + if ((!strcmp (key, GF_CONTENT_KEY)) && (!IA_ISREG (filler->stbuf->ia_type))) ignore = _gf_true; @@ -177,7 +193,7 @@ _posix_get_marker_all_contributions (posix_xattr_filler_t *filler) goto out; } - list = alloca (size + 1); + list = alloca (size); if (!list) { goto out; } @@ -192,8 +208,6 @@ _posix_get_marker_all_contributions (posix_xattr_filler_t *filler) list_offset = 0; while (remaining_size > 0) { - if (*(list + list_offset) == '\0') - break; strcpy (key, list + list_offset); if (fnmatch (marker_contri_key, key, 0) == 0) { ret = _posix_xattr_get_set_from_backend (filler, key); @@ -546,6 +560,55 @@ out: return ret; } +static void +_handle_list_xattr (dict_t *xattr_req, const char *real_path, + posix_xattr_filler_t *filler) +{ + int ret = -1; + ssize_t size = 0; + char *list = NULL; + int32_t list_offset = 0; + size_t remaining_size = 0; + char *key = NULL; + + if (!real_path) + goto out; + + size = sys_llistxattr (real_path, NULL, 0); + if (size <= 0) + goto out; + + list = alloca (size); + if (!list) + goto out; + + size = sys_llistxattr (real_path, list, size); + if (size <= 0) + goto out; + + remaining_size = size; + list_offset = 0; + while (remaining_size > 0) { + key = list + list_offset; + + if (_is_in_array (list_xattr_ignore_xattrs, key)) + goto next; + + if (posix_special_xattr (marker_xattrs, key)) + goto next; + + if (dict_get (filler->xattr, key)) + goto next; + + ret = _posix_xattr_get_set_from_backend (filler, key); +next: + remaining_size -= strlen (key) + 1; + list_offset += strlen (key) + 1; + + } /* while (remaining_size > 0) */ +out: + return; +} dict_t * posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, @@ -553,6 +616,12 @@ posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, { dict_t *xattr = NULL; posix_xattr_filler_t filler = {0, }; + gf_boolean_t list = _gf_false; + + if (dict_get (xattr_req, "list-xattr")) { + dict_del (xattr_req, "list-xattr"); + list = _gf_true; + } xattr = get_new_dict(); if (!xattr) { @@ -566,6 +635,9 @@ posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, filler.loc = loc; dict_foreach (xattr_req, _posix_xattr_get_set, &filler); + if (list) + _handle_list_xattr (xattr_req, real_path, &filler); + out: return xattr; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index d134eceb80e..f22770eb41a 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3220,13 +3220,18 @@ posix_get_ancestry_non_directory (xlator_t *this, inode_t *leaf_inode, goto out; } - list = alloca (size + 1); + list = alloca (size); if (!list) { *op_errno = errno; goto out; } size = sys_llistxattr (leaf_path, list, size); + if (size < 0) { + op_ret = -1; + *op_errno = errno; + goto out; + } remaining_size = size; list_offset = 0; @@ -3240,8 +3245,6 @@ posix_get_ancestry_non_directory (xlator_t *this, inode_t *leaf_inode, } while (remaining_size > 0) { - if (*(list + list_offset) == '\0') - break; strcpy (key, list + list_offset); if (strncmp (key, PGFID_XATTR_KEY_PREFIX, strlen (PGFID_XATTR_KEY_PREFIX)) != 0) @@ -3605,20 +3608,22 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, if (size == 0) goto done; - list = alloca (size + 1); + list = alloca (size); if (!list) { op_errno = errno; goto out; } size = sys_llistxattr (real_path, list, size); + if (size < 0) { + op_ret = -1; + op_errno = errno; + goto out; + } remaining_size = size; list_offset = 0; while (remaining_size > 0) { - if (*(list + list_offset) == '\0') - break; - strcpy (key, list + list_offset); size = sys_lgetxattr (real_path, key, NULL, 0); if (size == -1) { -- cgit