diff options
Diffstat (limited to 'xlators/storage/posix/src/posix-helpers.c')
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 57 |
1 files changed, 53 insertions, 4 deletions
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, |