summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
Diffstat (limited to 'xlators')
-rw-r--r--xlators/features/index/src/index.c4
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c35
-rw-r--r--xlators/protocol/server/src/authenticate.c45
-rw-r--r--xlators/protocol/server/src/server-helpers.c10
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c76
-rw-r--r--xlators/protocol/server/src/server.c134
-rw-r--r--xlators/storage/posix/src/posix-helpers.c58
-rw-r--r--xlators/storage/posix/src/posix.c389
-rw-r--r--xlators/storage/posix/src/posix.h12
9 files changed, 413 insertions, 350 deletions
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c
index d1eb763de8a..d061c410331 100644
--- a/xlators/features/index/src/index.c
+++ b/xlators/features/index/src/index.c
@@ -430,7 +430,8 @@ index_del (xlator_t *this, uuid_t gfid, const char *subdir)
out:
return ret;
}
-int
+
+static int
_check_key_is_zero_filled (dict_t *d, char *k, data_t *v,
void *tmp)
{
@@ -441,6 +442,7 @@ _check_key_is_zero_filled (dict_t *d, char *k, data_t *v,
return 0;
}
+
void
_xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
{
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index a6d02210368..214923decaa 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -2868,10 +2868,10 @@ send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
* when it tries to setxattr() for selinux xattrs
*/
static int
-fuse_filter_xattr(xlator_t *this, char *key)
+fuse_filter_xattr(char *key)
{
int need_filter = 0;
- struct fuse_private *priv = this->private;
+ struct fuse_private *priv = THIS->private;
if ((priv->client_pid == GF_CLIENT_PID_GSYNCD)
&& fnmatch ("*.selinux*", key, FNM_PERIOD) == 0)
@@ -2892,6 +2892,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
data_t *value_data = NULL;
int ret = -1;
int32_t len = 0;
+ int32_t len_next = 0;
state = frame->root->state;
finh = state->finh;
@@ -2922,32 +2923,20 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* we need to invoke fuse_filter_xattr() twice. Once
* while counting size and then while filling buffer
*/
- int _get_total_len (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- if (!fuse_filter_xattr (this, k))
- len += strlen (k) + 1;
- return 0;
- }
- dict_foreach (dict, _get_total_len, NULL);
+ len = dict_keys_join (NULL, 0, dict, fuse_filter_xattr);
+ if (len < 0)
+ goto out;
value = alloca (len + 1);
if (!value)
goto out;
- len = 0;
-
- int _set_listxattr_keys (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- if (!fuse_filter_xattr (this, k)) {
- strcpy (value + len, k);
- value[len + strlen (k)] = '\0';
- len += strlen (k) + 1;
- }
- return 0;
- }
- dict_foreach (dict, _set_listxattr_keys, NULL);
+ len_next = dict_keys_join (value, len, dict,
+ fuse_filter_xattr);
+ if (len_next != len)
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "sizes not equal %d != %d",
+ len, len_next);
send_fuse_xattr (this, finh, value, len, state->size);
} /* if(state->name)...else */
diff --git a/xlators/protocol/server/src/authenticate.c b/xlators/protocol/server/src/authenticate.c
index 9c843d0bb45..eb6deb80149 100644
--- a/xlators/protocol/server/src/authenticate.c
+++ b/xlators/protocol/server/src/authenticate.c
@@ -124,34 +124,41 @@ fini (dict_t *this, char *key, data_t *value, void *data)
return 0;
}
+static int
+_gf_auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp)
+{
+ auth_handle_t *handle = NULL;
+ xlator_t *xl = NULL;
+ int ret = 0;
+
+ xl = tmp;
+
+ handle = data_to_ptr (v);
+ if (!handle)
+ return 0;
+
+ list_add_tail (&(handle->vol_opt->list), &(xl->volume_options));
+
+ ret = xlator_options_validate_list (xl, xl->options,
+ handle->vol_opt, NULL);
+ if (ret) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "volume option validation failed");
+ return -1;
+ }
+ return 0;
+}
+
int32_t
gf_auth_init (xlator_t *xl, dict_t *auth_modules)
{
int ret = 0;
- auth_handle_t *handle = NULL;
dict_foreach (auth_modules, init, &ret);
if (ret)
goto out;
- int _auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp)
- {
- handle = data_to_ptr (v);
- if (!handle)
- return 0;
-
- list_add_tail (&(handle->vol_opt->list),
- &(xl->volume_options));
- ret = xlator_options_validate_list (xl, xl->options,
- handle->vol_opt, NULL);
- if (ret) {
- gf_log ("authenticate", GF_LOG_ERROR,
- "volume option validation failed");
- return -1;
- }
- return 0;
- }
- ret = dict_foreach (auth_modules, _auth_option_validate, NULL);
+ ret = dict_foreach (auth_modules, _gf_auth_option_validate, xl);
out:
if (ret) {
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 0adcd1cf10b..28b912eec69 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -1397,16 +1397,8 @@ gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)
if (!conf || !dict)
return 0;
- /* this exact key is used in 'io-stats' too.
- * But this is better place for this information dump.
- */
- int _handle_keyvalue_pair (dict_t *d, char *k,
- data_t *v, void *tmp)
- {
- return 0;
- }
if (dict_foreach_fnmatch (dict, "*io*stat*dump",
- _handle_keyvalue_pair, NULL ) > 0) {
+ dict_null_foreach_fn, NULL ) > 0) {
list_for_each_entry (xprt, &conf->xprt_list, list) {
total_read += xprt->total_bytes_read;
total_write += xprt->total_bytes_write;
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
index 286befc4e23..f44ced41dc2 100644
--- a/xlators/protocol/server/src/server-rpc-fops.c
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -890,6 +890,24 @@ out:
return 0;
}
+/* print every key */
+static int
+_gf_server_log_setxattr_failure (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+
+ frame = tmp;
+ state = CALL_STATE(frame);
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "%"PRId64": SETXATTR %s (%s) ==> %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), k);
+ return 0;
+}
+
int
server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, dict_t *xdata)
@@ -905,19 +923,14 @@ server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
rsp.xdata.xdata_len, op_errno, out);
if (op_ret == -1) {
- /* print every key */
- int _log_setxattr_failure (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%"PRId64": SETXATTR %s (%s) ==> %s (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid), k,
- strerror (op_errno));
- return 0;
- }
- dict_foreach (state->dict, _log_setxattr_failure, NULL);
+ if (op_errno != ENOTSUP)
+ dict_foreach (state->dict,
+ _gf_server_log_setxattr_failure,
+ frame);
+
+ gf_log (THIS->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%s", strerror (op_errno));
goto out;
}
@@ -933,6 +946,24 @@ out:
return 0;
}
+/* print every key here */
+static int
+_gf_server_log_fsetxattr_failure (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+
+ frame = tmp;
+ state = CALL_STATE(frame);
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), k);
+
+ return 0;
+}
int
server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -949,19 +980,14 @@ server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
rsp.xdata.xdata_len, op_errno, out);
if (op_ret == -1) {
- /* print every key here */
- int _log_setxattr_failure (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), k,
- strerror (op_errno));
- return 0;
+ if (op_errno != ENOTSUP) {
+ dict_foreach (state->dict,
+ _gf_server_log_fsetxattr_failure,
+ frame);
}
- dict_foreach (state->dict, _log_setxattr_failure, NULL);
+ gf_log (THIS->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%s", strerror (op_errno));
goto out;
}
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index 19f09a82f2f..d2bc4876c5b 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -616,84 +616,85 @@ out:
return 0;
}
+int
+_check_for_auth_option (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ int ret = 0;
+ xlator_t *xl = NULL;
+ char *tail = NULL;
+ char *tmp_addr_list = NULL;
+ char *addr = NULL;
+ char *tmp_str = NULL;
+
+ xl = tmp;
+
+ tail = strtail (k, "auth.");
+ if (!tail)
+ goto out;
+
+ /* fast fwd thru module type */
+ tail = strchr (tail, '.');
+ if (!tail)
+ goto out;
+ tail++;
+
+ tail = strtail (tail, xl->name);
+ if (!tail)
+ goto out;
+
+ if (*tail == '.') {
+ /* when we are here, the key is checked for
+ * valid auth.allow.<xlator>
+ * Now we verify the ip address
+ */
+ if (!strcmp (v->data, "*")) {
+ ret = 0;
+ goto out;
+ }
+
+ tmp_addr_list = gf_strdup (v->data);
+ addr = strtok_r (tmp_addr_list, ",", &tmp_str);
+ if (!addr)
+ addr = v->data;
+
+ while (addr) {
+ if (valid_internet_address (addr, _gf_true)) {
+ ret = 0;
+ } else {
+ ret = -1;
+ gf_log (xl->name, GF_LOG_ERROR,
+ "internet address '%s'"
+ " does not conform to"
+ " standards.", addr);
+ goto out;
+ }
+ if (tmp_str)
+ addr = strtok_r (NULL, ",", &tmp_str);
+ else
+ addr = NULL;
+ }
+
+ GF_FREE (tmp_addr_list);
+ tmp_addr_list = NULL;
+ }
+out:
+ return ret;
+}
int
validate_auth_options (xlator_t *this, dict_t *dict)
{
int error = -1;
xlator_list_t *trav = NULL;
- char *tail = NULL;
- char *tmp_addr_list = NULL;
- char *addr = NULL;
- char *tmp_str = NULL;
GF_VALIDATE_OR_GOTO ("server", this, out);
GF_VALIDATE_OR_GOTO ("server", dict, out);
trav = this->children;
while (trav) {
- int _check_for_auth_option (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- int ret = 0;
- tail = strtail (k, "auth.");
- if (!tail)
- goto internal_out;
-
- /* fast fwd thru module type */
- tail = strchr (tail, '.');
- if (!tail)
- goto internal_out;
- tail++;
-
- tail = strtail (tail, trav->xlator->name);
- if (!tail)
- goto internal_out;
-
- if (*tail == '.') {
-
- /* when we are here, the key is checked for
- * valid auth.allow.<xlator>
- * Now we verify the ip address
- */
- if (!strcmp (v->data, "*")) {
- ret = 0;
- goto internal_out;
- }
-
- tmp_addr_list = gf_strdup (v->data);
- addr = strtok_r (tmp_addr_list, ",", &tmp_str);
- if (!addr)
- addr = v->data;
-
- while (addr) {
-
- if (valid_internet_address (addr,
- _gf_true)) {
- ret = 0;
- } else {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "internet address '%s'"
- " does not conform to"
- " standards.", addr);
- goto internal_out;
-
- }
- if (tmp_str)
- addr = strtok_r (NULL, ",",
- &tmp_str);
- else
- addr = NULL;
- }
-
- GF_FREE (tmp_addr_list);
- tmp_addr_list = NULL;
- }
- internal_out:
- return ret;
- }
- error = dict_foreach (dict, _check_for_auth_option, NULL);
+ error = dict_foreach (dict, _check_for_auth_option,
+ trav->xlator);
if (-1 == error) {
gf_log (this->name, GF_LOG_ERROR,
@@ -706,7 +707,6 @@ validate_auth_options (xlator_t *this, dict_t *dict)
}
out:
- GF_FREE (tmp_addr_list);
return error;
}
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 58708a3476a..7e8d5838c39 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -46,14 +46,6 @@
#include "hashfn.h"
#include <fnmatch.h>
-typedef struct {
- xlator_t *this;
- const char *real_path;
- dict_t *xattr;
- struct iatt *stbuf;
- loc_t *loc;
-} posix_xattr_filler_t;
-
char *marker_xattrs[] = {"trusted.glusterfs.quota.*",
"trusted.glusterfs.*.xtime",
NULL};
@@ -946,35 +938,47 @@ out:
return ret;
}
+static int
+_handle_entry_create_keyvalue_pair (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ int ret = -1;
+ posix_xattr_filler_t *filler = NULL;
+
+ filler = tmp;
+
+ if (!strcmp (GFID_XATTR_KEY, k) ||
+ !strcmp ("gfid-req", k) ||
+ !strcmp ("system.posix_acl_default", k) ||
+ !strcmp ("system.posix_acl_access", k) ||
+ ZR_FILE_CONTENT_REQUEST(k)) {
+ return 0;
+ }
+
+ ret = posix_handle_pair (filler->this, filler->real_path, k, v,
+ XATTR_CREATE);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
int
posix_entry_create_xattr_set (xlator_t *this, const char *path,
dict_t *dict)
{
int ret = -1;
+ posix_xattr_filler_t filler = {0,};
+
if (!dict)
goto out;
- int _handle_keyvalue_pair (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- if (!strcmp (GFID_XATTR_KEY, k) ||
- !strcmp ("gfid-req", k) ||
- !strcmp ("system.posix_acl_default", k) ||
- !strcmp ("system.posix_acl_access", k) ||
- ZR_FILE_CONTENT_REQUEST(k)) {
- return 0;
- }
-
- ret = posix_handle_pair (this, path, k, v, XATTR_CREATE);
- if (ret < 0) {
- errno = -ret;
- return -1;
- }
- return 0;
- }
+ filler.this = this;
+ filler.real_path = path;
- ret = dict_foreach (dict, _handle_keyvalue_pair, NULL);
+ ret = dict_foreach (dict, _handle_entry_create_keyvalue_pair, &filler);
out:
return ret;
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 816011542af..258ce5241af 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -2382,6 +2382,17 @@ out:
}
static int gf_posix_xattr_enotsup_log;
+static int
+_handle_setxattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ posix_xattr_filler_t *filler = NULL;
+
+ filler = tmp;
+
+ return posix_handle_pair (filler->this, filler->real_path, k, v,
+ filler->flags);
+}
int32_t
posix_setxattr (call_frame_t *frame, xlator_t *this,
@@ -2390,7 +2401,8 @@ posix_setxattr (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
char * real_path = NULL;
- int ret = -1;
+
+ posix_xattr_filler_t filler = {0,};
DECLARE_OLD_FS_ID_VAR;
SET_FS_ID (frame->root->uid, frame->root->gid);
@@ -2405,17 +2417,13 @@ posix_setxattr (call_frame_t *frame, xlator_t *this,
op_ret = -1;
dict_del (dict, GFID_XATTR_KEY);
-
- int _handle_every_keyvalue_pair (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- ret = posix_handle_pair (this, real_path, k, v, flags);
- if (ret < 0) {
- op_errno = -ret;
- }
- return ret;
- }
- op_ret = dict_foreach (dict, _handle_every_keyvalue_pair, NULL);
+ filler.real_path = real_path;
+ filler.this = this;
+ filler.flags = flags;
+ op_ret = dict_foreach (dict, _handle_setxattr_keyvalue_pair,
+ &filler);
+ if (op_ret < 0)
+ op_errno = -op_ret;
out:
SET_TO_OLD_FS_ID ();
@@ -2899,6 +2907,17 @@ out:
return 0;
}
+static int
+_handle_fsetxattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ posix_xattr_filler_t *filler = NULL;
+
+ filler = tmp;
+
+ return posix_fhandle_pair (filler->this, filler->fd, k, v,
+ filler->flags);
+}
int32_t
posix_fsetxattr (call_frame_t *frame, xlator_t *this,
@@ -2908,7 +2927,9 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,
int32_t op_errno = 0;
struct posix_fd * pfd = NULL;
int _fd = -1;
- int ret = -1;
+ int ret = -1;
+
+ posix_xattr_filler_t filler = {0,};
DECLARE_OLD_FS_ID_VAR;
SET_FS_ID (frame->root->uid, frame->root->gid);
@@ -2929,17 +2950,13 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,
dict_del (dict, GFID_XATTR_KEY);
- int _handle_every_keyvalue_pair (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- ret = posix_fhandle_pair (this, _fd, k, v, flags);
- if (ret < 0) {
- op_errno = -ret;
- }
- return ret;
- }
-
- op_ret = dict_foreach (dict, _handle_every_keyvalue_pair, NULL);
+ filler.fd = _fd;
+ filler.this = this;
+ filler.flags = flags;
+ op_ret = dict_foreach (dict, _handle_fsetxattr_keyvalue_pair,
+ &filler);
+ if (op_ret < 0)
+ op_errno = -op_ret;
out:
SET_TO_OLD_FS_ID ();
@@ -3130,6 +3147,159 @@ __add_long_array (int64_t *dest, int64_t *src, int count)
}
}
+static int
+_posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ int size = 0;
+ int count = 0;
+ int op_ret = 0;
+ int op_errno = 0;
+ gf_xattrop_flags_t optype = 0;
+ char *array = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+ posix_xattr_filler_t *filler = NULL;
+
+ filler = tmp;
+
+ optype = (gf_xattrop_flags_t)(filler->flags);
+ this = filler->this;
+ inode = filler->inode;
+
+ count = v->len;
+ array = GF_CALLOC (count, sizeof (char), gf_posix_mt_char);
+
+ LOCK (&inode->lock);
+ {
+ if (filler->real_path) {
+ size = sys_lgetxattr (filler->real_path, k,
+ (char *)array, v->len);
+ } else {
+ size = sys_fgetxattr (filler->fd, k, (char *)array,
+ v->len);
+ }
+
+ op_errno = errno;
+ if ((size == -1) && (op_errno != ENODATA) &&
+ (op_errno != ENOATTR)) {
+ if (op_errno == ENOTSUP) {
+ GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log,
+ this->name, GF_LOG_WARNING,
+ "Extended attributes not "
+ "supported by filesystem");
+ } else if (op_errno != ENOENT ||
+ !posix_special_xattr (marker_xattrs,
+ k)) {
+ if (filler->real_path)
+ gf_log (this->name, GF_LOG_ERROR,
+ "getxattr failed on %s while doing "
+ "xattrop: Key:%s (%s)",
+ filler->real_path,
+ k, strerror (op_errno));
+ else
+ gf_log (this->name, GF_LOG_ERROR,
+ "fgetxattr failed on fd=%d while doing "
+ "xattrop: Key:%s (%s)",
+ filler->fd,
+ k, strerror (op_errno));
+ }
+
+ op_ret = -1;
+ goto unlock;
+ }
+
+ switch (optype) {
+
+ case GF_XATTROP_ADD_ARRAY:
+ __add_array ((int32_t *) array, (int32_t *) v->data,
+ v->len / 4);
+ break;
+
+ case GF_XATTROP_ADD_ARRAY64:
+ __add_long_array ((int64_t *) array, (int64_t *) v->data,
+ v->len / 8);
+ break;
+
+ case GF_XATTROP_OR_ARRAY:
+ __or_array ((int32_t *) array,
+ (int32_t *) v->data,
+ v->len / 4);
+ break;
+
+ case GF_XATTROP_AND_ARRAY:
+ __and_array ((int32_t *) array,
+ (int32_t *) v->data,
+ v->len / 4);
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unknown xattrop type (%d) on %s. Please send "
+ "a bug report to gluster-devel@nongnu.org",
+ optype, filler->real_path);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unlock;
+ }
+
+ if (filler->real_path) {
+ size = sys_lsetxattr (filler->real_path, k, array,
+ v->len, 0);
+ } else {
+ size = sys_fsetxattr (filler->fd, k, (char *)array,
+ v->len, 0);
+ }
+ }
+unlock:
+ UNLOCK (&inode->lock);
+
+ if (op_ret == -1)
+ goto out;
+
+ op_errno = errno;
+ if (size == -1) {
+ if (filler->real_path)
+ gf_log (this->name, GF_LOG_ERROR,
+ "setxattr failed on %s while doing xattrop: "
+ "key=%s (%s)", filler->real_path,
+ k, strerror (op_errno));
+ else
+ gf_log (this->name, GF_LOG_ERROR,
+ "fsetxattr failed on fd=%d while doing xattrop: "
+ "key=%s (%s)", filler->fd,
+ k, strerror (op_errno));
+
+ op_ret = -1;
+ goto out;
+ } else {
+ size = dict_set_bin (d, k, array, v->len);
+
+ if (size != 0) {
+ if (filler->real_path)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "dict_set_bin failed (path=%s): "
+ "key=%s (%s)", filler->real_path,
+ k, strerror (-size));
+ else
+ gf_log (this->name, GF_LOG_DEBUG,
+ "dict_set_bin failed (fd=%d): "
+ "key=%s (%s)", filler->fd,
+ k, strerror (-size));
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+ array = NULL;
+ }
+
+ array = NULL;
+
+out:
+ return op_ret;
+}
+
/**
* xattrop - xattr operations - for internal use by GlusterFS
* @optype: ADD_ARRAY:
@@ -3141,32 +3311,24 @@ int
do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
gf_xattrop_flags_t optype, dict_t *xattr)
{
- char *real_path = NULL;
- char *array = NULL;
- int size = 0;
- int count = 0;
-
- int op_ret = 0;
- int op_errno = 0;
-
- int ret = 0;
- int _fd = -1;
- struct posix_fd *pfd = NULL;
-
- char * path = NULL;
- inode_t * inode = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+ int _fd = -1;
+ char *real_path = NULL;
+ struct posix_fd *pfd = NULL;
+ inode_t *inode = NULL;
+ posix_xattr_filler_t filler = {0,};
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (xattr, out);
VALIDATE_OR_GOTO (this, out);
if (fd) {
- ret = posix_fd_ctx_get (fd, this, &pfd);
- if (ret < 0) {
+ op_ret = posix_fd_ctx_get (fd, this, &pfd);
+ if (op_ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"failed to get pfd from fd=%p",
fd);
- op_ret = -1;
op_errno = EBADFD;
goto out;
}
@@ -3177,152 +3339,21 @@ do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
MAKE_INODE_HANDLE (real_path, this, loc, NULL);
if (real_path) {
- path = gf_strdup (real_path);
inode = loc->inode;
} else if (fd) {
inode = fd->inode;
}
- int _handle_every_keyvalue_pair (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
-
- count = v->len;
- array = GF_CALLOC (count, sizeof (char), gf_posix_mt_char);
-
- LOCK (&inode->lock);
- {
- if (loc) {
- size = sys_lgetxattr (real_path, k,
- (char *)array, v->len);
- } else {
- size = sys_fgetxattr (_fd, k, (char *)array,
- v->len);
- }
-
- op_errno = errno;
- if ((size == -1) && (op_errno != ENODATA) &&
- (op_errno != ENOATTR)) {
- if (op_errno == ENOTSUP) {
- GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log,
- this->name,GF_LOG_WARNING,
- "Extended attributes not "
- "supported by filesystem");
- } else if (op_errno != ENOENT ||
- !posix_special_xattr (marker_xattrs,
- k)) {
- if (loc)
- gf_log (this->name, GF_LOG_ERROR,
- "getxattr failed on %s while doing "
- "xattrop: Key:%s (%s)", path,
- k, strerror (op_errno));
- else
- gf_log (this->name, GF_LOG_ERROR,
- "fgetxattr failed on fd=%d while doing "
- "xattrop: Key:%s (%s)", _fd,
- k, strerror (op_errno));
- }
-
- op_ret = -1;
- goto unlock;
- }
-
- switch (optype) {
-
- case GF_XATTROP_ADD_ARRAY:
- __add_array ((int32_t *) array, (int32_t *) v->data,
- v->len / 4);
- break;
+ filler.this = this;
+ filler.fd = _fd;
+ filler.real_path = real_path;
+ filler.flags = (int)optype;
+ filler.inode = inode;
- case GF_XATTROP_ADD_ARRAY64:
- __add_long_array ((int64_t *) array, (int64_t *) v->data,
- v->len / 8);
- break;
-
- case GF_XATTROP_OR_ARRAY:
- __or_array ((int32_t *) array,
- (int32_t *) v->data,
- v->len / 4);
- break;
-
- case GF_XATTROP_AND_ARRAY:
- __and_array ((int32_t *) array,
- (int32_t *) v->data,
- v->len / 4);
- break;
-
- default:
- gf_log (this->name, GF_LOG_ERROR,
- "Unknown xattrop type (%d) on %s. Please send "
- "a bug report to gluster-devel@nongnu.org",
- optype, path);
- op_ret = -1;
- op_errno = EINVAL;
- goto unlock;
- }
-
- if (loc) {
- size = sys_lsetxattr (real_path, k, array,
- v->len, 0);
- } else {
- size = sys_fsetxattr (_fd, k, (char *)array,
- v->len, 0);
- }
- }
- unlock:
- UNLOCK (&inode->lock);
-
- if (op_ret == -1)
- goto out;
-
- op_errno = errno;
- if (size == -1) {
- if (loc)
- gf_log (this->name, GF_LOG_ERROR,
- "setxattr failed on %s while doing xattrop: "
- "key=%s (%s)", path,
- k, strerror (op_errno));
- else
- gf_log (this->name, GF_LOG_ERROR,
- "fsetxattr failed on fd=%d while doing xattrop: "
- "key=%s (%s)", _fd,
- k, strerror (op_errno));
-
- op_ret = -1;
- goto out;
- } else {
- size = dict_set_bin (xattr, k, array, v->len);
-
- if (size != 0) {
- if (loc)
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_set_bin failed (path=%s): "
- "key=%s (%s)", path,
- k, strerror (-size));
- else
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_set_bin failed (fd=%d): "
- "key=%s (%s)", _fd,
- k, strerror (-size));
-
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
- array = NULL;
- }
-
- array = NULL;
-
- out:
- return op_ret;
- }
- op_ret = dict_foreach (xattr, _handle_every_keyvalue_pair, NULL);
+ op_ret = dict_foreach (xattr, _posix_handle_xattr_keyvalue_pair,
+ &filler);
out:
- GF_FREE (array);
-
- GF_FREE (path);
STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xattr, NULL);
return 0;
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index 45ee3596330..4703a1fd432 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -127,6 +127,18 @@ struct posix_private {
#endif
};
+typedef struct {
+ xlator_t *this;
+ const char *real_path;
+ dict_t *xattr;
+ struct iatt *stbuf;
+ loc_t *loc;
+ inode_t *inode; /* for all do_xattrop() key handling */
+ int fd;
+ int flags;
+} posix_xattr_filler_t;
+
+
#define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)
#define POSIX_BASE_PATH_LEN(this) (((struct posix_private *)this->private)->base_path_length)