diff options
| author | Pranith Kumar K <pkarampu@redhat.com> | 2015-02-25 11:37:57 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2015-02-27 01:28:35 -0800 | 
| commit | d5624b2d4baf509ad8d6037a0d9cabf9cd5ab1c5 (patch) | |
| tree | a5f257e370606282a1f9c98418e48c466077e5f3 /libglusterfs/src/syncop-utils.c | |
| parent | 6a77db6d19dba5367c02cbf2a5883ac49cef94e2 (diff) | |
libglusterfs: Moved common functions as utils in syncop/common-utils
These will be used by both afr and ec. Moved syncop_dirfd, syncop_ftw,
syncop_dir_scan functions also into syncop-utils.c
Change-Id: I467253c74a346e1e292d36a8c1a035775c3aa670
BUG: 1177601
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/9740
Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-by: Anuradha Talur <atalur@redhat.com>
Reviewed-by: Ravishankar N <ravishankar@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs/src/syncop-utils.c')
| -rw-r--r-- | libglusterfs/src/syncop-utils.c | 265 | 
1 files changed, 265 insertions, 0 deletions
diff --git a/libglusterfs/src/syncop-utils.c b/libglusterfs/src/syncop-utils.c new file mode 100644 index 00000000000..53768acd0ac --- /dev/null +++ b/libglusterfs/src/syncop-utils.c @@ -0,0 +1,265 @@ +/* +  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> +  This file is part of GlusterFS. + +  This file is licensed to you under your choice of the GNU Lesser +  General Public License, version 3 or any later version (LGPLv3 or +  later), or the GNU General Public License, version 2 (GPLv2), in all +  cases as published by the Free Software Foundation. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "syncop.h" +#include "common-utils.h" + +int +syncop_dirfd (xlator_t *subvol, loc_t *loc, fd_t **fd, int pid) +{ +        int  ret    = 0; +        fd_t *dirfd = NULL; + +        if (!fd) +                return -EINVAL; + +        dirfd = fd_create (loc->inode, pid); +        if (!dirfd) { +                gf_log (subvol->name, GF_LOG_ERROR, +                        "fd_create of %s failed: %s", +                        uuid_utoa (loc->gfid), strerror(errno)); +                ret = -errno; +                goto out; +        } + +        ret = syncop_opendir (subvol, loc, dirfd); +        if (ret) { +        /* +         * On Linux, if the brick was not updated, opendir will +         * fail. We therefore use backward compatible code +         * that violate the standards by reusing offsets +         * in seekdir() from different DIR *, but it works on Linux. +         * +         * On other systems it never worked, hence we do not need +         * to provide backward-compatibility. +         */ +#ifdef GF_LINUX_HOST_OS +                fd_unref (dirfd); +                dirfd = fd_anonymous (loc->inode); +                if (!dirfd) { +                        gf_log(subvol->name, GF_LOG_ERROR, +                               "fd_anonymous of %s failed: %s", +                               uuid_utoa (loc->gfid), strerror(errno)); +                        ret = -errno; +                        goto out; +                } +                ret = 0; +#else /* GF_LINUX_HOST_OS */ +                fd_unref (dirfd); +                gf_log (subvol->name, GF_LOG_ERROR, +                        "opendir of %s failed: %s", +                        uuid_utoa (loc->gfid), strerror(errno)); +                goto out; +#endif /* GF_LINUX_HOST_OS */ +        } +out: +        if (ret == 0) +                *fd = dirfd; +        return ret; +} + +int +syncop_ftw (xlator_t *subvol, loc_t *loc, int pid, void *data, +            int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, +                       void *data)) +{ +        loc_t       child_loc = {0, }; +        fd_t        *fd       = NULL; +        uint64_t    offset    = 0; +        gf_dirent_t *entry    = NULL; +        int         ret       = 0; +        gf_dirent_t entries; + +        ret = syncop_dirfd (subvol, loc, &fd, pid); +        if (ret) +                goto out; + +        INIT_LIST_HEAD (&entries.list); + +        while ((ret = syncop_readdirp (subvol, fd, 131072, offset, 0, +                                       &entries))) { +                if (ret < 0) +                        break; + +                if (ret > 0) { +                        /* If the entries are only '.', and '..' then ret +                         * value will be non-zero. so set it to zero here. */ +                        ret = 0; +                } +                list_for_each_entry (entry, &entries.list, list) { +                        offset = entry->d_off; + +                        if (!strcmp (entry->d_name, ".") || +                            !strcmp (entry->d_name, "..")) +                                continue; + +                        gf_link_inode_from_dirent (NULL, fd->inode, entry); + +                        ret = fn (subvol, entry, loc, data); +                        if (ret) +                                break; + +                        if (entry->d_stat.ia_type == IA_IFDIR) { +                                child_loc.inode = inode_ref (entry->inode); +                                uuid_copy (child_loc.gfid, entry->inode->gfid); +                                ret = syncop_ftw (subvol, &child_loc, +                                                  pid, data, fn); +                                loc_wipe (&child_loc); +                                if (ret) +                                        break; +                        } +                } + +                gf_dirent_free (&entries); +                if (ret) +                        break; +        } + +out: +        if (fd) +                fd_unref (fd); +        return ret; +} + +int +syncop_dir_scan (xlator_t *subvol, loc_t *loc, int pid, void *data, +                 int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, +                            void *data)) +{ +        fd_t        *fd    = NULL; +        uint64_t    offset = 0; +        gf_dirent_t *entry = NULL; +        int         ret    = 0; +        gf_dirent_t entries; + +        ret = syncop_dirfd (subvol, loc, &fd, pid); +        if (ret) +                goto out; + +        INIT_LIST_HEAD (&entries.list); + +        while ((ret = syncop_readdir  (subvol, fd, 131072, offset, &entries))) { +                if (ret < 0) +                        break; + +                if (ret > 0) { +                        /* If the entries are only '.', and '..' then ret +                         * value will be non-zero. so set it to zero here. */ +                        ret = 0; +                } + +                list_for_each_entry (entry, &entries.list, list) { +                        offset = entry->d_off; + +                        if (!strcmp (entry->d_name, ".") || +                            !strcmp (entry->d_name, "..")) +                                continue; + +                        ret = fn (subvol, entry, loc, data); +                        if (ret) +                                break; +                } +                gf_dirent_free (&entries); +                if (ret) +                        break; +        } + +out: +        if (fd) +                fd_unref (fd); +        return ret; +} + +int +syncop_is_subvol_local (xlator_t *this, loc_t *loc, gf_boolean_t *is_local) +{ +        char *pathinfo = NULL; +        dict_t *xattr = NULL; +        int ret = 0; + +        if (!this || !this->type || !is_local) +                return -EINVAL; + +        if (strcmp (this->type, "protocol/client") != 0) +                return -EINVAL; + +        *is_local = _gf_false; + +        ret = syncop_getxattr (this, loc, &xattr, GF_XATTR_PATHINFO_KEY, NULL); +        if (ret < 0) { +                ret = -1; +                goto out; +        } + +        if (!xattr) { +                ret = -EINVAL; +                goto out; +        } + +        ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &pathinfo); +        if (ret) +                goto out; + +        ret = glusterfs_is_local_pathinfo (pathinfo, is_local); + +        gf_log (this->name, GF_LOG_DEBUG, "subvol %s is %slocal", +                this->name, is_local ? "" : "not "); + +out: +        if (xattr) +                dict_unref (xattr); + +        return ret; +} + +int +syncop_gfid_to_path (inode_table_t *itable, xlator_t *subvol, uuid_t gfid, +                     char **path_p) +{ +        int      ret   = 0; +        char    *path  = NULL; +        loc_t    loc   = {0,}; +        dict_t  *xattr = NULL; + +        uuid_copy (loc.gfid, gfid); +        loc.inode = inode_new (itable); + +        ret = syncop_getxattr (subvol, &loc, &xattr, GFID_TO_PATH_KEY, NULL); +        if (ret < 0) +                goto out; + +        ret = dict_get_str (xattr, GFID_TO_PATH_KEY, &path); +        if (ret || !path) { +                ret = -EINVAL; +                goto out; +        } + +        if (path_p) { +                *path_p = gf_strdup (path); +                if (!*path_p) { +                        ret = -ENOMEM; +                        goto out; +                } +        } + +        ret = 0; + +out: +        if (xattr) +                dict_unref (xattr); +        loc_wipe (&loc); + +        return ret; +}  | 
