summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix-helpers.c')
-rw-r--r--xlators/storage/posix/src/posix-helpers.c57
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,