Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/server/fs/vfs/vfs_lookup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. namei
  2. lookup

   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  * vfs_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 "vfs.h"
  43 
  44 /*
  45  * Convert a pathname into a pointer to a locked vnode.
  46  *
  47  * @path: full path name.
  48  * @vpp:  vnode to be returned.
  49  */
  50 int
  51 namei(char *path, vnode_t *vpp)
  52 {
  53         char *p;
  54         char node[PATH_MAX];
  55         char name[PATH_MAX];
  56         mount_t mp;
  57         vnode_t dvp, vp;
  58         int error, i;
  59 
  60         DPRINTF(VFSDB_VNODE, ("namei: path=%s\n", path));
  61 
  62         /*
  63          * Convert a full path name to its mount point and
  64          * the local node in the file system.
  65          */
  66         if (vfs_findroot(path, &mp, &p))
  67                 return ENOTDIR;
  68         strlcpy(node, "/", sizeof(node));
  69         strlcat(node, p, sizeof(node));
  70         vp = vn_lookup(mp, node);
  71         if (vp) {
  72                 /* vnode is already active. */
  73                 *vpp = vp;
  74                 return 0;
  75         }
  76         /*
  77          * Find target vnode, started from root directory.
  78          * This is done to attach the fs specific data to
  79          * the target vnode.
  80          */
  81         if ((dvp = mp->m_root) == NULL)
  82                 sys_panic("VFS: no root");
  83 
  84         vref(dvp);
  85         vn_lock(dvp);
  86         node[0] = '\0';
  87 
  88         while (*p != '\0') {
  89                 /*
  90                  * Get lower directory/file name.
  91                  */
  92                 while (*p == '/')
  93                         p++;
  94                 for (i = 0; i < PATH_MAX; i++) {
  95                         if (*p == '\0' || *p == '/')
  96                                 break;
  97                         name[i] = *p++;
  98                 }
  99                 name[i] = '\0';
 100 
 101                 /*
 102                  * Get a vnode for the target.
 103                  */
 104                 strlcat(node, "/", sizeof(node));
 105                 strlcat(node, name, sizeof(node));
 106                 vp = vn_lookup(mp, node);
 107                 if (vp == NULL) {
 108                         vp = vget(mp, node);
 109                         if (vp == NULL) {
 110                                 vput(dvp);
 111                                 return ENOMEM;
 112                         }
 113                         /* Find a vnode in this directory. */
 114                         error = VOP_LOOKUP(dvp, name, vp);
 115                         if (error || (*p == '/' && vp->v_type != VDIR)) {
 116                                 /* Not found */
 117                                 vput(vp);
 118                                 vput(dvp);
 119                                 return error;
 120                         }
 121                 }
 122                 vput(dvp);
 123                 dvp = vp;
 124                 while (*p != '\0' && *p != '/')
 125                         p++;
 126         }
 127 
 128         /*
 129          * Detemine X permission.
 130          */
 131         if (vp->v_type != VDIR && sec_vnode_permission(path) != 0) {
 132                 vp->v_mode &= ~(0111);
 133         }
 134 
 135         *vpp = vp;
 136         return 0;
 137 }
 138 
 139 /*
 140  * Search a pathname.
 141  * This is a very central but not so complicated routine. ;-P
 142  *
 143  * @path: full path.
 144  * @vpp:  pointer to locked vnode for directory.
 145  * @name: pointer to file name in path.
 146  *
 147  * This routine returns a locked directory vnode and file name.
 148  */
 149 int
 150 lookup(char *path, vnode_t *vpp, char **name)
 151 {
 152         char buf[PATH_MAX];
 153         char root[] = "/";
 154         char *file, *dir;
 155         vnode_t vp;
 156         int error;
 157 
 158         DPRINTF(VFSDB_VNODE, ("lookup: path=%s\n", path));
 159 
 160         /*
 161          * Get the path for directory.
 162          */
 163         strlcpy(buf, path, sizeof(buf));
 164         file = strrchr(buf, '/');
 165         if (!buf[0])
 166                 return ENOTDIR;
 167         if (file == buf)
 168                 dir = root;
 169         else {
 170                 *file = '\0';
 171                 dir = buf;
 172         }
 173         /*
 174          * Get the vnode for directory
 175          */
 176         if ((error = namei(dir, &vp)) != 0)
 177                 return error;
 178         if (vp->v_type != VDIR) {
 179                 vput(vp);
 180                 return ENOTDIR;
 181         }
 182         *vpp = vp;
 183 
 184         /*
 185          * Get the file name
 186          */
 187         *name = strrchr(path, '/') + 1;
 188         return 0;
 189 }

/* [<][>][^][v][top][bottom][index][help] */