diff options
| author | Shehjar Tikoo <shehjart@gluster.com> | 2010-03-31 07:27:03 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-03-31 07:44:02 -0700 | 
| commit | c4fd1cf7325972d8ff64ef3a2bea70edcf4f1085 (patch) | |
| tree | b91c42227b2881eb8b77d39aca3d8348966bc052 /xlators/nfs/server/src/nfs-common.c | |
| parent | 8b2949db0d56bdf5842abcb72437cc7dccd884df (diff) | |
nfs: Add generic nfs translator
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 399 (NFS translator with Mount v3 and NFS v3 support)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=399
Diffstat (limited to 'xlators/nfs/server/src/nfs-common.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs-common.c | 379 | 
1 files changed, 379 insertions, 0 deletions
diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c new file mode 100644 index 00000000000..3623f041c14 --- /dev/null +++ b/xlators/nfs/server/src/nfs-common.c @@ -0,0 +1,379 @@ +/* +  Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> +  This file is part of GlusterFS. + +  GlusterFS is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3 of the License, +  or (at your option) any later version. + +  GlusterFS is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +  General Public License for more details. + +  You should have received a copy of the GNU General Public License +  along with this program.  If not, see +  <http://www.gnu.org/licenses/>. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "rpcsvc.h" +#include "dict.h" +#include "xlator.h" +#include "xdr-nfs3.h" +#include "msg-nfs3.h" +#include "iobuf.h" +#include "nfs-common.h" +#include "nfs-fops.h" +#include "rpcsvc.h" +#include "iatt.h" + +#include <libgen.h> + +xlator_t * +nfs_xlid_to_xlator (xlator_list_t *cl, uint8_t xlid) +{ +        xlator_t        *xl = NULL; +        uint8_t         id = 0; + +        while (id <= xlid) { +                if (!cl) { +                        xl = NULL; +                        break; +                } + +                xl = cl->xlator; +                cl = cl->next; +                id++; +        } + +        return xl; +} + + +xlator_t * +nfs_path_to_xlator (xlator_list_t *cl, char *path) +{ +        return NULL; +} + + +uint16_t +nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl) +{ +        uint16_t        xlid = 0; + +        if ((!cl) || (!xl)) +                return 0; + +        while (cl) { +                if (xl == cl->xlator) +                        break; +                cl = cl->next; +                ++xlid; +        } + +        return xlid; +} + + +xlator_t * +nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) +{ +        char            volname[MNTPATHLEN]; +        char            *volptr = NULL; +        int             pathlen = 0; +        xlator_t        *targetxl = NULL; + +        if ((!cl) || (!path)) +                return NULL; + +        strcpy (volname, path); +        pathlen = strlen (volname); +        gf_log (GF_NFS, GF_LOG_TRACE, "Subvolume search: %s", path); +        if (volname[0] == '/') +                volptr = &volname[1]; +        else +                volptr = &volname[0]; + +        if (volname[pathlen - 1] == '/') +                volname[pathlen - 1] = '\0'; + +        while (cl) { +                if (strcmp (volptr, cl->xlator->name) == 0) { +                        targetxl = cl->xlator; +                        break; +                } + +                cl = cl->next; +        } + +        return targetxl; + +} + + +/* Returns 1 if the stat seems to be filled with zeroes. */ +int +nfs_zero_filled_stat (struct iatt *buf) +{ +        if (!buf) +                return 1; + +        /* Do not use st_dev because it is transformed to store the xlator id +         * in place of the device number. Do not use st_ino because by this time +         * we've already mapped the root ino to 1 so it is not guaranteed to be +         * 0. +         */ +        if ((buf->ia_nlink == 0) && (buf->ia_type == 0)) +                return 1; + +        return 0; +} + + +void +nfs_loc_wipe (loc_t *loc) +{ +        if (!loc) +                return; + +        if (loc->path) { +                FREE (loc->path); +                loc->path = NULL; +        } + +        if (loc->parent) { +                inode_unref (loc->parent); +                loc->parent = NULL; +	} + +        if (loc->inode) { +                inode_unref (loc->inode); +                loc->inode = NULL; +        } + +        loc->ino = 0; +} + + +int +nfs_loc_copy (loc_t *dst, loc_t *src) +{ +	int ret = -1; + +	dst->ino = src->ino; + +	if (src->inode) +		dst->inode = inode_ref (src->inode); + +	if (src->parent) +		dst->parent = inode_ref (src->parent); + +	dst->path = strdup (src->path); + +	if (!dst->path) +		goto out; + +	dst->name = strrchr (dst->path, '/'); +	if (dst->name) +		dst->name++; + +	ret = 0; +out: +	return ret; +} + + +int +nfs_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) +{ +        int     ret = -EFAULT; + +        if (!loc) +                return ret; + +        if (inode) { +                loc->inode = inode_ref (inode); +                loc->ino = inode->ino; +        } + +        if (parent) +                loc->parent = inode_ref (parent); + +        loc->path = strdup (path); +        if (!loc->path) { +                gf_log (GF_NFS, GF_LOG_ERROR, "strdup failed"); +                goto loc_wipe; +        } + +        loc->name = strrchr (loc->path, '/'); +        if (loc->name) +                loc->name++; +        else +                goto loc_wipe; + +        ret = 0; +loc_wipe: +        if (ret < 0) +                nfs_loc_wipe (loc); + +        return ret; +} + + +int +nfs_inode_loc_fill (inode_t *inode, loc_t *loc) +{ +        char            *resolvedpath = NULL; +        inode_t         *parent = NULL; +        int             ret = -EFAULT; + +        if ((!inode) || (!loc)) +                return ret; + +        if ((inode) && (inode->ino == 1)) +                goto ignore_parent; + +        parent = inode_parent (inode, 0, NULL); +        if (!parent) +                goto err; + +ignore_parent: +        ret = inode_path (inode, NULL, &resolvedpath); +        if (ret < 0) +                goto err; + +        ret = nfs_loc_fill (loc, inode, parent, resolvedpath); +        if (ret < 0) +                goto err; + +err: +        if (parent) +                inode_unref (parent); + +        if (resolvedpath) +                FREE (resolvedpath); + +        return ret; +} + + +int +nfs_ino_loc_fill (inode_table_t *itable, uint64_t ino, uint64_t gen, loc_t *loc) +{ +        int             ret = -EFAULT; +        inode_t         *inode = NULL; + +        if (!loc) +                return ret; + +        inode = inode_get (itable, ino, gen); +        if (!inode) { +                ret = -ENOENT; +                goto err; +        } + +        ret = nfs_inode_loc_fill (inode, loc); + +err: +        if (inode) +                inode_unref (inode); +        return ret; +} + + +int +nfs_parent_inode_loc_fill (inode_t *parent, inode_t *entryinode, char *entry, +                           loc_t *loc) +{ +        int             ret = -EFAULT; +        char            *path = NULL; + +        if ((!parent) || (!entry) || (!loc) || (!entryinode)) +                return ret; + +        ret = inode_path (parent, entry, &path); +        if (ret < 0) +                goto err; + +        ret = nfs_loc_fill (loc, entryinode, parent, path); + +err: +        return ret; +} + + +/* Returns -1 if parent is not available, return -2 if the entry is not + * available. In case the return is going to be -2, and how = NFS_RESOLVE_CREATE + * it does however fill in the loc so that it can be used to perform a lookup + * fop for the entry. + * On other errors, return -3. 0 on success. + */ +int +nfs_entry_loc_fill (inode_table_t *itable, ino_t ino, uint64_t gen, char *entry, +                    loc_t *loc, int how) +{ +        inode_t         *parent = NULL; +        inode_t         *entryinode = NULL; +        int             ret = -3; +        char            *resolvedpath = NULL; + +        if ((!itable) || (!entry) || (!loc)) +                return ret; + +        parent = inode_get (itable, ino, gen); + +        ret = -1; +        /* Will need hard resolution now */ +        if (!parent) +                goto err; + +        ret = -2; +        entryinode = inode_grep (itable, parent, entry); +        if (!entryinode) { +                if (how != NFS_RESOLVE_CREATE) +                        goto err; +                else { +                        /* Even though we'll create the inode and the loc for +                         * a missing inode, we still need to return -2 so +                         * that the caller can use the filled loc to call +                         * lookup. +                         */ +                        entryinode = inode_new (itable); +                        nfs_parent_inode_loc_fill (parent, entryinode, entry, +                                                   loc); +                        goto err; +                } +        } + +        ret = inode_path (parent, entry, &resolvedpath); +        if (ret < 0) { +                ret = -3; +                goto err; +        } + +        ret = nfs_loc_fill (loc, entryinode, parent, resolvedpath); +        if (ret < 0) +                ret = -3; + +err: +        if (parent) +                inode_unref (parent); + +        if (entryinode) +                inode_unref (entryinode); + +        if (resolvedpath) +                FREE (resolvedpath); + +        return ret; +} + + +  | 
