diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 7 | ||||
| -rw-r--r-- | xlators/debug/io-stats/src/io-stats.c | 2 | ||||
| -rw-r--r-- | xlators/features/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/features/namespace/Makefile.am | 3 | ||||
| -rw-r--r-- | xlators/features/namespace/src/Makefile.am | 17 | ||||
| -rw-r--r-- | xlators/features/namespace/src/namespace.c | 1367 | ||||
| -rw-r--r-- | xlators/features/namespace/src/namespace.h | 23 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 28 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 11 | ||||
| -rw-r--r-- | xlators/performance/io-threads/src/io-threads.c | 58 | 
10 files changed, 1464 insertions, 54 deletions
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,  };  | 
