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 <amarts@redhat.com>
BUG: 875913
Reviewed-on: http://review.gluster.org/4187
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
This commit is contained in:
Amar Tumballi 2012-11-13 01:14:43 +05:30 committed by Anand Avati
parent e5a19e2ab5
commit 000e65d7af
15 changed files with 529 additions and 420 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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" \

View File

@ -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,

View File

@ -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);

View File

@ -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)
{

View File

@ -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 */

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
filler.this = this;
filler.real_path = path;
ret = posix_handle_pair (this, path, k, v, XATTR_CREATE);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}
ret = dict_foreach (dict, _handle_keyvalue_pair, NULL);
ret = dict_foreach (dict, _handle_entry_create_keyvalue_pair, &filler);
out:
return ret;

View File

@ -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)
{
filler.this = this;
filler.fd = _fd;
filler.real_path = real_path;
filler.flags = (int)optype;
filler.inode = inode;
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;
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;

View File

@ -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)