diff options
Diffstat (limited to 'xlators/storage/posix/src')
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 39 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 182 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 10 |
3 files changed, 197 insertions, 34 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 5725cad7d92..ab46f7f7e95 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -784,6 +784,27 @@ out: return op_ret; } +#ifdef GF_DARWIN_HOST_OS +static +void posix_dump_buffer (xlator_t *this, const char *real_path, const char *key, + data_t *value, int flags) +{ + char buffer[3*value->len+1]; + int index = 0; + buffer[0] = 0; + gf_loglevel_t log_level = gf_log_get_loglevel (); + if (log_level == GF_LOG_TRACE) { + char *data = (char *) value->data; + for (index = 0; index < value->len; index++) + sprintf(buffer+3*index, " %02x", data[index]); + } + gf_log (this->name, GF_LOG_DEBUG, + "Dump %s: key:%s flags: %u length:%u data:%s ", + real_path, key, flags, value->len, + (log_level == GF_LOG_TRACE ? buffer : "<skipped in DEBUG>")); +} +#endif + static int gf_xattr_enotsup_log; int @@ -802,7 +823,9 @@ posix_handle_pair (xlator_t *this, const char *real_path, } else { sys_ret = sys_lsetxattr (real_path, key, value->data, value->len, flags); - +#ifdef GF_DARWIN_HOST_OS + posix_dump_buffer(this, real_path, key, value, flags); +#endif if (sys_ret < 0) { ret = -errno; if (errno == ENOTSUP) { @@ -825,13 +848,13 @@ posix_handle_pair (xlator_t *this, const char *real_path, gf_log (this->name, ((errno == EINVAL) ? GF_LOG_DEBUG : GF_LOG_ERROR), - "%s: key:%s error:%s", - real_path, key, + "%s: key:%s flags: %u length:%d error:%s", + real_path, key, flags, value->len, strerror (errno)); #else /* ! DARWIN */ gf_log (this->name, GF_LOG_ERROR, - "%s: key:%s error:%s", - real_path, key, + "%s: key:%s flags: %u length:%d error:%s", + real_path, key, flags, value->len, strerror (errno)); #endif /* DARWIN */ } @@ -1430,12 +1453,10 @@ posix_fsyncer_process (xlator_t *this, call_stub_t *stub, gf_boolean_t do_fsync) } if (do_fsync) { -#ifdef HAVE_FDATASYNC if (stub->args.datasync) - ret = fdatasync (pfd->fd); + ret = sys_fdatasync (pfd->fd); else -#endif - ret = fsync (pfd->fd); + ret = sys_fsync (pfd->fd); } else { ret = 0; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 588079d9225..d33b5027ef5 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -761,7 +761,7 @@ posix_do_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, if (ret < 0) { ret = -errno; gf_log(this->name, GF_LOG_ERROR, - "zerofill failed on fd %d length %ld %s", + "zerofill failed on fd %d length %" PRId64 " %s", pfd->fd, len, strerror(errno)); goto out; } @@ -2859,16 +2859,14 @@ posix_fsync (call_frame_t *frame, xlator_t *this, if (datasync) { ; -#ifdef HAVE_FDATASYNC - op_ret = fdatasync (_fd); + op_ret = sys_fdatasync (_fd); if (op_ret == -1) { gf_log (this->name, GF_LOG_ERROR, "fdatasync on fd=%p failed: %s", fd, strerror (errno)); } -#endif } else { - op_ret = fsync (_fd); + op_ret = sys_fsync (_fd); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -2911,6 +2909,23 @@ _handle_setxattr_keyvalue_pair (dict_t *d, char *k, data_t *v, filler->flags); } +#ifdef GF_DARWIN_HOST_OS +static inline int +map_xattr_flags(int flags) +{ + /* DARWIN has different defines on XATTR_ flags. + There do not seem to be a POSIX standard + Parse any other flags over. + */ + int darwinflags = flags & ~(GF_XATTR_CREATE | GF_XATTR_REPLACE | XATTR_REPLACE); + if (GF_XATTR_CREATE & flags) + darwinflags |= XATTR_CREATE; + if (GF_XATTR_REPLACE & flags) + darwinflags |= XATTR_REPLACE; + return darwinflags; +} +#endif + int32_t posix_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int flags, dict_t *xdata) @@ -2937,7 +2952,11 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, filler.real_path = real_path; filler.this = this; +#ifdef GF_DARWIN_HOST_OS + filler.flags = map_xattr_flags(flags); +#else filler.flags = flags; +#endif op_ret = dict_foreach (dict, _handle_setxattr_keyvalue_pair, &filler); if (op_ret < 0) { @@ -3354,7 +3373,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, char *list = NULL; int32_t list_offset = 0; size_t remaining_size = 0; - char key[4096] = {0,}; + char keybuffer[4096] = {0,}; DECLARE_OLD_FS_ID_VAR; @@ -3522,8 +3541,20 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, } if (name) { - strcpy (key, name); - + strcpy (keybuffer, name); + char *key = keybuffer; +#if defined(GF_DARWIN_HOST_OS_DISABLED) + if (priv->xattr_user_namespace == XATTR_STRIP) { + if (strncmp(key, "user.",5) == 0) { + key += 5; + gf_log (this->name, + GF_LOG_DEBUG, + "getxattr for file %s" + " stripping user key: %s -> %s", + real_path, keybuffer, key); + } + } +#endif size = sys_lgetxattr (real_path, key, NULL, 0); if (size <= 0) { op_errno = errno; @@ -3611,14 +3642,13 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, while (remaining_size > 0) { if (*(list + list_offset) == '\0') break; - - strcpy (key, list + list_offset); - size = sys_lgetxattr (real_path, key, NULL, 0); + strcpy (keybuffer, list + list_offset); + size = sys_lgetxattr (real_path, keybuffer, NULL, 0); if (size == -1) { op_ret = -1; op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "getxattr failed on " - "%s: key = %s (%s)", real_path, key, + "%s: key = %s (%s)", real_path, keybuffer, strerror (op_errno)); break; } @@ -3630,29 +3660,37 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, goto out; } - size = sys_lgetxattr (real_path, key, value, size); + size = sys_lgetxattr (real_path, keybuffer, value, size); if (size == -1) { op_ret = -1; op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "getxattr failed on " - "%s: key = %s (%s)", real_path, key, + "%s: key = %s (%s)", real_path, keybuffer, strerror (op_errno)); GF_FREE (value); break; } value [size] = '\0'; - op_ret = dict_set_dynptr (dict, key, value, size); +#ifdef GF_DARWIN_HOST_OS + /* The protocol expect namespace for now */ + char *newkey = NULL; + gf_add_prefix (XATTR_USER_PREFIX, keybuffer, &newkey); + strcpy (keybuffer, newkey); + GF_FREE (newkey); +#endif + op_ret = dict_set_dynptr (dict, keybuffer, value, size); if (op_ret < 0) { op_errno = -op_ret; gf_log (this->name, GF_LOG_ERROR, "dict set operation " - "on %s for the key %s failed.", real_path, key); + "on %s for the key %s failed.", real_path, + keybuffer); GF_FREE (value); goto out; } - remaining_size -= strlen (key) + 1; - list_offset += strlen (key) + 1; + remaining_size -= strlen (keybuffer) + 1; + list_offset += strlen (keybuffer) + 1; } /* while (remaining_size > 0) */ @@ -3729,7 +3767,16 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, if (name) { strcpy (key, name); - +#ifdef GF_DARWIN_HOST_OS + struct posix_private *priv = NULL; + priv = this->private; + if (priv->xattr_user_namespace == XATTR_STRIP) { + char *newkey = NULL; + gf_add_prefix (XATTR_USER_PREFIX, key, &newkey); + strcpy (key, newkey); + GF_FREE (newkey); + } +#endif size = sys_fgetxattr (_fd, key, NULL, 0); if (size <= 0) { op_errno = errno; @@ -3832,6 +3879,7 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, } value [size] = '\0'; + op_ret = dict_set_dynptr (dict, key, value, size); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, "dict set operation " @@ -3910,7 +3958,11 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, filler.fd = _fd; filler.this = this; +#ifdef GF_DARWIN_HOST_OS + filler.flags = map_xattr_flags(flags); +#else filler.flags = flags; +#endif op_ret = dict_foreach (dict, _handle_fsetxattr_keyvalue_pair, &filler); if (op_ret < 0) { @@ -3935,7 +3987,17 @@ _posix_remove_xattr (dict_t *dict, char *key, data_t *value, void *data) filler = (posix_xattr_filler_t *) data; this = filler->this; - +#ifdef GF_DARWIN_HOST_OS + struct posix_private *priv = NULL; + priv = (struct posix_private *) this->private; + char *newkey = NULL; + if (priv->xattr_user_namespace == XATTR_STRIP) { + gf_remove_prefix (XATTR_USER_PREFIX, key, &newkey); + gf_log("remove_xattr", GF_LOG_DEBUG, "key %s => %s" , key, + newkey); + key = newkey; + } +#endif op_ret = sys_lremovexattr (filler->real_path, key); if (op_ret == -1) { filler->op_errno = errno; @@ -3944,7 +4006,9 @@ _posix_remove_xattr (dict_t *dict, char *key, data_t *value, void *data) "removexattr failed on %s (for %s): %s", filler->real_path, key, strerror (errno)); } - +#ifdef GF_DARWIN_HOST_OS + GF_FREE(newkey); +#endif return op_ret; } @@ -4176,10 +4240,19 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v, 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); +#ifdef GF_DARWIN_HOST_OS + struct posix_private *priv = NULL; + priv = this->private; + if (priv->xattr_user_namespace == XATTR_STRIP) { + if (strncmp(k, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) == 0) { + k += XATTR_USER_PREFIX_LEN; + } + } +#endif + LOCK (&inode->lock); { if (filler->real_path) { @@ -5135,6 +5208,23 @@ set_batch_fsync_mode (struct posix_private *priv, const char *str) return 0; } +#ifdef GF_DARWIN_HOST_OS +static int +set_xattr_user_namespace_mode (struct posix_private *priv, const char *str) +{ + if (strcmp (str, "none") == 0) + priv->xattr_user_namespace = XATTR_NONE; + else if (strcmp (str, "strip") == 0) + priv->xattr_user_namespace = XATTR_STRIP; + else if (strcmp (str, "append") == 0) + priv->xattr_user_namespace = XATTR_APPEND; + else if (strcmp (str, "both") == 0) + priv->xattr_user_namespace = XATTR_BOTH; + else + return -1; + return 0; +} +#endif int reconfigure (xlator_t *this, dict_t *options) @@ -5164,6 +5254,21 @@ reconfigure (xlator_t *this, dict_t *options) goto out; } +#ifdef GF_DARWIN_HOST_OS + + char *xattr_user_namespace_mode_str = NULL; + + GF_OPTION_RECONF ("xattr-user-namespace-mode", xattr_user_namespace_mode_str, + options, str, out); + + if (set_xattr_user_namespace_mode (priv, xattr_user_namespace_mode_str) != 0) { + gf_log (this->name, GF_LOG_ERROR, "Unknown xattr user namespace mode string: %s", + xattr_user_namespace_mode_str); + goto out; + } + +#endif + GF_OPTION_RECONF ("linux-aio", priv->aio_configured, options, bool, out); @@ -5351,7 +5456,8 @@ init (xlator_t *this) dir_data->data); ret = -1; goto out; - } else if ((size == -1) && (errno != ENODATA)) { + } else if ((size == -1) && (errno != ENODATA) && + (errno != ENOATTR)) { /* Wrong 'gfid' is set, it should be error */ gf_log (this->name, GF_LOG_WARNING, "%s: failed to fetch gfid (%s)", @@ -5610,8 +5716,24 @@ init (xlator_t *this) goto out; } - GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec, - uint32, out); +#ifdef GF_DARWIN_HOST_OS + + char *xattr_user_namespace_mode_str = NULL; + + GF_OPTION_INIT ("xattr-user-namespace-mode", + xattr_user_namespace_mode_str, str, out); + + if (set_xattr_user_namespace_mode (_private, + xattr_user_namespace_mode_str) != 0) { + gf_log (this->name, GF_LOG_ERROR, + "Unknown xattr user namespace mode string: %s", + xattr_user_namespace_mode_str); + goto out; + } +#endif + + GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec, + uint32, out); out: return ret; } @@ -5769,5 +5891,15 @@ struct volume_options options[] = { .default_value = "off", .description = "Enable placeholders for gfid to path conversion" }, +#if GF_DARWIN_HOST_OS + { .key = {"xattr-user-namespace-mode"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "none", + .description = "Option to control XATTR user namespace on the raw filesystem: " + "\t- None: Will use the user namespace, so files will be exchangable with Linux.\n" + " The raw filesystem will not be compatible with OS X Finder.\n" + "\t- Strip: Will strip the user namespace before setting. The raw filesystem will work in OS X.\n" + }, +#endif { .key = {NULL} } }; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 91e0664ed2d..c9bfc984da5 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -158,6 +158,16 @@ struct posix_private { uint32_t health_check_interval; pthread_t health_check; gf_boolean_t health_check_active; + +#ifdef GF_DARWIN_HOST_OS + enum { + XATTR_NONE = 0, + XATTR_STRIP, + XATTR_APPEND, + XATTR_BOTH, + } xattr_user_namespace; +#endif + }; typedef struct { |