diff options
Diffstat (limited to 'xlators/features/mac-compat/src')
-rw-r--r-- | xlators/features/mac-compat/src/Makefile.am | 5 | ||||
-rw-r--r-- | xlators/features/mac-compat/src/mac-compat.c | 246 | ||||
-rw-r--r-- | xlators/features/mac-compat/src/mac-compat.h | 41 |
3 files changed, 223 insertions, 69 deletions
diff --git a/xlators/features/mac-compat/src/Makefile.am b/xlators/features/mac-compat/src/Makefile.am index f8567edce71..42ed350e93e 100644 --- a/xlators/features/mac-compat/src/Makefile.am +++ b/xlators/features/mac-compat/src/Makefile.am @@ -6,9 +6,10 @@ mac_compat_la_LDFLAGS = -module -avoid-version mac_compat_la_SOURCES = mac-compat.c mac_compat_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la +noinst_HEADERS = mac-compat.h + AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src AM_CFLAGS = -Wall $(GF_CFLAGS) -CLEANFILES = - +CLEANFILES = diff --git a/xlators/features/mac-compat/src/mac-compat.c b/xlators/features/mac-compat/src/mac-compat.c index 7cb550ad581..0eaf563e889 100644 --- a/xlators/features/mac-compat/src/mac-compat.c +++ b/xlators/features/mac-compat/src/mac-compat.c @@ -15,35 +15,28 @@ #include "xlator.h" #include "defaults.h" #include "compat-errno.h" +#include "syscall.h" +#include "mem-pool.h" +#include "mac-compat.h" - -enum apple_xattr { - GF_FINDER_INFO_XATTR, - GF_RESOURCE_FORK_XATTR, - GF_XATTR_ALL, - GF_XATTR_NONE -}; - -static char *apple_xattr_name[] = { - [GF_FINDER_INFO_XATTR] = "com.apple.FinderInfo", - [GF_RESOURCE_FORK_XATTR] = "com.apple.ResourceFork" -}; - -static const char *apple_xattr_value[] = { - [GF_FINDER_INFO_XATTR] = - /* 1 2 3 4 5 6 7 8 */ - "\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0", - [GF_RESOURCE_FORK_XATTR] = "" -}; - -static int32_t apple_xattr_len[] = { - [GF_FINDER_INFO_XATTR] = 32, - [GF_RESOURCE_FORK_XATTR] = 1 -}; - +static int +dict_key_remove_namespace(dict_t *dict, char *key, data_t *value, void *data) +{ + /* + char buffer[3*value->len+1]; + int index = 0; + for (index = 0; index < value->len; index++) + sprintf(buffer+3*index, " %02x", value->data[index]); + */ + xlator_t *this = (xlator_t *) data; + if (strncmp(key, "user.", 5) == 0) { + dict_set (dict, key + 5, value); + gf_log (this->name, GF_LOG_DEBUG, + "remove_namespace_dict: %s -> %s ", key, key + 5); + dict_del (dict, key); + } + return 0; +} int32_t maccomp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -53,54 +46,91 @@ maccomp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, intptr_t ax = (intptr_t)this->private; int i = 0; + gf_log (this->name, GF_LOG_DEBUG, + "getxattr_cbk: dict %p private: %p xdata %p ", dict, + this->private, xdata); + + if (dict) { + dict_foreach(dict, dict_key_remove_namespace, this); + } + else { + // TODO: we expect dict to exist here, don't know why this + // this is needed + dict = dict_new(); + } + gf_log (this->name, GF_LOG_DEBUG, + "getxattr_cbk: dict %p ax: %ld op_ret %d op_err %d ", dict, ax, + op_ret, op_errno); if ((ax == GF_XATTR_ALL && op_ret >= 0) || ax != GF_XATTR_NONE) { op_ret = op_errno = 0; - for (i = 0; i < GF_XATTR_ALL; i++) { if (dict_get (dict, apple_xattr_name[i])) continue; - + /* set dummy data */ + gf_log (this->name, GF_LOG_DEBUG, + "getxattr_cbk: setting dummy data %p, %s", dict, + apple_xattr_name[i]); if (dict_set (dict, apple_xattr_name[i], bin_to_data ((void *)apple_xattr_value[i], apple_xattr_len[i])) == -1) { op_ret = -1; - op_errno = ENOMEM; + op_errno = ENOATTR; break; } } } - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata); - return 0; } -int32_t -maccomp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name, dict_t *xdata) +static +int prepend_xattr_user_namespace(dict_t *dict, char *key, data_t *value, void *obj) { - intptr_t ax = GF_XATTR_NONE; - int i = 0; + xlator_t *this = (xlator_t *) obj; + dict_t *newdict = (dict_t *) this->private; + char *newkey = NULL; + gf_add_prefix(XATTR_USER_PREFIX, key, &newkey); + key = newkey; + dict_set(newdict, (char *)key, value); + if (newkey) + GF_FREE(newkey); + return 0; +} +intptr_t +check_name(const char *name, char **newkey) +{ + intptr_t ax = GF_XATTR_NONE; if (name) { + int i = 0; for (i = 0; i < GF_XATTR_ALL; i++) { if (strcmp (apple_xattr_name[i], name) == 0) { ax = i; - break; } } + gf_add_prefix("user.", name, newkey); } else ax = GF_XATTR_ALL; + return ax; +} - this->private = (void *)ax; +int32_t +maccomp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + char *newkey = NULL; + this->private = (void *) check_name(name, &newkey); + gf_log (this->name, GF_LOG_DEBUG, + "getxattr: name %s private: %p xdata %p ", name, + this->private, xdata); STACK_WIND (frame, maccomp_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, - loc, name, xdata); + loc, newkey, xdata); return 0; } @@ -109,30 +139,17 @@ int32_t maccomp_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { - intptr_t ax = GF_XATTR_NONE; - int i = 0; - - if (name) { - for (i = 0; i < GF_XATTR_ALL; i++) { - if (strcmp (apple_xattr_name[i], name) == 0) { - ax = i; - - break; - } - } - } else - ax = GF_XATTR_ALL; - - this->private = (void *)ax; + char *newkey = NULL; + this->private = (void *) check_name(name, &newkey); STACK_WIND (frame, maccomp_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, - fd, name, xdata); + fd, newkey, xdata); + GF_FREE(newkey); return 0; } - int32_t maccomp_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) @@ -141,12 +158,56 @@ maccomp_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1 && ax != GF_XATTR_NONE) op_ret = op_errno = 0; - + gf_log (this->name, GF_LOG_DEBUG, + "setxattr_cbk op_ret %d op_errno %d private: %p xdata %p ", + op_ret, op_errno, this->private, xdata); STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata); + return 0; +} +int32_t +maccomp_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *iatt1, + struct iatt *iattr2, dict_t *xdata) +{ + gf_log (this->name, GF_LOG_DEBUG, + "setattr_cbk op_ret %d op_errno %d private: %p xdata %p ", + op_ret, op_errno, this->private, xdata); + STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, + iatt1, iattr2, xdata); return 0; } +int map_flags(int flags) +{ + /* DARWIN has different defines on XATTR_ flags. + There do not seem to be a POSIX standard + Parse any other flags over. + NOFOLLOW is always true on Linux and Darwin + */ + int linux_flags = flags & ~(GF_XATTR_CREATE | GF_XATTR_REPLACE | XATTR_REPLACE); + if (XATTR_CREATE & flags) + linux_flags |= GF_XATTR_CREATE; + if (XATTR_REPLACE & flags) + linux_flags |= GF_XATTR_REPLACE; + return linux_flags; +} + +int32_t +maccomp_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) +{ + char *newkey = NULL; + + this->private = (void *) check_name(name, &newkey); + + STACK_WIND (frame, default_fremovexattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fremovexattr, + fd, newkey, xdata); + GF_FREE(newkey); + return 0; +} int32_t maccomp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, @@ -162,16 +223,56 @@ maccomp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, break; } } + dict_t *newdict = dict_new(); + this->private = (void *) newdict; + dict_foreach(dict, prepend_xattr_user_namespace, this); this->private = (void *)ax; - + int linux_flags = map_flags(flags); + gf_log (this->name, GF_LOG_DEBUG, + "setxattr flags: %d -> %d dict %p private: %p xdata %p ", + flags, linux_flags, dict, this->private, xdata); STACK_WIND (frame, maccomp_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, - loc, dict, flags, xdata); + loc, newdict, linux_flags, xdata); + dict_unref(newdict); return 0; } +int32_t +maccomp_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *iattr, + int32_t flags, dict_t *xdata) +{ + gf_log (this->name, GF_LOG_DEBUG, + "setattr iattr %p private: %p xdata %p ", + iattr, this->private, xdata); + STACK_WIND (frame, maccomp_setattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setattr, + loc, iattr, flags, xdata); + return 0; +} + +int32_t +maccomp_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + char *newkey = NULL; + this->private = (void *) check_name(name, &newkey); + + STACK_WIND (frame, default_removexattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->removexattr, + loc, newkey, xdata); + + gf_log (this->name, GF_LOG_TRACE, + "removeattr name %p private: %p xdata %p ", + name, this->private, xdata); + GF_FREE(newkey); + return 0; + +} int32_t maccomp_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, @@ -188,12 +289,20 @@ maccomp_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, } } - this->private = (void *)ax; + dict_t *newdict = dict_new(); + this->private = (void *) newdict; + dict_foreach(dict, prepend_xattr_user_namespace, this); + this->private = (void *)ax; + int linux_flags = map_flags(flags); + gf_log (this->name, GF_LOG_DEBUG, + "fsetxattr flags: %d -> %d dict %p private: %p xdata %p ", + flags, linux_flags, dict, this->private, xdata); STACK_WIND (frame, maccomp_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, - fd, dict, flags, xdata); + fd, newdict, linux_flags, xdata); + dict_unref(newdict); return 0; } @@ -224,10 +333,13 @@ fini (xlator_t *this) struct xlator_fops fops = { - .getxattr = maccomp_getxattr, - .fgetxattr = maccomp_fgetxattr, - .setxattr = maccomp_setxattr, - .fsetxattr = maccomp_fsetxattr, + .getxattr = maccomp_getxattr, + .fgetxattr = maccomp_fgetxattr, + .setxattr = maccomp_setxattr, + .setattr = maccomp_setattr, + .fsetxattr = maccomp_fsetxattr, + .removexattr = maccomp_removexattr, + .fremovexattr = maccomp_fremovexattr, }; struct xlator_cbks cbks; diff --git a/xlators/features/mac-compat/src/mac-compat.h b/xlators/features/mac-compat/src/mac-compat.h new file mode 100644 index 00000000000..b033ca0e4d8 --- /dev/null +++ b/xlators/features/mac-compat/src/mac-compat.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#ifndef __MAC_COMPAT_H__ +#define __MAC_COMPAT_H__ + +enum apple_xattr { + GF_FINDER_INFO_XATTR, + GF_RESOURCE_FORK_XATTR, + GF_XATTR_ALL, + GF_XATTR_NONE +}; + +static char *apple_xattr_name[] = { + [GF_FINDER_INFO_XATTR] = "com.apple.FinderInfo", + [GF_RESOURCE_FORK_XATTR] = "com.apple.ResourceFork" +}; + +static const char *apple_xattr_value[] = { + [GF_FINDER_INFO_XATTR] = + /* 1 2 3 4 5 6 7 8 */ + "\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0", + [GF_RESOURCE_FORK_XATTR] = "" +}; + +static int32_t apple_xattr_len[] = { + [GF_FINDER_INFO_XATTR] = 32, + [GF_RESOURCE_FORK_XATTR] = 1 +}; + +#endif /* __MAC_COMPAT_H__ */ |