From 2a0398dee8521704b90d3f1776a5e380bf8ac5b3 Mon Sep 17 00:00:00 2001 From: Csaba Henk Date: Wed, 12 May 2010 19:10:47 +0000 Subject: added features/mac-compat Signed-off-by: Csaba Henk Signed-off-by: Anand V. Avati BUG: 800 (Problem on OSX with NFS and CIFS exports) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=800 --- configure.ac | 2 + glusterfsd/src/glusterfsd.c | 55 +++--- glusterfsd/src/glusterfsd.h | 2 + libglusterfs/src/compat.c | 86 ---------- libglusterfs/src/compat.h | 30 ---- libglusterfs/src/glusterfs.h | 1 + xlators/features/Makefile.am | 2 +- xlators/features/mac-compat/Makefile.am | 3 + xlators/features/mac-compat/src/Makefile.am | 13 ++ xlators/features/mac-compat/src/mac-compat.c | 247 +++++++++++++++++++++++++++ xlators/mount/fuse/src/fuse-bridge.c | 165 +++++------------- xlators/storage/posix/src/posix.c | 7 +- 12 files changed, 345 insertions(+), 268 deletions(-) create mode 100644 xlators/features/mac-compat/Makefile.am create mode 100644 xlators/features/mac-compat/src/Makefile.am create mode 100644 xlators/features/mac-compat/src/mac-compat.c diff --git a/configure.ac b/configure.ac index 88b8ada46fb..8bc498218a7 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,8 @@ AC_CONFIG_FILES([Makefile xlators/features/quota/src/Makefile xlators/features/read-only/Makefile xlators/features/read-only/src/Makefile + xlators/features/mac-compat/Makefile + xlators/features/mac-compat/src/Makefile xlators/encryption/Makefile xlators/encryption/rot-13/Makefile xlators/encryption/rot-13/src/Makefile diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 12d6be445c6..b01285a085f 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -142,6 +142,8 @@ static struct argp_option gf_options[] = { "Add/override a translator option for a volume with specified value"}, {"read-only", ARGP_READ_ONLY_KEY, 0, 0, "Mount the filesystem in 'read-only' mode"}, + {"mac-compat", ARGP_MAC_COMPAT_KEY, 0, 0, + "Provide stubs for attributes needed for seamless operation on Macs"}, {0, 0, 0, 0, "Fuse options:"}, {"disable-direct-io-mode", ARGP_DISABLE_DIRECT_IO_MODE_KEY, 0, 0, @@ -373,15 +375,21 @@ _add_fuse_mount (xlator_t *graph) } static xlator_t * -_add_ro_volume (xlator_t *graph) +_add_volume (xlator_t *graph, const char *voltype) { cmd_args_t *cmd_args = NULL; xlator_t *top = NULL; glusterfs_ctx_t *ctx = NULL; xlator_list_t *xlchild = NULL; + char *shortvoltype = (char *)voltype; ctx = graph->ctx; cmd_args = &ctx->cmd_args; + for (;;) { + if (*(shortvoltype++) == '/') + break; + assert (*shortvoltype); + } xlchild = CALLOC (sizeof (*xlchild), 1); if (!xlchild) { @@ -390,12 +398,13 @@ _add_ro_volume (xlator_t *graph) xlchild->xlator = graph; top = CALLOC (1, sizeof (*top)); - top->name = strdup ("read-only"); - if (xlator_set_type (top, ZR_XLATOR_READ_ONLY) == -1) { + top->name = strdup (shortvoltype); + if (xlator_set_type (top, voltype) == -1) { fprintf (stderr, - "read-only volume initialization failed"); + "%s volume initialization failed", + shortvoltype); gf_log ("glusterfs", GF_LOG_ERROR, - "read-only initialization failed"); + "%s initialization failed", shortvoltype); return NULL; } top->children = xlchild; @@ -843,6 +852,10 @@ parse_opts (int key, char *arg, struct argp_state *state) cmd_args->read_only = 1; break; + case ARGP_MAC_COMPAT_KEY: + cmd_args->mac_compat = 1; + break; + case ARGP_VOLUME_FILE_KEY: cmd_args->volume_file = gf_strdup (arg); break; @@ -1362,27 +1375,19 @@ main (int argc, char *argv[]) "on client side, exiting\n"); return -1; } - if (!fuse_volume_found && (cmd_args->mount_point != NULL)) { + if (cmd_args->mac_compat) + graph = _add_volume (graph, ZR_XLATOR_MAC_COMPAT); + if (graph && !fuse_volume_found && (cmd_args->mount_point != NULL)) { /* Check for read-only option and add a read-only translator */ - if (cmd_args->read_only) { - if ((graph = _add_ro_volume (graph)) == NULL) { - /* _add_fuse_mount() prints necessary - * error message - */ - fprintf (stderr, - "failed to load 'ro' option. exiting\n"); - gf_log ("glusterfs", GF_LOG_ERROR, "exiting"); - return -1; - } - } - if ((graph = _add_fuse_mount (graph)) == NULL) { - /* _add_fuse_mount() prints necessary - * error message - */ - fprintf (stderr, "exiting\n"); - gf_log ("glusterfs", GF_LOG_ERROR, "exiting"); - return -1; - } + if (cmd_args->read_only) + graph = _add_volume (graph, ZR_XLATOR_READ_ONLY); + if (graph) + graph = _add_fuse_mount (graph); + } + if (!graph) { + fprintf (stderr, "failed to complete xlator graph, exiting\n"); + gf_log ("glusterfs", GF_LOG_ERROR, "exiting"); + return -1; } /* daemonize now */ diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h index f3ee2ed3f84..ec068ec00c2 100644 --- a/glusterfsd/src/glusterfsd.h +++ b/glusterfsd/src/glusterfsd.h @@ -44,6 +44,7 @@ #define ENABLE_DEBUG_MODE 1 #define ZR_XLATOR_READ_ONLY "features/read-only" +#define ZR_XLATOR_MAC_COMPAT "features/mac-compat" #define ZR_XLATOR_FUSE "mount/fuse" #define ZR_MOUNTPOINT_OPT "mountpoint" #define ZR_ATTR_TIMEOUT_OPT "attribute-timeout" @@ -77,6 +78,7 @@ enum argp_option_keys { ARGP_LOG_SERVER_KEY = 146, ARGP_LOG_SERVER_PORT_KEY = 147, ARGP_READ_ONLY_KEY = 148, + ARGP_MAC_COMPAT_KEY = 149, }; /* Moved here from fetch-spec.h */ diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c index 85af45f9a48..891b156d3f5 100644 --- a/libglusterfs/src/compat.c +++ b/libglusterfs/src/compat.c @@ -36,92 +36,6 @@ #include "compat.h" #include "common-utils.h" -#ifdef GF_DARWIN_HOST_OS - -#define GF_FINDER_INFO_XATTR "com.apple.FinderInfo" -#define GF_RESOURCE_FORK_XATTR "com.apple.ResourceFork" -#define GF_FINDER_INFO_SIZE 32 - -static const char gf_finder_info_content[GF_FINDER_INFO_SIZE] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -}; - - -int32_t -gf_darwin_compat_listxattr (int len, dict_t *dict, int size) -{ - data_t *data = NULL; - if (len == -1) - len = 0; - - data = dict_get (dict, GF_FINDER_INFO_XATTR); - if (!data) { - dict_set (dict, GF_FINDER_INFO_XATTR, - bin_to_data ((void *)gf_finder_info_content, - GF_FINDER_INFO_SIZE)); - len += strlen (GF_FINDER_INFO_XATTR); - } - - data = dict_get (dict, GF_RESOURCE_FORK_XATTR); - if (!data) { - dict_set (dict, GF_RESOURCE_FORK_XATTR, str_to_data ("")); - len += strlen (GF_RESOURCE_FORK_XATTR); - } - - return len; -} - -int32_t -gf_darwin_compat_getxattr (const char *key, dict_t *dict) -{ - data_t *data = NULL; - - if (strcmp(key, GF_FINDER_INFO_XATTR) == 0) { - data = dict_get (dict, GF_FINDER_INFO_XATTR); - if (!data) { - dict_set (dict, GF_FINDER_INFO_XATTR, - bin_to_data ((void *)gf_finder_info_content, - GF_FINDER_INFO_SIZE)); - return GF_FINDER_INFO_SIZE; - } - return 0; - } - - if (strcmp(key, GF_RESOURCE_FORK_XATTR) == 0) { - data = dict_get (dict, GF_RESOURCE_FORK_XATTR); - if (!data) { - /* Always null */ - dict_set (dict, GF_RESOURCE_FORK_XATTR, - str_to_data ("")); - return 0; - } - return 0; - } - return -1; -} - - -int32_t -gf_darwin_compat_setxattr (dict_t *dict) -{ - data_t *data = NULL; - - data = dict_get (dict, GF_FINDER_INFO_XATTR); - if (data) - return 0; - data = dict_get (dict, GF_RESOURCE_FORK_XATTR); - if (data) - return 0; - - return -1; -} - -#endif /* DARWIN */ - - #ifdef GF_SOLARIS_HOST_OS int diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index 20db203bf9f..d69d504cbc3 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -321,36 +321,6 @@ dirent_size (struct dirent *entry) } -static inline int32_t -gf_compat_getxattr (const char *key, dict_t *dict) -{ -#ifdef GF_DARWIN_HOST_OS - return gf_darwin_compat_getxattr (key, dict); -#endif - return -1; -} - - -static inline int32_t -gf_compat_setxattr (dict_t *dict) -{ -#ifdef GF_DARWIN_HOST_OS - return gf_darwin_compat_setxattr (dict); -#endif - return -1; -} - - -static inline int32_t -gf_compat_listxattr (int len, dict_t *dict, int size) -{ -#ifdef GF_DARWIN_HOST_OS - return gf_darwin_compat_listxattr (len, dict, size); -#endif - return len; -} - - #ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC /* Linux, Solaris, Cygwin */ #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec) diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 226c358e50c..f6ba4e2efcb 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -210,6 +210,7 @@ struct _cmd_args { char *run_id; int debug_mode; int read_only; + int mac_compat; struct list_head xlator_options; /* list of xlator_option_t */ /* fuse options */ diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am index 303767d350f..6496f3ab0c9 100644 --- a/xlators/features/Makefile.am +++ b/xlators/features/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = locks trash quota read-only access-control #path-converter # filter +SUBDIRS = locks trash quota read-only access-control mac-compat #path-converter # filter CLEANFILES = diff --git a/xlators/features/mac-compat/Makefile.am b/xlators/features/mac-compat/Makefile.am new file mode 100644 index 00000000000..d471a3f9243 --- /dev/null +++ b/xlators/features/mac-compat/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +CLEANFILES = diff --git a/xlators/features/mac-compat/src/Makefile.am b/xlators/features/mac-compat/src/Makefile.am new file mode 100644 index 00000000000..915c13e308f --- /dev/null +++ b/xlators/features/mac-compat/src/Makefile.am @@ -0,0 +1,13 @@ +xlator_LTLIBRARIES = mac-compat.la +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features + +mac_compat_la_LDFLAGS = -module -avoidversion + +mac_compat_la_SOURCES = mac-compat.c +mac_compat_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la + +AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ + -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) + +CLEANFILES = + diff --git a/xlators/features/mac-compat/src/mac-compat.c b/xlators/features/mac-compat/src/mac-compat.c new file mode 100644 index 00000000000..649d2ad5db4 --- /dev/null +++ b/xlators/features/mac-compat/src/mac-compat.c @@ -0,0 +1,247 @@ +/* + Copyright (c) 2008-2010 Gluster, Inc. + This file is part of GlusterFS. + + GlusterFS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + GlusterFS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "xlator.h" +#include "defaults.h" +#include "compat-errno.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 +}; + + +int32_t +maccomp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict) +{ + intptr_t ax = (intptr_t)this->private; + int i = 0; + + 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; + + 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; + + break; + } + } + } + + STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); + + return 0; +} + + +int32_t +maccomp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name) +{ + 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; + + STACK_WIND (frame, maccomp_getxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->getxattr, + loc, name); + return 0; +} + + +int32_t +maccomp_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name) +{ + 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; + + STACK_WIND (frame, maccomp_getxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fgetxattr, + fd, name); + return 0; +} + + +int32_t +maccomp_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno) +{ + intptr_t ax = (intptr_t)this->private; + + if (op_ret == -1 && ax != GF_XATTR_NONE) + op_ret = op_errno = 0; + + STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno); + + return 0; +} + + +int32_t +maccomp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, + int32_t flags) +{ + intptr_t ax = GF_XATTR_NONE; + int i = 0; + + for (i = 0; i < GF_XATTR_ALL; i++) { + if (dict_get (dict, apple_xattr_name[i])) { + ax = i; + + break; + } + } + + this->private = (void *)ax; + + STACK_WIND (frame, maccomp_setxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setxattr, + loc, dict, flags); + return 0; +} + + +int32_t +maccomp_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, + int32_t flags) +{ + intptr_t ax = GF_XATTR_NONE; + int i = 0; + + for (i = 0; i < GF_XATTR_ALL; i++) { + if (dict_get (dict, apple_xattr_name[i])) { + ax = i; + + break; + } + } + + this->private = (void *)ax; + + STACK_WIND (frame, maccomp_setxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, + fd, dict, flags); + return 0; +} + + +int32_t +init (xlator_t *this) +{ + if (!this->children || this->children->next) { + gf_log (this->name, GF_LOG_ERROR, + "translator not configured with exactly one child"); + return -1; + } + + if (!this->parents) { + gf_log (this->name, GF_LOG_WARNING, + "dangling volume. check volfile "); + } + + return 0; +} + + +void +fini (xlator_t *this) +{ + return; +} + + +struct xlator_fops fops = { + .getxattr = maccomp_getxattr, + .fgetxattr = maccomp_fgetxattr, + .setxattr = maccomp_setxattr, + .fsetxattr = maccomp_fsetxattr, +}; + +struct xlator_cbks cbks = { +}; + +struct volume_options options[] = { + { .key = {NULL} }, +}; diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 9f210aa73ba..1adbddadf68 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -53,9 +53,6 @@ #include "list.h" #include "dict.h" -#include "compat.h" -#include "compat-errno.h" - /* TODO: when supporting posix acl, remove this definition */ #define DISABLE_POSIX_ACL @@ -69,6 +66,7 @@ #define MAX_FUSE_PROC_DELAY 1 static int gf_fuse_conn_err_log; +static int gf_fuse_xattr_enotsup_log; typedef struct fuse_in_header fuse_in_header_t; typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh, @@ -1087,11 +1085,9 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg) } -static int gf_fuse_xattr_enotsup_log; static int -fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) +fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno) { fuse_state_t *state = frame->root->state; fuse_in_header_t *finh = state->finh; @@ -1104,32 +1100,12 @@ fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, send_fuse_err (this, finh, 0); } else { - if (frame->root->op == GF_FOP_SETXATTR) { - op_ret = gf_compat_setxattr (state->dict); - if (op_ret == 0) - op_errno = 0; - if (op_errno == ENOTSUP) { - gf_fuse_xattr_enotsup_log++; - if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER)) - gf_log ("glusterfs-fuse", - GF_LOG_CRITICAL, - "extended attribute not " - "supported by the backend " - "storage"); - } - } else { - if ((frame->root->op == GF_FOP_REMOVEXATTR) - && (op_errno == ENOATTR)) { - goto nolog; - } - gf_log ("glusterfs-fuse", GF_LOG_WARNING, - "%"PRIu64": %s() %s => -1 (%s)", - frame->root->unique, - gf_fop_list[frame->root->op], - state->loc.path ? state->loc.path : "ERR", - strerror (op_errno)); - } - nolog: + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "%"PRIu64": %s() %s => -1 (%s)", + frame->root->unique, + gf_fop_list[frame->root->op], + state->loc.path ? state->loc.path : "ERR", + strerror (op_errno)); send_fuse_err (this, finh, op_errno); } @@ -1142,54 +1118,25 @@ fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, static int -fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf) { - fuse_state_t *state = frame->root->state; - fuse_in_header_t *finh = state->finh; - - if (op_ret == 0) { - gf_log ("glusterfs-fuse", GF_LOG_TRACE, - "%"PRIu64": %s() %s => 0", frame->root->unique, - gf_fop_list[frame->root->op], - state->loc.path ? state->loc.path : "ERR"); - - send_fuse_err (this, finh, 0); - } else { - if (frame->root->op == GF_FOP_SETXATTR) { - op_ret = gf_compat_setxattr (state->dict); - if (op_ret == 0) - op_errno = 0; - if (op_errno == ENOTSUP) { - gf_fuse_xattr_enotsup_log++; - if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER)) - gf_log ("glusterfs-fuse", - GF_LOG_CRITICAL, - "extended attribute not " - "supported by the backend " - "storage"); - } - } else { - if ((frame->root->op == GF_FOP_REMOVEXATTR) - && (op_errno == ENOATTR)) { - goto nolog; - } - gf_log ("glusterfs-fuse", GF_LOG_WARNING, - "%"PRIu64": %s() %s => -1 (%s)", - frame->root->unique, - gf_fop_list[frame->root->op], - state->loc.path ? state->loc.path : "ERR", - strerror (op_errno)); - } - nolog: + return fuse_err_cbk (frame, cookie, this, op_ret, op_errno); +} - send_fuse_err (this, finh, op_errno); - } - free_state (state); - STACK_DESTROY (frame->root); +static int +fuse_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno) +{ + if (op_ret == -1 && op_errno == ENOTSUP) + GF_LOG_OCCASIONALLY (gf_fuse_xattr_enotsup_log, + "glusterfs-fuse", GF_LOG_CRITICAL, + "extended attribute not supported " + "by the backend storage"); - return 0; + return fuse_err_cbk (frame, cookie, this, op_ret, op_errno); } @@ -2448,7 +2395,7 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", finh->unique, state->loc.path, finh->nodeid, name); - FUSE_FOP (state, fuse_err_cbk, GF_FOP_SETXATTR, + FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_SETXATTR, setxattr, &state->loc, state->dict, fsi->flags); return; @@ -2485,47 +2432,19 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, char *value = ""; fuse_state_t *state = NULL; fuse_in_header_t *finh = NULL; - int32_t dummy_ret = 0; data_t *value_data = NULL; fuse_private_t *priv = NULL; struct stat st; char *file = NULL; int32_t fd = -1; - int ret = -1; int32_t len = 0; data_pair_t *trav = NULL; priv = this->private; - ret = op_ret; state = frame->root->state; finh = state->finh; - dummy_ret = 0; - -#ifdef GF_DARWIN_HOST_OS - /* This is needed in MacFuse, where MacOSX Finder needs some specific - * keys to be supported from FS - */ - - if (state->name) { - if (!dict) { - dict = get_new_dict (); - need_to_free_dict = 1; - } - dummy_ret = gf_compat_getxattr (state->name, dict); - if (dummy_ret != -1) - ret = dummy_ret; - } else { - if (!dict) { - dict = get_new_dict (); - need_to_free_dict = 1; - } - dummy_ret = gf_compat_listxattr (ret, dict, state->size); - if (dummy_ret != -1) - ret = dummy_ret; - } -#endif /* DARWIN */ - if (ret >= 0) { + if (op_ret >= 0) { gf_log ("glusterfs-fuse", GF_LOG_TRACE, "%"PRIu64": %s() %s => %d", frame->root->unique, gf_fop_list[frame->root->op], state->loc.path, op_ret); @@ -2535,17 +2454,15 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* if callback for getxattr */ value_data = dict_get (dict, state->name); if (value_data) { - ret = value_data->len; /* Don't return the value for '\0' */ - value = value_data->data; - - send_fuse_xattr (this, finh, value, ret, state->size); - /* if(ret >...)...else if...else */ + send_fuse_xattr (this, finh, value_data->data, + value_data->len, /* Don't return the value for '\0' */ + state->size); + /* if(op_ret >...)...else if...else */ } else if (!strcmp (state->name, "user.glusterfs-booster-volfile")) { if (!priv->volfile) { memset (&st, 0, sizeof (st)); fd = fileno (this->ctx->specfp); - ret = fstat (fd, &st); - if (ret != 0) { + if (fstat (fd, &st) != 0) { gf_log (this->name, GF_LOG_ERROR, "fstat on fd (%d) failed (%s)", fd, strerror (errno)); @@ -2555,15 +2472,15 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, priv->volfile_size = st.st_size; file = priv->volfile = GF_CALLOC (1, priv->volfile_size, gf_fuse_mt_char); - ret = lseek (fd, 0, SEEK_SET); - while ((ret = read (fd, file, GF_UNIT_KB)) > 0) { - file += ret; + len = lseek (fd, 0, SEEK_SET); + while ((len = read (fd, file, GF_UNIT_KB)) > 0) { + file += len; } } send_fuse_xattr (this, finh, priv->volfile, priv->volfile_size, state->size); - /* if(ret >...)...else if...else */ + /* if(op_ret >...)...else if...else */ } else if (!strcmp (state->name, "user.glusterfs-booster-path")) { send_fuse_xattr (this, finh, state->loc.path, strlen (state->loc.path) + 1, state->size); @@ -2597,12 +2514,12 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_errno != ENODATA) { if (op_errno == ENOTSUP) { - gf_fuse_xattr_enotsup_log++; - if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER)) - gf_log ("glusterfs-fuse", GF_LOG_ERROR, - "extended attribute not " - "supported by the backend " - "storage"); + GF_LOG_OCCASIONALLY (gf_fuse_xattr_enotsup_log, + "glusterfs-fuse", + GF_LOG_ERROR, + "extended attribute not " + "supported by the backend " + "storage"); } else { diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 677aa0270da..22e9fcecb23 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3025,7 +3025,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, { struct posix_private *priv = NULL; int32_t op_ret = -1; - int32_t op_errno = ENOENT; + int32_t op_errno = 0; int32_t list_offset = 0; size_t size = 0; size_t remaining_size = 0; @@ -3134,8 +3134,11 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, } op_ret = sys_lgetxattr (real_path, key, value, op_ret); - if (op_ret == -1) + if (op_ret == -1) { + op_errno = errno; + break; + } value [op_ret] = '\0'; if (strcmp (key, gen_key) != 0) -- cgit