[BACK]Return to vfs_lookup.c CVS log [TXT][DIR] Up to [local] / prex / usr / server / fs / vfs

Annotation of prex/usr/server/fs/vfs/vfs_lookup.c, Revision 1.1

1.1     ! nbrk        1: /*
        !             2:  * Copyright (c) 2005-2007, Kohsuke Ohtani
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. Neither the name of the author nor the names of any co-contributors
        !            14:  *    may be used to endorse or promote products derived from this software
        !            15:  *    without specific prior written permission.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            27:  * SUCH DAMAGE.
        !            28:  */
        !            29:
        !            30: /*
        !            31:  * lookup.c - vnode lookup function.
        !            32:  */
        !            33:
        !            34: #include <sys/vnode.h>
        !            35: #include <sys/mount.h>
        !            36:
        !            37: #include <limits.h>
        !            38: #include <unistd.h>
        !            39: #include <string.h>
        !            40: #include <errno.h>
        !            41:
        !            42: #include <stdlib.h>
        !            43:
        !            44: #include "vfs.h"
        !            45:
        !            46: /*
        !            47:  * Convert a pathname into a pointer to a locked vnode.
        !            48:  * @path: full path name.
        !            49:  * @vpp:  vnode to be returned.
        !            50:  */
        !            51: int
        !            52: namei(char *path, vnode_t *vpp)
        !            53: {
        !            54:        char *p;
        !            55:        char node[PATH_MAX];
        !            56:        char name[PATH_MAX];
        !            57:        mount_t mp;
        !            58:        vnode_t dvp, vp;
        !            59:        int err, i;
        !            60:
        !            61:        DPRINTF(VFSDB_VNODE, ("namei: path=%s\n", path));
        !            62:
        !            63:        /*
        !            64:         * Convert a full path name to its mount point and
        !            65:         * the local node in the file system.
        !            66:         */
        !            67:        if (vfs_findroot(path, &mp, &p))
        !            68:                return ENOTDIR;
        !            69:        strcpy(node, "/");
        !            70:        strlcat(node, p, PATH_MAX);
        !            71:        vp = vn_lookup(mp, node);
        !            72:        if (vp) {
        !            73:                /* vnode is already active. */
        !            74:                *vpp = vp;
        !            75:                return 0;
        !            76:        }
        !            77:        /*
        !            78:         * Find target vnode, started from root directory.
        !            79:         * This is done to attach the fs specific data to
        !            80:         * the target vnode.
        !            81:         */
        !            82:        if ((dvp = mp->m_root) == NULL)
        !            83:                sys_panic("VFS: no root");
        !            84:
        !            85:        vref(dvp);
        !            86:        vn_lock(dvp);
        !            87:        node[0] = '\0';
        !            88:
        !            89:        while (*p != '\0') {
        !            90:                /*
        !            91:                 * Get lower directory/file name.
        !            92:                 */
        !            93:                while (*p == '/')
        !            94:                        p++;
        !            95:                for (i = 0; i < PATH_MAX; i++) {
        !            96:                        if (*p == '\0' || *p == '/')
        !            97:                                break;
        !            98:                        name[i] = *p++;
        !            99:                }
        !           100:                name[i] = '\0';
        !           101:
        !           102:                /*
        !           103:                 * Get a vnode for the target.
        !           104:                 */
        !           105:                strlcat(node, "/", PATH_MAX);
        !           106:                strlcat(node, name, PATH_MAX);
        !           107:                vp = vn_lookup(mp, node);
        !           108:                if (vp == NULL) {
        !           109:                        vp = vget(mp, node);
        !           110:                        if (vp == NULL) {
        !           111:                                vput(dvp);
        !           112:                                return ENOMEM;
        !           113:                        }
        !           114:                        /* Find a vnode in this directory. */
        !           115:                        err = VOP_LOOKUP(dvp, name, vp);
        !           116:                        if (err || (*p == '/' && vp->v_type != VDIR)) {
        !           117:                                /* Not found */
        !           118:                                vput(vp);
        !           119:                                vput(dvp);
        !           120:                                return err;
        !           121:                        }
        !           122:                }
        !           123:                vput(dvp);
        !           124:                dvp = vp;
        !           125:                while (*p != '\0' && *p != '/')
        !           126:                        p++;
        !           127:        }
        !           128:        *vpp = vp;
        !           129:        return 0;
        !           130: }
        !           131:
        !           132: /*
        !           133:  * Search a pathname.
        !           134:  * @path: full path.
        !           135:  * @vpp:  pointer to locked vnode for directory.
        !           136:  * @name: pointer to file name in path.
        !           137:  *
        !           138:  * This is a very central but not so complicated routine. ;-P
        !           139:  * This routine returns a locked directory vnode and file name.
        !           140:  */
        !           141: int
        !           142: lookup(char *path, vnode_t *vpp, char **name)
        !           143: {
        !           144:        char buf[PATH_MAX];
        !           145:        char root[] = "/";
        !           146:        char *file, *dir;
        !           147:        vnode_t vp;
        !           148:        int err;
        !           149:
        !           150:        DPRINTF(VFSDB_VNODE, ("lookup: path=%s\n", path));
        !           151:
        !           152:        /*
        !           153:         * Get the path for directory.
        !           154:         */
        !           155:        strcpy(buf, path);
        !           156:        file = strrchr(buf, '/');
        !           157:        if (!buf[0])
        !           158:                return ENOTDIR;
        !           159:        if (file == buf)
        !           160:                dir = root;
        !           161:        else {
        !           162:                *file = '\0';
        !           163:                dir = buf;
        !           164:        }
        !           165:        /*
        !           166:         * Get the vnode for directory
        !           167:         */
        !           168:        if ((err = namei(dir, &vp)) != 0)
        !           169:                return err;
        !           170:        if (vp->v_type != VDIR) {
        !           171:                vput(vp);
        !           172:                return ENOTDIR;
        !           173:        }
        !           174:        *vpp = vp;
        !           175:
        !           176:        /*
        !           177:         * Get the file name
        !           178:         */
        !           179:        *name = strrchr(path, '/') + 1;
        !           180:        return 0;
        !           181: }

CVSweb