From 000e65d7af7be31236e060064fb3b4a332e78cf3 Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Tue, 13 Nov 2012 01:14:43 +0530 Subject: core: remove all the 'inner' functions in codebase * move 'dict_keys_join()' from api/glfs_fops.c to libglusterfs/dict.c - also added an argument which is treated as a filter function if required, currently useful for fuse. * now 'make CFLAGS="-std=gnu99 -pedantic" 2>&1 | grep nested' gives no output. Change-Id: I4e18496fbd93ae1d3942026ef4931889cba015e8 Signed-off-by: Amar Tumballi BUG: 875913 Reviewed-on: http://review.gluster.org/4187 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- api/src/glfs-fops.c | 24 +- cli/src/cli-rpc-ops.c | 44 +-- cli/src/cli-xml-output.c | 56 ++-- libglusterfs/src/common-utils.h | 11 +- libglusterfs/src/dict.c | 46 +++ libglusterfs/src/dict.h | 5 + xlators/features/index/src/index.c | 4 +- xlators/mount/fuse/src/fuse-bridge.c | 35 +-- xlators/protocol/server/src/authenticate.c | 45 +-- xlators/protocol/server/src/server-helpers.c | 10 +- xlators/protocol/server/src/server-rpc-fops.c | 76 +++-- xlators/protocol/server/src/server.c | 134 ++++----- xlators/storage/posix/src/posix-helpers.c | 58 ++-- xlators/storage/posix/src/posix.c | 389 ++++++++++++++------------ xlators/storage/posix/src/posix.h | 12 + 15 files changed, 529 insertions(+), 420 deletions(-) diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index c9897243..be26dc12 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -1856,32 +1856,12 @@ out: } -static int -dict_keys_join (void *value, int size, dict_t *dict) -{ - int len = 0; - - int add_key_len (dict_t *d, char *k, data_t *v, void *o) - { - if (value && size > len) - strncpy (value + len, k, size - len); - - len += (strlen (k) + 1); - - return 0; - } - - dict_foreach (dict, add_key_len, 0); - - return len; -} - int glfs_listxattr_process (void *value, size_t size, dict_t *xattr) { int ret = -1; - ret = dict_keys_join (NULL, 0, xattr); + ret = dict_keys_join (NULL, 0, xattr, NULL); if (!value || !size) goto out; @@ -1892,7 +1872,7 @@ glfs_listxattr_process (void *value, size_t size, dict_t *xattr) goto out; } - dict_keys_join (value, size, xattr); + dict_keys_join (value, size, xattr, NULL); out: if (xattr) dict_unref (xattr); diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 22a69da7..c5a0fffb 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -474,6 +474,30 @@ cli_out_options ( char *substr, char *optstr, char *valstr) cli_out ("%s: %s",ptr2 , valstr); } +static int +_gf_cli_output_volinfo_opts (dict_t *d, char *k, + data_t *v, void *tmp) +{ + int ret = 0; + char *key = NULL; + char *ptr = NULL; + data_t *value = NULL; + + key = tmp; + + ptr = strstr (k, "option."); + if (ptr) { + value = v; + if (!value) { + ret = -1; + goto out; + } + cli_out_options (key, k, v->data); + } +out: + return ret; +} + int gf_cli_get_volume_cbk (struct rpc_req *req, struct iovec *iov, @@ -491,12 +515,10 @@ gf_cli_get_volume_cbk (struct rpc_req *req, struct iovec *iov, int32_t replica_count = 0; int32_t vol_type = 0; int32_t transport = 0; - char *ptr = NULL; char *volume_id_str = NULL; char *brick = NULL; char *volname = NULL; dict_t *dict = NULL; - data_t *value = NULL; cli_local_t *local = NULL; char key[1024] = {0}; char err_str[2048] = {0}; @@ -724,22 +746,8 @@ next: cli_out ("Options Reconfigured:"); snprintf (key, 256, "volume%d.option.",i); - int _output_volinfo_opts (dict_t *d, char *k, - data_t *v, void *tmp) - { - ptr = strstr (k, "option."); - if (ptr) { - value = v; - if (!value) { - ret = -1; - goto internal_out; - } - cli_out_options (key, k, v->data); - } - internal_out: - return ret; - } - ret = dict_foreach (dict, _output_volinfo_opts, NULL); + + ret = dict_foreach (dict, _gf_cli_output_volinfo_opts, key); if (ret) goto out; diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 88410ef5..7155ef53 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -2265,15 +2265,44 @@ out: return ret; } +struct tmp_xml_option_logger { + char *key; + xmlTextWriterPtr writer; +}; + +static int +_output_vol_info_option (dict_t *d, char *k, data_t *v, + void *data) +{ + int ret = 0; + char *ptr = NULL; + struct tmp_xml_option_logger *tmp = NULL; + + tmp = data; + + ptr = strstr (k, "option."); + if (!ptr) + goto out; + + if (!v) { + ret = -1; + goto out; + } + ret = cli_xml_output_vol_info_option (tmp->writer, tmp->key, k, + v->data); + +out: + return ret; +} + int cli_xml_output_vol_info_options (xmlTextWriterPtr writer, dict_t *dict, char *prefix) { int ret = -1; int opt_count = 0; - data_t *value = 0; - char *ptr = NULL; char key[1024] = {0,}; + struct tmp_xml_option_logger tmp = {0,}; snprintf (key, sizeof (key), "%s.opt_count", prefix); ret = dict_get_int32 (dict, key, &opt_count); @@ -2288,26 +2317,9 @@ cli_xml_output_vol_info_options (xmlTextWriterPtr writer, dict_t *dict, XML_RET_CHECK_AND_GOTO (ret, out); snprintf (key, sizeof (key), "%s.option.", prefix); - int _output_vol_info_option (dict_t *d, char *k, data_t *v, - void *data) - { - int ret = 0; - ptr = strstr (k, "option."); - if (!ptr) - goto internal_out; - - value = v; - if (!value) { - ret = -1; - goto internal_out; - } - ret = cli_xml_output_vol_info_option (writer, key, k, - v->data); - - internal_out: - return ret; - } - ret = dict_foreach (dict, _output_vol_info_option, NULL); + tmp.key = key; + tmp.writer = writer; + ret = dict_foreach (dict, _output_vol_info_option, &tmp); if (ret) goto out; diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 75692309..d9d3082c 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -172,7 +172,6 @@ void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx); } \ } while (0) - #define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \ do { \ if (!dict) { \ @@ -180,13 +179,9 @@ void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx); "setxattr dict is null"); \ goto label; \ } \ - int _handle_keyvalue_pair (dict_t *d, char *k, \ - data_t *v, void *tmp) \ - { \ - return 0; \ - } \ - if (dict_foreach_fnmatch (dict, pattern, \ - _handle_keyvalue_pair, NULL) > 0) { \ + if (dict_foreach_fnmatch (dict, pattern, \ + dict_null_foreach_fn, \ + NULL) > 0) { \ op_errno = EPERM; \ gf_log (this->name, GF_LOG_ERROR, \ "attempt to set internal" \ diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index e9b8da1c..a8cdeaf2 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -1078,6 +1078,13 @@ data_to_bin (data_t *data) return data->data; } +int +dict_null_foreach_fn (dict_t *d, char *k, + data_t *v, void *tmp) +{ + return 0; +} + int dict_foreach (dict_t *dict, int (*fn)(dict_t *this, @@ -1148,6 +1155,45 @@ dict_foreach_fnmatch (dict_t *dict, char *pattern, } +/** + * dict_keys_join - pack the keys of the dictionary in a buffer. + * + * @value : buffer in which the keys will be packed (can be NULL) + * @size : size of the buffer which is sent (can be 0, in which case buffer + * is not packed but only length is returned) + * @dict : dictionary of which all the keys will be packed + * @filter_fn : keys matched in filter_fn() is counted. + * + * @return : @length of string after joining keys. + * + */ + +int +dict_keys_join (void *value, int size, dict_t *dict, + int (*filter_fn)(char *k)) +{ + int len = 0; + data_pair_t *pairs = NULL; + data_pair_t *next = NULL; + + pairs = dict->members_list; + while (pairs) { + next = pairs->next; + + if (filter_fn && filter_fn (pairs->key)) + continue; + + if (value && (size > len)) + strncpy (value + len, pairs->key, size - len); + + len += (strlen (pairs->key) + 1); + + pairs = next; + } + + return len; +} + static int _copy (dict_t *unused, char *key, diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h index dbf98046..c7606352 100644 --- a/libglusterfs/src/dict.h +++ b/libglusterfs/src/dict.h @@ -177,7 +177,12 @@ int dict_foreach_fnmatch (dict_t *dict, char *pattern, void *data), void *data); +int dict_null_foreach_fn (dict_t *d, char *k, + data_t *v, void *tmp); + dict_t *dict_copy (dict_t *this, dict_t *new); +int dict_keys_join (void *value, int size, dict_t *dict, + int (*filter_fn)(char *key)); /* CLEANED UP FUNCTIONS DECLARATIONS */ GF_MUST_CHECK dict_t *dict_new (void); diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index d1eb763d..d061c410 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 a6d02210..214923de 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 9c843d0b..eb6deb80 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 0adcd1cf..28b912ee 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 286befc4..f44ced41 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 19f09a82..d2bc4876 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. + * 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. - * 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 58708a34..7e8d5838 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 -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 81601154..258ce524 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 45ee3596..4703a1fd 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) -- cgit