summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVarsha Rao <varao@redhat.com>2018-02-12 10:37:15 +0530
committerVarsha Rao <varshar16@review.gluster.org>2018-02-21 09:52:17 +0000
commitd0e7177416be3005b3f092addf0bba4dd9dc7a2d (patch)
tree34158ebb910b6de730f47dc2d903da7040809d47
parent49e57efa515f12013da9f5293846aff17ac48f7d (diff)
xlators/features/namespace: Add namespace xlator and link into brick graph
The following release-3.8-fb branch patch is upstreamed: > features/namespace: Add namespace xlator and link into brick graph > Commit ID: dbd30776f26e > https://review.gluster.org/#/c/18041/ > By Michael Goulet <mgoulet@fb.com> Changes in this patch: Removes extra config.h and namespace.h file in namespace.c Adds default_getspec_cbk to libglusterfs.sym Rename dict_for_each to dict_foreach_inline Remove fd.h header file stack.h Add test case for truncate, open and symlink This patch is required to forward port io-threads namespace patch. Updates: #401 Change-Id: Ib88c95b89eecee9b8957df8a4c8712c899c761d1 Signed-off-by: Varsha Rao <varao@redhat.com>
-rw-r--r--configure.ac2
-rw-r--r--glusterfs.spec.in1
-rw-r--r--libglusterfs/src/dict.h2
-rw-r--r--libglusterfs/src/libglusterfs.sym1
-rw-r--r--libglusterfs/src/stack.h9
-rw-r--r--tests/basic/namespace.t104
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c7
-rw-r--r--xlators/debug/io-stats/src/io-stats.c2
-rw-r--r--xlators/features/Makefile.am2
-rw-r--r--xlators/features/namespace/Makefile.am3
-rw-r--r--xlators/features/namespace/src/Makefile.am17
-rw-r--r--xlators/features/namespace/src/namespace.c1367
-rw-r--r--xlators/features/namespace/src/namespace.h23
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c28
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c11
-rw-r--r--xlators/performance/io-threads/src/io-threads.c58
16 files changed, 1582 insertions, 55 deletions
diff --git a/configure.ac b/configure.ac
index f463b43d0ca..35e4f27a130 100644
--- a/configure.ac
+++ b/configure.ac
@@ -150,6 +150,8 @@ AC_CONFIG_FILES([Makefile
xlators/features/read-only/src/Makefile
xlators/features/compress/Makefile
xlators/features/compress/src/Makefile
+ xlators/features/namespace/Makefile
+ xlators/features/namespace/src/Makefile
xlators/features/quiesce/Makefile
xlators/features/quiesce/src/Makefile
xlators/features/barrier/Makefile
diff --git a/glusterfs.spec.in b/glusterfs.spec.in
index d2e280c98b5..1c3c51b6513 100644
--- a/glusterfs.spec.in
+++ b/glusterfs.spec.in
@@ -1086,6 +1086,7 @@ exit 0
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/cdc.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/changelog.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/gfid-access.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/namespace.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/read-only.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/shard.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/snapview-client.so
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
index 1ce055a5940..e481330d6b5 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -62,7 +62,7 @@ typedef struct _data_pair data_pair_t;
#define DICT_KEY_VALUE_MAX_SIZE 1048576
-#define dict_for_each(d, c) for (c = d->members_list; c; c = c->next)
+#define dict_foreach_inline(d, c) for (c = d->members_list; c; c = c->next)
struct _data {
unsigned char is_static:1;
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
index b8dc496421c..c3d2e72527b 100644
--- a/libglusterfs/src/libglusterfs.sym
+++ b/libglusterfs/src/libglusterfs.sym
@@ -221,6 +221,7 @@ default_getactivelk
default_getactivelk_failure_cbk
default_getactivelk_resume
default_getspec
+default_getspec_cbk
default_getxattr
default_getxattr_cbk
default_getxattr_failure_cbk
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index 4a3a788f5ee..e7d0b3ff7f4 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -83,6 +83,13 @@ struct _call_frame {
const char *unwind_to;
};
+struct _ns_info {
+ uint32_t hash; /* Hash of the namespace from SuperFastHash */
+ gf_boolean_t found; /* Set to true if we found a namespace */
+};
+
+typedef struct _ns_info ns_info_t;
+
#define SMALL_GROUP_COUNT 128
struct _call_stack {
@@ -122,6 +129,8 @@ struct _call_stack {
send information over the wire too */
struct timespec ctime; /* timestamp, most probably set at
creation of stack. */
+
+ ns_info_t ns_info;
};
diff --git a/tests/basic/namespace.t b/tests/basic/namespace.t
new file mode 100644
index 00000000000..ea473abbc1c
--- /dev/null
+++ b/tests/basic/namespace.t
@@ -0,0 +1,104 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+. $(dirname $0)/../nfs.rc
+
+# These hashes are a result of calling SuperFastHash
+# on the corresponding folder names.
+NAMESPACE_HASH=28153613
+NAMESPACE2_HASH=3926991974
+NAMESPACE3_HASH=3493960770
+
+function check_samples() {
+ local FOP_TYPE=$1
+ local NS_HASH=$2
+ local FILE=$3
+ local BRICK=$4
+ local GFID="$(getfattr -n trusted.gfid -e text --only-values $B0/$BRICK$FILE | xxd -p)"
+
+ grep -i "ns_$OP" /var/log/glusterfs/bricks/d-backends-$BRICK.log |
+ grep -- $NS_HASH | sed 's/\-//g' | grep -- $GFID
+ if [ $? -eq 0 ]; then
+ echo "Y"
+ else
+ echo "N"
+ fi
+}
+
+cleanup;
+
+TEST mkdir -p $B0/${V0}{0,1,2,3,4,5,6,7,8,9}
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2,3,4,5,6,7,8}
+TEST $CLI volume set $V0 nfs.disable off
+TEST $CLI volume set $V0 performance.stat-prefetch off
+TEST $CLI volume set $V0 performance.nfs.stat-prefetch off
+TEST $CLI volume set $V0 cluster.read-subvolume-index 0
+TEST $CLI volume set $V0 diagnostics.brick-log-level DEBUG
+TEST $CLI volume set $V0 features.tag-namespaces on
+TEST $CLI volume set $V0 storage.build-pgfid on
+TEST $CLI volume start $V0
+
+sleep 2
+
+TEST mount_nfs $H0:/$V0 $N0 nolock;
+
+################################
+# Paths in the samples #
+################################
+
+mkdir -p $N0/namespace
+
+# subvol_1 = bar, subvol_2 = foo, subvol_3 = hey
+# Test create, write (tagged by loc, fd respectively).
+touch $N0/namespace/{bar,foo,hey}
+echo "garbage" > $N0/namespace/bar
+echo "garbage" > $N0/namespace/foo
+echo "garbage" > $N0/namespace/hey
+EXPECT_WITHIN 10 "Y" check_samples CREATE $NAMESPACE_HASH /namespace/bar patchy0
+EXPECT_WITHIN 10 "Y" check_samples CREATE $NAMESPACE_HASH /namespace/foo patchy3
+EXPECT_WITHIN 10 "Y" check_samples CREATE $NAMESPACE_HASH /namespace/hey patchy6
+EXPECT_WITHIN 10 "Y" check_samples WRITEV $NAMESPACE_HASH /namespace/bar patchy0
+EXPECT_WITHIN 10 "Y" check_samples WRITEV $NAMESPACE_HASH /namespace/foo patchy3
+EXPECT_WITHIN 10 "Y" check_samples WRITEV $NAMESPACE_HASH /namespace/hey patchy6
+
+# Test stat (tagged by loc)
+stat $N0/namespace/bar &> /dev/null
+stat $N0/namespace/foo &> /dev/null
+stat $N0/namespace/hey &> /dev/null
+EXPECT_WITHIN 10 "Y" check_samples STAT $NAMESPACE_HASH /namespace/bar patchy0
+EXPECT_WITHIN 10 "Y" check_samples STAT $NAMESPACE_HASH /namespace/foo patchy3
+EXPECT_WITHIN 10 "Y" check_samples STAT $NAMESPACE_HASH /namespace/hey patchy6
+
+EXPECT_WITHIN 10 "Y" umount_nfs $N0;
+sleep 1
+TEST mount_nfs $H0:/$V0 $N0 nolock;
+
+cat $N0/namespace/bar &> /dev/null
+EXPECT_WITHIN 10 "Y" check_samples READ $NAMESPACE_HASH /namespace/bar patchy0
+
+dir $N0/namespace &> /dev/null
+EXPECT_WITHIN 10 "Y" check_samples LOOKUP $NAMESPACE_HASH /namespace patchy0
+
+mkdir -p $N0/namespace{2,3}
+EXPECT_WITHIN 10 "Y" check_samples MKDIR $NAMESPACE2_HASH /namespace2 patchy0
+EXPECT_WITHIN 10 "Y" check_samples MKDIR $NAMESPACE3_HASH /namespace3 patchy0
+
+touch $N0/namespace2/file
+touch $N0/namespace3/file
+EXPECT_WITHIN 10 "Y" check_samples CREATE $NAMESPACE2_HASH /namespace2/file patchy0
+EXPECT_WITHIN 10 "Y" check_samples CREATE $NAMESPACE3_HASH /namespace3/file patchy0
+
+truncate -s 0 $N0/namespace/bar
+EXPECT_WITHIN 10 "Y" check_samples TRUNCATE $NAMESPACE_HASH /namespace/bar patchy0
+
+ln -s $N0/namespace/foo $N0/namespace/foo_link
+EXPECT_WITHIN 10 "Y" check_samples SYMLINK $NAMESPACE_HASH /namespace/foo patchy3
+
+open $N0/namespace/hey
+EXPECT_WITHIN 10 "Y" check_samples OPEN $NAMESPACE_HASH /namespace/hey patchy6
+
+cleanup;
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
index cdd22475cbe..8d3c823043f 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -1651,10 +1651,9 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
* Heal daemons don't have IO threads ... and as a result they
* send this getxattr down and eventually crash :(
*/
- if (strcmp (name, IO_THREADS_QUEUE_SIZE_KEY) == 0) {
- ret = -EINVAL;
- goto out;
- }
+ op_errno = -1;
+ GF_CHECK_XATTR_KEY_AND_GOTO(name, IO_THREADS_QUEUE_SIZE_KEY, op_errno,
+ out);
/*
* Special xattrs which need responses from all subvols
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
index 985c5fbc389..6ddad96d8aa 100644
--- a/xlators/debug/io-stats/src/io-stats.c
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -962,7 +962,7 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
*/
data_pair_t *curr = NULL;
- dict_for_each (xattr, curr) {
+ dict_foreach_inline (xattr, curr) {
ios_log (this, logfp,
"\"%s.%s.%s.queue_size\": \"%d\",",
key_prefix, str_prefix, curr->key,
diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am
index 1e24679903d..1a2bc70ec68 100644
--- a/xlators/features/Makefile.am
+++ b/xlators/features/Makefile.am
@@ -1,5 +1,5 @@
SUBDIRS = locks quota read-only quiesce marker index barrier \
arbiter compress changelog changetimerecorder \
gfid-access $(GLUPY_SUBDIR) upcall snapview-client snapview-server \
- trash shard bit-rot leases selinux sdfs
+ trash shard bit-rot leases selinux sdfs namespace
CLEANFILES =
diff --git a/xlators/features/namespace/Makefile.am b/xlators/features/namespace/Makefile.am
new file mode 100644
index 00000000000..a985f42a877
--- /dev/null
+++ b/xlators/features/namespace/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/features/namespace/src/Makefile.am b/xlators/features/namespace/src/Makefile.am
new file mode 100644
index 00000000000..e355d42cf4e
--- /dev/null
+++ b/xlators/features/namespace/src/Makefile.am
@@ -0,0 +1,17 @@
+xlator_LTLIBRARIES = namespace.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
+
+namespace_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS)
+
+namespace_la_SOURCES = namespace.c
+namespace_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = namespace.h
+
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \
+ -I$(top_srcdir)/xlators/lib/src
+
+AM_CFLAGS = -Wall $(GF_CFLAGS)
+
+CLEANFILES =
diff --git a/xlators/features/namespace/src/namespace.c b/xlators/features/namespace/src/namespace.c
new file mode 100644
index 00000000000..cabd247da0c
--- /dev/null
+++ b/xlators/features/namespace/src/namespace.c
@@ -0,0 +1,1367 @@
+/*
+ * Copyright (c) 2008-2012 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.
+ *
+ * xlators/features/namespace:
+ * This translator tags each request with a namespace hash,
+ * which then can be used in later translators to track and
+ * throttle fops per namespace.
+ */
+
+#include <sys/types.h>
+
+#include "defaults.h"
+#include "glusterfs.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "namespace.h"
+
+/* Return codes for common path parsing functions. */
+enum _path_parse_result {
+ PATH_PARSE_RESULT_NO_PATH = 0,
+ PATH_PARSE_RESULT_FOUND = 1,
+ PATH_PARSE_RESULT_IS_GFID = 2,
+};
+
+typedef enum _path_parse_result path_parse_result_t;
+
+/* Clean up an ns_local struct. Wipe a loc (its inode is ref'd, so we're good.)
+ */
+static inline void
+ns_local_cleanup (ns_local_t *local)
+{
+ if (!local) {
+ return;
+ }
+
+ loc_wipe (&local->loc);
+ GF_FREE (local);
+}
+
+/* Create a new ns_local. We ref the inode, fake a new loc struct, and stash
+ * the stub given to us. */
+static inline ns_local_t *
+ns_local_new (call_stub_t *stub, inode_t *inode)
+{
+ ns_local_t *local = NULL;
+ loc_t loc = {0, };
+
+ if (!stub || !inode) {
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (ns_local_t), 0);
+ if (local == NULL) {
+ goto out;
+ }
+
+ /* Set up a fake loc_t struct to give to the getxattr call. */
+ gf_uuid_copy (loc.gfid, inode->gfid);
+ loc.inode = inode_ref (inode);
+
+ /* If for some reason inode_ref() fails, then just give up. */
+ if (!loc.inode) {
+ GF_FREE (local);
+ goto out;
+ }
+
+ local->stub = stub;
+ local->loc = loc;
+
+out:
+ return local;
+}
+
+/* Try parsing a path string. If the path string is a GFID, then return
+ * with PATH_PARSE_RESULT_IS_GFID. If we have no namespace (i.e. '/') then
+ * return PATH_PARSE_RESULT_NO_PATH and set the hash to 1. Otherwise, hash the
+ * namespace and store it in the info struct. */
+static path_parse_result_t
+parse_path (ns_info_t *info, const char *path)
+{
+ int len = 0;
+ const char *ns_begin = path;
+ const char *ns_end = NULL;
+
+ if (!path || strlen (path) == 0) {
+ return PATH_PARSE_RESULT_NO_PATH;
+ }
+
+ if (path[0] == '<') {
+ return PATH_PARSE_RESULT_IS_GFID;
+ }
+
+ /* Right now we only want the top-level directory, so
+ * skip the initial '/' and read until the next '/'. */
+ while (*ns_begin == '/') {
+ ns_begin++;
+ }
+
+ /* ns_end will point to the next '/' or NULL if there is no delimiting
+ * '/' (i.e. "/directory" or the top level "/") */
+ ns_end = strchr (ns_begin, '/');
+ len = ns_end ? (ns_end - ns_begin) : strlen (ns_begin);
+
+ if (len != 0) {
+ info->hash = SuperFastHash (ns_begin, len);
+ } else {
+ /* If our substring is empty, then we can hash '/' instead.
+ * '/' is used in the namespace config for the top-level
+ * namespace. */
+ info->hash = SuperFastHash ("/", 1);
+ }
+
+ info->found = _gf_true;
+ return PATH_PARSE_RESULT_FOUND;
+}
+
+/* Cache namespace info stored in the stack (info) into the inode. */
+static int
+ns_inode_ctx_put (inode_t *inode, xlator_t *this, ns_info_t *info)
+{
+ ns_info_t *cached_ns_info = NULL;
+ uint64_t ns_as_64 = 0;
+ int ret = -1;
+
+ if (!inode || !this) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Need a valid inode and xlator to cache ns_info.");
+ ret = -1;
+ goto out;
+ }
+
+ cached_ns_info = GF_CALLOC (1, sizeof (ns_info_t), 0);
+
+ /* If we've run out of memory, then return ENOMEM. */
+ if (cached_ns_info == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "No memory to cache ns_info.");
+ ret = -(ENOMEM);
+ goto out;
+ }
+
+ *cached_ns_info = *info;
+ ns_as_64 = (uint64_t)cached_ns_info;
+
+ ret = inode_ctx_put (inode, this, ns_as_64);
+
+ if (ret) {
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && cached_ns_info) {
+ GF_FREE (cached_ns_info);
+ }
+
+ return ret;
+}
+
+/* Retrieve namespace info cached in the inode into the stack for use in later
+ * translators. */
+static int
+ns_inode_ctx_get (inode_t *inode, xlator_t *this, ns_info_t *info)
+{
+ ns_info_t *cached_ns_info = NULL;
+ uint64_t ns_as_64 = 0;
+ int ret = -1;
+
+ if (!inode) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ ret = inode_ctx_get (inode, this, &ns_as_64);
+
+ if (!ret) {
+ cached_ns_info = (ns_info_t *)ns_as_64;
+ *info = *cached_ns_info;
+ }
+
+out:
+ return ret;
+}
+
+/* This callback is the top of the unwind path of our attempt to get the path
+ * manually from the posix translator. We'll try to parse the path returned
+ * if it exists, then cache the hash if possible. Then just return to the
+ * default stub that we provide in the local, since there's nothing else to do
+ * once we've gotten the namespace hash. */
+int32_t
+get_path_resume_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = PATH_PARSE_RESULT_NO_PATH;
+ call_frame_t *resume_frame = NULL;
+ ns_local_t *local = NULL;
+ call_stub_t *stub = NULL;
+ ns_info_t *info = NULL;
+ char *path = NULL;
+
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
+ local = frame->local;
+
+ GF_VALIDATE_OR_GOTO (this->name, local, out);
+ stub = local->stub;
+
+ GF_VALIDATE_OR_GOTO (this->name, stub, out);
+ /* Get the ns_info from the frame that we will eventually resume,
+ * not the frame that we're going to destroy (frame). */
+ resume_frame = stub->frame;
+
+ GF_VALIDATE_OR_GOTO (this->name, resume_frame, out);
+ GF_VALIDATE_OR_GOTO (this->name, resume_frame->root, out);
+ info = &resume_frame->root->ns_info;
+
+ GF_VALIDATE_OR_GOTO (this->name, dict, out);
+
+ /* If we get a value back for the GET_ANCESTRY_PATH_KEY, then we
+ * try to access it and parse it like a path. */
+ if (!op_ret && !dict_get_str (dict, GET_ANCESTRY_PATH_KEY, &path)) {
+ gf_log (this->name, GF_LOG_DEBUG, "G>P %s retrieved path %s",
+ uuid_utoa (local->loc.gfid), path);
+ /* Now let's parse a path, finally. */
+ ret = parse_path (info, path);
+ }
+
+ if (ret == PATH_PARSE_RESULT_FOUND) {
+ /* If we finally found namespace, then stash it. */
+ ns_inode_ctx_put (local->loc.inode, this, info);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "G>P %s %10u namespace found %s",
+ uuid_utoa (local->loc.inode->gfid), info->hash, path);
+ } else if (ret == PATH_PARSE_RESULT_NO_PATH) {
+ gf_log (this->name, GF_LOG_WARNING, "G>P %s has no path",
+ uuid_utoa (local->loc.inode->gfid));
+ } else if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "G>P %s winding failed, still have gfid",
+ uuid_utoa (local->loc.inode->gfid));
+ }
+
+out:
+ /* Make sure to clean up local finally. */
+
+ if (frame) {
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ }
+
+ if (local) {
+ ns_local_cleanup (local);
+ }
+
+ if (stub) {
+ call_resume (stub);
+ }
+
+ return 0;
+}
+
+/* This function tries first to set a namespace based on the information that
+ * it can retrieve from an `loc_t`. This includes first looking for a cached
+ * namespace in the inode, then trying to parse the path string in the `loc_t`
+ * struct. If this fails, then it will try to call inode_path. */
+static path_parse_result_t
+set_ns_from_loc (const char *fn, call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
+{
+ path_parse_result_t ret = PATH_PARSE_RESULT_NO_PATH;
+ ns_private_t *priv = (ns_private_t *)this->private;
+ ns_info_t *info = &frame->root->ns_info;
+ char *path = NULL;
+
+ info->hash = 0;
+ info->found = _gf_false;
+
+ if (!priv->tag_namespaces) {
+ return ret;
+ }
+
+ /* This is our first pass at trying to get a path. Try getting
+ * from the inode context, then from the loc's path itself. */
+ if (!loc || !loc->path || !loc->inode) {
+ ret = PATH_PARSE_RESULT_NO_PATH;
+ } else if (!ns_inode_ctx_get (loc->inode, this, info)) {
+ ret = PATH_PARSE_RESULT_FOUND;
+ } else {
+ ret = parse_path (info, loc->path);
+ gf_log (this->name, GF_LOG_DEBUG, "%s: LOC retrieved path %s",
+ fn, loc->path);
+
+ if (ret == PATH_PARSE_RESULT_FOUND) {
+ ns_inode_ctx_put (loc->inode, this, info);
+ }
+ }
+
+ /* Keep trying by calling inode_path next, making sure to copy
+ the loc's gfid into its inode if necessary. */
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ if (gf_uuid_is_null (loc->inode->gfid)) {
+ gf_uuid_copy (loc->inode->gfid, loc->gfid);
+ }
+
+ if (inode_path (loc->inode, NULL, &path) >= 0 && path) {
+ ret = parse_path (info, loc->path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: LOC retrieved path %s", fn, path);
+
+ if (ret == PATH_PARSE_RESULT_FOUND) {
+ ns_inode_ctx_put (loc->inode, this, info);
+ }
+ }
+
+ if (path) {
+ GF_FREE (path);
+ }
+ }
+
+ /* Report our status, and if we have a GFID, we'll eventually try a
+ * GET_ANCESTRY_PATH_KEY wind when we return from this function. */
+ if (ret == PATH_PARSE_RESULT_FOUND) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: LOC %s %10u namespace found for %s", fn,
+ uuid_utoa (loc->inode->gfid), info->hash, loc->path);
+ } else if (ret == PATH_PARSE_RESULT_NO_PATH) {
+ gf_log (this->name, GF_LOG_WARNING, "%s: LOC has no path", fn);
+ } else if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ /* Make sure to copy the inode's gfid for the eventual wind. */
+ if (gf_uuid_is_null (loc->inode->gfid)) {
+ gf_uuid_copy (loc->inode->gfid, loc->gfid);
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: LOC %s winding, looking for path", fn,
+ uuid_utoa (loc->inode->gfid));
+ }
+
+ return ret;
+}
+
+/* This function tries first to set a namespace based on the information that
+ * it can retrieve from an `fd_t`. This includes first looking for a cached
+ * namespace in the inode, then trying to call inode_path manually. */
+static path_parse_result_t
+set_ns_from_fd (const char *fn, call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ path_parse_result_t ret = PATH_PARSE_RESULT_NO_PATH;
+ ns_private_t *priv = (ns_private_t *)this->private;
+ ns_info_t *info = &frame->root->ns_info;
+ char *path = NULL;
+
+ info->hash = 0;
+ info->found = _gf_false;
+
+ if (!priv->tag_namespaces) {
+ return ret;
+ }
+
+ /* This is our first pass at trying to get a path. Try getting
+ * from the inode context, then inode_path. */
+ if (!fd || !fd->inode) {
+ ret = PATH_PARSE_RESULT_NO_PATH;
+ } else if (!ns_inode_ctx_get (fd->inode, this, info)) {
+ ret = PATH_PARSE_RESULT_FOUND;
+ } else if (inode_path (fd->inode, NULL, &path) >= 0 && path) {
+ ret = parse_path (info, path);
+ gf_log (this->name, GF_LOG_DEBUG, "%s: FD retrieved path %s",
+ fn, path);
+
+ if (ret == PATH_PARSE_RESULT_FOUND) {
+ ns_inode_ctx_put (fd->inode, this, info);
+ }
+ }
+
+ if (path) {
+ GF_FREE (path);
+ }
+
+ /* Report our status, and if we have a GFID, we'll eventually try a
+ * GET_ANCESTRY_PATH_KEY wind when we return from this function. */
+ if (ret == PATH_PARSE_RESULT_FOUND) {
+ gf_log (this->name, GF_LOG_DEBUG, "%s: FD %s %10u namespace found",
+ fn, uuid_utoa (fd->inode->gfid), info->hash);
+ } else if (ret == PATH_PARSE_RESULT_NO_PATH) {
+ gf_log (this->name, GF_LOG_WARNING, "%s: FD has no path", fn);
+ } else if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: FD %s winding, looking for path",
+ fn, uuid_utoa (fd->inode->gfid));
+ }
+
+ return ret;
+}
+
+/* This macro does the work of winding down a call of `getxattr` in the case
+ * that we have to retrieve the path manually. It assumes that there is a label
+ * called `wind` and the existence of several basic variables (frame, this),
+ * but otherwise is general enough for any fop (fd- or loc-based.) */
+#define GET_ANCESTRY_PATH_WIND(fop, inode, args...) \
+ do { \
+ ns_info_t *info = &frame->root->ns_info; \
+ call_frame_t *new_frame = NULL; \
+ ns_local_t *local = NULL; \
+ call_stub_t *stub = NULL; \
+ \
+ gf_log (this->name, GF_LOG_DEBUG, \
+ " %s winding, looking for path", \
+ uuid_utoa (inode->gfid)); \
+ \
+ new_frame = create_frame (this, this->ctx->pool); \
+ if (!new_frame) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "Cannot allocate new call frame."); \
+ goto wind; \
+ } \
+ \
+ stub = fop_##fop##_stub (frame, default_##fop, args); \
+ if (!stub) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "Cannot allocate function stub."); \
+ goto wind; \
+ } \
+ \
+ new_frame->root->uid = 0; \
+ new_frame->root->gid = 0; \
+ /* Put a phony "not found" NS info into this call. */ \
+ new_frame->root->ns_info = *info; \
+ \
+ local = ns_local_new (stub, inode); \
+ if (!local) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "Cannot allocate function local."); \
+ goto wind; \
+ } \
+ \
+ new_frame->local = local; \
+ /* After allocating a new frame, a call stub (to \
+ * resume our current fop), and a local variables \
+ * struct (for our loc to getxattr and our resume \
+ * stub), call getxattr and unwind to get_path_resume_cbk. \
+ */ \
+ STACK_WIND (new_frame, get_path_resume_cbk, \
+ FIRST_CHILD (this), \
+ FIRST_CHILD (this)->fops->getxattr, &local->loc, \
+ GET_ANCESTRY_PATH_KEY, NULL); \
+ } while (0)
+
+int32_t
+ns_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (rmdir, loc->inode, loc, xflags, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rmdir, loc, xflags, xdata);
+ return 0;
+}
+
+int32_t
+ns_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (unlink, loc->inode, loc, xflags, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->unlink, loc, xflags, xdata);
+ return 0;
+}
+
+int32_t
+ns_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, newloc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (rename, newloc->inode, oldloc, newloc,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_rename_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rename, oldloc, newloc, xdata);
+ return 0;
+}
+
+int32_t
+ns_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, newloc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (link, newloc->inode, oldloc, newloc,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_link_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->link, oldloc, newloc, xdata);
+ return 0;
+}
+
+int32_t
+ns_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (mkdir, loc->inode, loc, mode, umask,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->mkdir, loc, mode, umask, xdata);
+ return 0;
+}
+
+int32_t
+ns_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc, mode_t umask, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (symlink, loc->inode, linkname, loc,
+ umask, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->symlink, linkname, loc, umask,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t dev, mode_t umask, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (mknod, loc->inode, loc, mode, dev,
+ umask, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->mknod, loc, mode, dev, umask,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (create, loc->inode, loc, flags, mode,
+ umask, fd, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_create_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->create, loc, flags, mode, umask,
+ fd, xdata);
+ return 0;
+}
+
+int32_t
+ns_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fsetattr, fd->inode, fd, stbuf, valid,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (setattr, loc->inode, loc, stbuf, valid,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fremovexattr, fd->inode, fd, name,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fremovexattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fremovexattr, fd, name, xdata);
+ return 0;
+}
+
+int32_t
+ns_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (removexattr, loc->inode, loc, name,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->removexattr, loc, name, xdata);
+ return 0;
+}
+
+int32_t
+ns_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (setxattr, loc->inode, loc, dict, flags,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setxattr, loc, dict, flags,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fsetxattr, fd->inode, fd, dict, flags,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (truncate, loc->inode, loc, offset,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->truncate, loc, offset, xdata);
+ return 0;
+}
+
+int32_t
+ns_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (ftruncate, fd->inode, fd, offset,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->ftruncate, fd, offset, xdata);
+ return 0;
+}
+
+int32_t
+ns_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t offset, uint32_t flags, struct iobref *iobref,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (writev, fd->inode, fd, vector, count,
+ offset, flags, iobref, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_writev_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->writev, fd, vector, count, offset,
+ flags, iobref, xdata);
+ return 0;
+}
+
+int32_t
+ns_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (lookup, loc->inode, loc, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lookup, loc, xdata);
+ return 0;
+}
+
+int32_t
+ns_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (stat, loc->inode, loc, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, loc, xdata);
+ return 0;
+}
+
+int32_t
+ns_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fstat, fd->inode, fd, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd, xdata);
+ return 0;
+}
+
+int32_t
+ns_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (readlink, loc->inode, loc, size, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readlink, loc, size, xdata);
+ return 0;
+}
+
+int32_t
+ns_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (access, loc->inode, loc, mask, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_access_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->access, loc, mask, xdata);
+ return 0;
+}
+
+int32_t
+ns_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (open, fd->inode, loc, flags, fd, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_open_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->open, loc, flags, fd, xdata);
+ return 0;
+}
+
+int32_t
+ns_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (readv, fd->inode, fd, size, offset,
+ flags, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_readv_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readv, fd, size, offset, flags,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (flush, fd->inode, fd, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_flush_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->flush, fd, xdata);
+ return 0;
+}
+
+int32_t
+ns_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fsync, fd->inode, fd, datasync, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsync, fd, datasync, xdata);
+ return 0;
+}
+
+int32_t
+ns_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (opendir, loc->inode, loc, fd, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->opendir, loc, fd, xdata);
+ return 0;
+}
+
+int32_t
+ns_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fsyncdir, fd->inode, fd, datasync,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsyncdir, fd, datasync, xdata);
+ return 0;
+}
+
+int32_t
+ns_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (rchecksum, fd->inode, fd, offset, len,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rchecksum, fd, offset, len,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (statfs, loc->inode, loc, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->statfs, loc, xdata);
+ return 0;
+}
+
+int32_t
+ns_inodelk (call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc,
+ int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (inodelk, loc->inode, volume, loc, cmd,
+ flock, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->inodelk, volume, loc, cmd, flock,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
+ int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (finodelk, fd->inode, volume, fd, cmd,
+ flock, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->finodelk, volume, fd, cmd, flock,
+ xdata);
+ return 0;
+}
+
+int32_t
+ns_entrylk (call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc,
+ const char *basename, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (entrylk, loc->inode, volume, loc,
+ basename, cmd, type, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->entrylk, volume, loc, basename,
+ cmd, type, xdata);
+ return 0;
+}
+
+int32_t
+ns_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
+ const char *basename, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fentrylk, fd->inode, volume, fd,
+ basename, cmd, type, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fentrylk, volume, fd, basename,
+ cmd, type, xdata);
+ return 0;
+}
+
+int32_t
+ns_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fgetxattr, fd->inode, fd, name, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name, xdata);
+ return 0;
+}
+
+int32_t
+ns_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,
+ dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (getxattr, loc->inode, loc, name, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->getxattr, loc, name, xdata);
+ return 0;
+}
+
+int32_t
+ns_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *flock, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (lk, fd->inode, fd, cmd, flock, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_lk_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lk, fd, cmd, flock, xdata);
+ return 0;
+}
+
+int32_t
+ns_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (readdir, fd->inode, fd, size, offset,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readdir, fd, size, offset, xdata);
+
+ return 0;
+}
+
+int32_t
+ns_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, dict_t *dict)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (readdirp, fd->inode, fd, size, offset,
+ dict);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readdirp, fd, size, offset, dict);
+ return 0;
+}
+
+int32_t
+ns_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_loc (__FUNCTION__, frame, this, loc);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (xattrop, loc->inode, loc, flags, dict,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->xattrop, loc, flags, dict, xdata);
+
+ return 0;
+}
+
+int32_t
+ns_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fxattrop, fd->inode, fd, flags, dict,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fxattrop, fd, flags, dict, xdata);
+
+ return 0;
+}
+
+
+int32_t
+ns_getspec (call_frame_t *frame, xlator_t *this, const char *key, int32_t flag)
+{
+ STACK_WIND (frame, default_getspec_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->getspec, key, flag);
+ return 0;
+}
+
+int32_t
+ns_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (fallocate, fd->inode, fd, keep_size,
+ offset, len, xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_fallocate_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fallocate, fd, keep_size, offset,
+ len, xdata);
+ return 0;
+}
+
+int32_t
+ns_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (discard, fd->inode, fd, offset, len,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_discard_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->discard, fd, offset, len, xdata);
+ return 0;
+}
+
+int32_t
+ns_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ off_t len, dict_t *xdata)
+{
+ path_parse_result_t ret = set_ns_from_fd (__FUNCTION__, frame, this, fd);
+
+ if (ret == PATH_PARSE_RESULT_IS_GFID) {
+ GET_ANCESTRY_PATH_WIND (zerofill, fd->inode, fd, offset, len,
+ xdata);
+ return 0;
+ }
+wind:
+ STACK_WIND (frame, default_zerofill_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->zerofill, fd, offset, len, xdata);
+ return 0;
+}
+
+int
+ns_forget (xlator_t *this, inode_t *inode)
+{
+ uint64_t ns_as_64 = 0;
+ ns_info_t *info = NULL;
+
+ inode_ctx_del (inode, this, &ns_as_64);
+
+ if (!ns_as_64) {
+ return 0;
+ }
+
+ info = (ns_info_t *)ns_as_64;
+ GF_FREE (info);
+
+ return 0;
+}
+
+int32_t
+init (xlator_t *this)
+{
+ int32_t ret = -1;
+ ns_private_t *priv = NULL;
+
+ GF_VALIDATE_OR_GOTO (GF_NAMESPACE, this, out);
+
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "translator needs a single subvolume.");
+ goto out;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "dangling volume. please check volfile.");
+ goto out;
+ }
+
+ priv = GF_CALLOC (1, sizeof (ns_private_t), 0);
+
+ if (!priv) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Can't allocate ns_priv structure.");
+ goto out;
+ }
+
+ GF_OPTION_INIT ("tag-namespaces", priv->tag_namespaces, bool, out);
+
+ gf_log (this->name, GF_LOG_INFO, "Namespace xlator loaded");
+ this->private = priv;
+ ret = 0;
+
+out:
+ if (ret) {
+ GF_FREE (priv);
+ }
+
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ GF_FREE (this->private);
+}
+
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+ int ret = -1;
+ ns_private_t *priv = NULL;
+
+ GF_VALIDATE_OR_GOTO (this->name, this, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
+ GF_VALIDATE_OR_GOTO (this->name, options, out);
+
+ priv = (ns_private_t *)this->private;
+
+ GF_OPTION_RECONF ("tag-namespaces", priv->tag_namespaces, options, bool,
+ out);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+struct xlator_fops fops = {
+ .lookup = ns_lookup,
+ .stat = ns_stat,
+ .fstat = ns_fstat,
+ .truncate = ns_truncate,
+ .ftruncate = ns_ftruncate,
+ .access = ns_access,
+ .readlink = ns_readlink,
+ .mknod = ns_mknod,
+ .mkdir = ns_mkdir,
+ .unlink = ns_unlink,
+ .rmdir = ns_rmdir,
+ .symlink = ns_symlink,
+ .rename = ns_rename,
+ .link = ns_link,
+ .create = ns_create,
+ .open = ns_open,
+ .readv = ns_readv,
+ .writev = ns_writev,
+ .flush = ns_flush,
+ .fsync = ns_fsync,
+ .opendir = ns_opendir,
+ .readdir = ns_readdir,
+ .readdirp = ns_readdirp,
+ .fsyncdir = ns_fsyncdir,
+ .statfs = ns_statfs,
+ .setxattr = ns_setxattr,
+ .getxattr = ns_getxattr,
+ .fsetxattr = ns_fsetxattr,
+ .fgetxattr = ns_fgetxattr,
+ .removexattr = ns_removexattr,
+ .fremovexattr = ns_fremovexattr,
+ .lk = ns_lk,
+ .inodelk = ns_inodelk,
+ .finodelk = ns_finodelk,
+ .entrylk = ns_entrylk,
+ .fentrylk = ns_fentrylk,
+ .rchecksum = ns_rchecksum,
+ .xattrop = ns_xattrop,
+ .fxattrop = ns_fxattrop,
+ .setattr = ns_setattr,
+ .fsetattr = ns_fsetattr,
+ .getspec = ns_getspec,
+ .fallocate = ns_fallocate,
+ .discard = ns_discard,
+ .zerofill = ns_zerofill,
+};
+
+struct xlator_cbks cbks = {
+ .forget = ns_forget,
+};
+
+struct xlator_dumpops dumpops;
+
+struct volume_options options[] = {
+ {
+ .key = { "tag-namespaces" },
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "This option enables this translator's functionality "
+ "that tags every fop with a namespace hash for later "
+ "throttling, stats collection, logging, etc.",
+ .op_version = {GD_OP_VERSION_4_1_0},
+ .tags = {"namespace"},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC,
+ },
+ {.key = { NULL } },
+};
diff --git a/xlators/features/namespace/src/namespace.h b/xlators/features/namespace/src/namespace.h
new file mode 100644
index 00000000000..1dbec50e024
--- /dev/null
+++ b/xlators/features/namespace/src/namespace.h
@@ -0,0 +1,23 @@
+#ifndef __NAMESPACE_H__
+#define __NAMESPACE_H__
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "call-stub.h"
+
+#define GF_NAMESPACE "namespace"
+
+typedef struct {
+ gf_boolean_t tag_namespaces;
+} ns_private_t;
+
+typedef struct {
+ loc_t loc; /* We store a "fake" loc_t for the getxattr wind. */
+ call_stub_t *stub; /* A stub back to the function we're resuming. */
+} ns_local_t;
+
+#endif /* __NAMESPACE_H__ */
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 0c984c97192..f9fcf88a256 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -2049,6 +2049,31 @@ out:
return ret;
}
+static int
+brick_graph_add_namespace (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
+ dict_t *set_dict, glusterd_brickinfo_t *brickinfo)
+{
+ xlator_t *xl = NULL;
+ int ret = -1;
+
+ if (!graph || !volinfo || !set_dict)
+ goto out;
+
+ ret = dict_get_str_boolean (set_dict, "features.tag-namespaces", 0);
+ if (ret == -1)
+ goto out;
+
+ if (ret) {
+ xl = volgen_graph_add (graph, "features/namespace", volinfo->volname);
+ if (!xl)
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
xlator_t *
add_one_peer (volgen_graph_t *graph, glusterd_brickinfo_t *peer,
char *volname, uint16_t index)
@@ -2642,6 +2667,7 @@ static volgen_brick_xlator_t server_graph_table[] = {
{brick_graph_add_decompounder, "decompounder"},
{brick_graph_add_io_stats, "NULL"},
{brick_graph_add_sdfs, "sdfs"},
+ {brick_graph_add_namespace, "namespace"},
{brick_graph_add_cdc, NULL},
{brick_graph_add_quota, "quota"},
{brick_graph_add_index, "index"},
@@ -4983,7 +5009,7 @@ static gf_boolean_t
volgen_is_shd_compatible_xl (char *xl_type)
{
char *shd_xls[] = {"cluster/replicate", "cluster/disperse",
- "debug/io-stats", NULL};
+ NULL};
if (gf_get_index_by_elem (shd_xls, xl_type) != -1)
return _gf_true;
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 5cfb1d0a9d3..243b6076868 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2368,6 +2368,17 @@ struct volopt_map_entry glusterd_volopt_map[] = {
"snapdir-entry-path which is set by samba"
},
+ { .key = "features.tag-namespaces",
+ .voltype = "features/namespace",
+ .op_version = GD_OP_VERSION_4_1_0,
+ .option = "tag-namespaces",
+ .value = "off",
+ .flags = OPT_FLAG_CLIENT_OPT,
+ .description = "This option enables this translator's functionality "
+ "that tags every fop with a namespace hash for later "
+ "throttling, stats collection, logging, etc."
+ },
+
#ifdef HAVE_LIB_Z
/* Compressor-decompressor xlator options
* defaults used from xlator/features/compress/src/cdc.h
diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c
index 501e4019e90..fa067cc4d6a 100644
--- a/xlators/performance/io-threads/src/io-threads.c
+++ b/xlators/performance/io-threads/src/io-threads.c
@@ -126,7 +126,6 @@ __iot_dequeue (iot_conf_t *conf, int *pri)
return stub;
}
-
void
__iot_enqueue (iot_conf_t *conf, call_stub_t *stub, int pri)
{
@@ -157,7 +156,6 @@ __iot_enqueue (iot_conf_t *conf, call_stub_t *stub, int pri)
conf->queue_sizes[pri]++;
}
-
void *
iot_worker (void *data)
{
@@ -232,7 +230,6 @@ iot_worker (void *data)
return NULL;
}
-
int
do_iot_schedule (iot_conf_t *conf, call_stub_t *stub, int pri)
{
@@ -374,7 +371,6 @@ iot_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
return 0;
}
-
int
iot_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
struct iatt *stbuf, int32_t valid, dict_t *xdata)
@@ -383,7 +379,6 @@ iot_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
return 0;
}
-
int
iot_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iatt *stbuf, int32_t valid, dict_t *xdata)
@@ -392,7 +387,6 @@ iot_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
-
int
iot_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
dict_t *xdata)
@@ -401,7 +395,6 @@ iot_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
return 0;
}
-
int
iot_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata)
{
@@ -409,7 +402,6 @@ iot_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict
return 0;
}
-
int
iot_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
dev_t rdev, mode_t umask, dict_t *xdata)
@@ -418,7 +410,6 @@ iot_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
return 0;
}
-
int
iot_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
mode_t umask, dict_t *xdata)
@@ -427,7 +418,6 @@ iot_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
return 0;
}
-
int
iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
{
@@ -435,7 +425,6 @@ iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *x
return 0;
}
-
int
iot_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
loc_t *loc, mode_t umask, dict_t *xdata)
@@ -444,7 +433,6 @@ iot_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
return 0;
}
-
int
iot_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
dict_t *xdata)
@@ -453,7 +441,6 @@ iot_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
return 0;
}
-
int
iot_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
fd_t *fd, dict_t *xdata)
@@ -462,7 +449,6 @@ iot_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
return 0;
}
-
int
iot_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
@@ -482,7 +468,6 @@ iot_put (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
return 0;
}
-
int
iot_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t offset, uint32_t flags, dict_t *xdata)
@@ -491,7 +476,6 @@ iot_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
return 0;
}
-
int
iot_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
@@ -499,7 +483,6 @@ iot_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
return 0;
}
-
int
iot_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
dict_t *xdata)
@@ -508,7 +491,6 @@ iot_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
return 0;
}
-
int
iot_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t offset,
@@ -519,7 +501,6 @@ iot_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
-
int
iot_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
struct gf_flock *flock, dict_t *xdata)
@@ -528,7 +509,6 @@ iot_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
return 0;
}
-
int
iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
@@ -536,7 +516,6 @@ iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
return 0;
}
-
int
iot_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
@@ -544,7 +523,6 @@ iot_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
return 0;
}
-
int
iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
dict_t *xdata)
@@ -553,7 +531,6 @@ iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
return 0;
}
-
int
iot_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
dict_t *xdata)
@@ -562,8 +539,6 @@ iot_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
return 0;
}
-
-
int
iot_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
dict_t *xdata)
@@ -572,7 +547,6 @@ iot_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
return 0;
}
-
int
iot_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
dict_t *xdata)
@@ -581,7 +555,6 @@ iot_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
return 0;
}
-
int
iot_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
dict_t *xdata)
@@ -590,7 +563,6 @@ iot_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
return 0;
}
-
int
iot_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
dict_t *xdata)
@@ -599,7 +571,6 @@ iot_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
return 0;
}
-
int
iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
@@ -607,7 +578,6 @@ iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
return 0;
}
-
int
iot_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
int32_t flags, dict_t *xdata)
@@ -616,7 +586,6 @@ iot_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
return 0;
}
-
int
iot_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
@@ -624,6 +593,8 @@ iot_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
iot_conf_t *conf = NULL;
dict_t *depths = NULL;
int i = 0;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
conf = this->private;
@@ -632,9 +603,12 @@ iot_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
* We explicitly do not want a reference count
* for this dict in this translator
*/
- depths = get_new_dict ();
- if (!depths)
+ depths = dict_new ();
+ if (!depths) {
+ op_ret = -1;
+ op_errno = ENOMEM;
goto unwind_special_getxattr;
+ }
for (i = 0; i < GF_FOP_PRI_MAX; i++) {
if (dict_set_int32 (depths,
@@ -647,7 +621,10 @@ iot_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
unwind_special_getxattr:
- STACK_UNWIND_STRICT (getxattr, frame, 0, 0, depths, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno,
+ depths, xdata);
+ if (depths)
+ dict_unref(depths);
return 0;
}
@@ -655,7 +632,6 @@ unwind_special_getxattr:
return 0;
}
-
int
iot_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
const char *name, dict_t *xdata)
@@ -673,7 +649,6 @@ iot_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
return 0;
}
-
int
iot_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
@@ -690,7 +665,6 @@ iot_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
-
int
iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t offset, dict_t *xdata)
@@ -699,7 +673,6 @@ iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
return 0;
}
-
int
iot_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t offset, dict_t *xdata)
@@ -744,7 +717,6 @@ iot_fentrylk (call_frame_t *frame, xlator_t *this,
return 0;
}
-
int
iot_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
@@ -753,7 +725,6 @@ iot_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
return 0;
}
-
int
iot_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
@@ -762,7 +733,6 @@ iot_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
-
int32_t
iot_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
int32_t len, dict_t *xdata)
@@ -827,7 +797,6 @@ iot_setactivelk (call_frame_t *frame, xlator_t *this, loc_t *loc,
return 0;
}
-
int
__iot_workers_scale (iot_conf_t *conf)
{
@@ -872,7 +841,6 @@ __iot_workers_scale (iot_conf_t *conf)
return diff;
}
-
int
iot_workers_scale (iot_conf_t *conf)
{
@@ -893,7 +861,6 @@ out:
return ret;
}
-
int
set_stack_size (iot_conf_t *conf)
{
@@ -931,7 +898,6 @@ set_stack_size (iot_conf_t *conf)
return err;
}
-
int32_t
mem_acct_init (xlator_t *this)
{
@@ -1022,7 +988,6 @@ out:
return ret;
}
-
int
init (xlator_t *this)
{
@@ -1180,7 +1145,6 @@ iot_client_destroy (xlator_t *this, client_t *client)
return 0;
}
-
struct xlator_dumpops dumpops = {
.priv = iot_priv_dump,
};