From 801b7bd50a51c66e327ad79cdfc131654e069cdc Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Mon, 28 Sep 2015 13:09:38 +0530 Subject: storage/posix: Reduce number of getxattrs for internal xattrs Most of the gluster internal xattrs don't exceed 256 bytes. So try getxattr with ~256 bytes. If it gives ERANGE then go the old way of getxattr with NULL 'buf' to find the length and then getxattr with allocated 'buf' to fill the data. This way we reduce lot of getxattrs. Change-Id: I716d484bc9ba67a81d0cedb5ee3e72a5ba661f6d BUG: 1265893 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/12240 Tested-by: NetBSD Build System Reviewed-by: N Balachandran Reviewed-by: Raghavendra Bhat --- xlators/storage/posix/src/posix-helpers.c | 57 ++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) (limited to 'xlators/storage/posix/src/posix-helpers.c') diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 23485bdfd8d..0353788740e 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -75,6 +75,7 @@ static char* list_xattr_ignore_xattrs[] = { GFID_XATTR_KEY, NULL }; + gf_boolean_t posix_special_xattr (char **pattern, char *key) { @@ -115,29 +116,77 @@ posix_xattr_ignorable (char *key) return _is_in_array (posix_ignore_xattrs, key); } +static gf_boolean_t +posix_is_valid_namespace (char *key) +{ + static char *xattr_namespaces[] = {"trusted.", "security.", "system.", + "user.", NULL }; + int i = 0; + + for (i = 0; xattr_namespaces[i]; i++) { + if (strncmp (key, xattr_namespaces[i], + strlen (xattr_namespaces[i])) == 0) + return _gf_true; + } + + return _gf_false; +} + static int _posix_xattr_get_set_from_backend (posix_xattr_filler_t *filler, char *key) { ssize_t xattr_size = -1; int ret = 0; - char *value = NULL; + char *value = NULL; + char val_buf[256] = {0}; + gf_boolean_t have_val = _gf_false; + + if (!posix_is_valid_namespace (key)) { + ret = -1; + goto out; + } + /* Most of the gluster internal xattrs don't exceed 256 bytes. So try + * getxattr with ~256 bytes. If it gives ERANGE then go the old way + * of getxattr with NULL buf to find the length and then getxattr with + * allocated buf to fill the data. This way we reduce lot of getxattrs. + */ if (filler->real_path) - xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0); + xattr_size = sys_lgetxattr (filler->real_path, key, val_buf, + sizeof (val_buf) - 1); else + xattr_size = sys_fgetxattr (filler->fdnum, key, val_buf, + sizeof (val_buf) - 1); + + if (xattr_size >= 0) { + have_val = _gf_true; + } else if (xattr_size == -1 && errno != ERANGE) { + ret = -1; + goto out; + } + + if (have_val) { + /*No need to do getxattr*/ + } else if (filler->real_path) { + xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0); + } else { xattr_size = sys_fgetxattr (filler->fdnum, key, NULL, 0); + } if (xattr_size != -1) { value = GF_CALLOC (1, xattr_size + 1, gf_posix_mt_char); if (!value) goto out; - if (filler->real_path) + if (have_val) { + memcpy (value, val_buf, xattr_size); + } else if (filler->real_path) { xattr_size = sys_lgetxattr (filler->real_path, key, value, xattr_size); - else + } else { xattr_size = sys_fgetxattr (filler->fdnum, key, value, xattr_size); + } if (xattr_size == -1) { if (filler->real_path) gf_msg (filler->this->name, GF_LOG_WARNING, 0, -- cgit