diff options
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/index/src/index.c | 4 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 35 | ||||
-rw-r--r-- | xlators/protocol/server/src/authenticate.c | 45 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 10 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 76 | ||||
-rw-r--r-- | xlators/protocol/server/src/server.c | 134 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 58 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 389 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 12 |
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) |