1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)vfs_lookup.c 7.30 (Berkeley) 05/15/91 8 */ 9 10 #include "param.h" 11 #include "syslimits.h" 12 #include "time.h" 13 #include "namei.h" 14 #include "vnode.h" 15 #include "mount.h" 16 #include "errno.h" 17 #include "malloc.h" 18 #include "filedesc.h" 19 #include "proc.h" 20 21 #ifdef KTRACE 22 #include "ktrace.h" 23 #endif 24 25 /* 26 * Convert a pathname into a pointer to a locked inode. 27 * 28 * The FOLLOW flag is set when symbolic links are to be followed 29 * when they occur at the end of the name translation process. 30 * Symbolic links are always followed for all other pathname 31 * components other than the last. 32 * 33 * The segflg defines whether the name is to be copied from user 34 * space or kernel space. 35 * 36 * Overall outline of namei: 37 * 38 * copy in name 39 * get starting directory 40 * while (!done && !error) { 41 * call lookup to search path. 42 * if symbolic link, massage name in buffer and continue 43 * } 44 */ 45 namei(ndp, p) 46 register struct nameidata *ndp; 47 struct proc *p; 48 { 49 register struct filedesc *fdp; /* pointer to file descriptor state */ 50 register char *cp; /* pointer into pathname argument */ 51 register struct vnode *dp; /* the directory we are searching */ 52 struct iovec aiov; /* uio for reading symbolic links */ 53 struct uio auio; 54 int error, linklen; 55 56 ndp->ni_cred = p->p_ucred; 57 fdp = p->p_fd; 58 59 /* 60 * Get a buffer for the name to be translated, and copy the 61 * name into the buffer. 62 */ 63 #ifdef DIAGNOSTIC 64 if (ndp->ni_nameiop & HASBUF) 65 panic("namei: reentered"); 66 #endif 67 MALLOC(ndp->ni_pnbuf, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK); 68 if (ndp->ni_segflg == UIO_SYSSPACE) 69 error = copystr(ndp->ni_dirp, ndp->ni_pnbuf, 70 MAXPATHLEN, &ndp->ni_pathlen); 71 else 72 error = copyinstr(ndp->ni_dirp, ndp->ni_pnbuf, 73 MAXPATHLEN, &ndp->ni_pathlen); 74 if (error) { 75 free(ndp->ni_pnbuf, M_NAMEI); 76 ndp->ni_vp = NULL; 77 return (error); 78 } 79 ndp->ni_loopcnt = 0; 80 #ifdef KTRACE 81 if (KTRPOINT(p, KTR_NAMEI)) 82 ktrnamei(p->p_tracep, ndp->ni_pnbuf); 83 #endif 84 85 /* 86 * Get starting point for the translation. 87 */ 88 if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL) 89 ndp->ni_rootdir = rootdir; 90 dp = fdp->fd_cdir; 91 VREF(dp); 92 for (;;) { 93 /* 94 * Check if root directory should replace current directory. 95 * Done at start of translation and after symbolic link. 96 */ 97 ndp->ni_ptr = ndp->ni_pnbuf; 98 if (*ndp->ni_ptr == '/') { 99 vrele(dp); 100 while (*ndp->ni_ptr == '/') { 101 ndp->ni_ptr++; 102 ndp->ni_pathlen--; 103 } 104 dp = ndp->ni_rootdir; 105 VREF(dp); 106 } 107 ndp->ni_startdir = dp; 108 if (error = lookup(ndp, p)) { 109 FREE(ndp->ni_pnbuf, M_NAMEI); 110 return (error); 111 } 112 /* 113 * Check for symbolic link 114 */ 115 if (ndp->ni_more == 0) { 116 if ((ndp->ni_nameiop & (SAVENAME | SAVESTART)) == 0) 117 FREE(ndp->ni_pnbuf, M_NAMEI); 118 else 119 ndp->ni_nameiop |= HASBUF; 120 return (0); 121 } 122 if ((ndp->ni_nameiop & LOCKPARENT) && ndp->ni_pathlen == 1) 123 VOP_UNLOCK(ndp->ni_dvp); 124 if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { 125 error = ELOOP; 126 break; 127 } 128 if (ndp->ni_pathlen > 1) 129 MALLOC(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); 130 else 131 cp = ndp->ni_pnbuf; 132 aiov.iov_base = cp; 133 aiov.iov_len = MAXPATHLEN; 134 auio.uio_iov = &aiov; 135 auio.uio_iovcnt = 1; 136 auio.uio_offset = 0; 137 auio.uio_rw = UIO_READ; 138 auio.uio_segflg = UIO_SYSSPACE; 139 auio.uio_procp = (struct proc *)0; 140 auio.uio_resid = MAXPATHLEN; 141 if (error = VOP_READLINK(ndp->ni_vp, &auio, p->p_ucred)) { 142 if (ndp->ni_pathlen > 1) 143 free(cp, M_NAMEI); 144 break; 145 } 146 linklen = MAXPATHLEN - auio.uio_resid; 147 if (linklen + ndp->ni_pathlen >= MAXPATHLEN) { 148 if (ndp->ni_pathlen > 1) 149 free(cp, M_NAMEI); 150 error = ENAMETOOLONG; 151 break; 152 } 153 if (ndp->ni_pathlen > 1) { 154 bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen); 155 FREE(ndp->ni_pnbuf, M_NAMEI); 156 ndp->ni_pnbuf = cp; 157 } else 158 ndp->ni_pnbuf[linklen] = '\0'; 159 ndp->ni_pathlen += linklen; 160 vput(ndp->ni_vp); 161 dp = ndp->ni_dvp; 162 } 163 FREE(ndp->ni_pnbuf, M_NAMEI); 164 vrele(ndp->ni_dvp); 165 vput(ndp->ni_vp); 166 ndp->ni_vp = NULL; 167 return (error); 168 } 169 170 /* 171 * Search a pathname. 172 * This is a very central and rather complicated routine. 173 * 174 * The pathname is pointed to by ni_ptr and is of length ni_pathlen. 175 * The starting directory is taken from ni_startdir. The pathname is 176 * descended until done, or a symbolic link is encountered. The variable 177 * ni_more is clear if the path is completed; it is set to one if a 178 * symbolic link needing interpretation is encountered. 179 * 180 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on 181 * whether the name is to be looked up, created, renamed, or deleted. 182 * When CREATE, RENAME, or DELETE is specified, information usable in 183 * creating, renaming, or deleting a directory entry may be calculated. 184 * If flag has LOCKPARENT or'ed into it, the parent directory is returned 185 * locked. If flag has WANTPARENT or'ed into it, the parent directory is 186 * returned unlocked. Otherwise the parent directory is not returned. If 187 * the target of the pathname exists and LOCKLEAF is or'ed into the flag 188 * the target is returned locked, otherwise it is returned unlocked. 189 * When creating or renaming and LOCKPARENT is specified, the target may not 190 * be ".". When deleting and LOCKPARENT is specified, the target may be ".". 191 * NOTE: (LOOKUP | LOCKPARENT) currently returns the parent vnode unlocked. 192 * 193 * Overall outline of lookup: 194 * 195 * dirloop: 196 * identify next component of name at ndp->ni_ptr 197 * handle degenerate case where name is null string 198 * if .. and crossing mount points and on mounted filesys, find parent 199 * call VOP_LOOKUP routine for next component name 200 * directory vnode returned in ni_dvp, unlocked unless LOCKPARENT set 201 * component vnode returned in ni_vp (if it exists), locked. 202 * if result vnode is mounted on and crossing mount points, 203 * find mounted on vnode 204 * if more components of name, do next level at dirloop 205 * return the answer in ni_vp, locked if LOCKLEAF set 206 * if LOCKPARENT set, return locked parent in ni_dvp 207 * if WANTPARENT set, return unlocked parent in ni_dvp 208 */ 209 lookup(ndp, p) 210 register struct nameidata *ndp; 211 struct proc *p; 212 { 213 register char *cp; /* pointer into pathname argument */ 214 register struct vnode *dp = 0; /* the directory we are searching */ 215 struct vnode *tdp; /* saved dp */ 216 struct mount *mp; /* mount table entry */ 217 int docache; /* == 0 do not cache last component */ 218 int flag; /* LOOKUP, CREATE, RENAME or DELETE */ 219 int wantparent; /* 1 => wantparent or lockparent flag */ 220 int rdonly; /* mounted read-only flag bit(s) */ 221 int error = 0; 222 223 /* 224 * Setup: break out flag bits into variables. 225 */ 226 flag = ndp->ni_nameiop & OPMASK; 227 wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT); 228 docache = (ndp->ni_nameiop & NOCACHE) ^ NOCACHE; 229 if (flag == DELETE || (wantparent && flag != CREATE)) 230 docache = 0; 231 rdonly = MNT_RDONLY; 232 if (ndp->ni_nameiop & REMOTE) 233 rdonly |= MNT_EXRDONLY; 234 ndp->ni_dvp = NULL; 235 ndp->ni_more = 0; 236 dp = ndp->ni_startdir; 237 ndp->ni_startdir = NULLVP; 238 VOP_LOCK(dp); 239 240 dirloop: 241 /* 242 * Search a new directory. 243 * 244 * The ni_hash value is for use by vfs_cache. 245 * The last component of the filename is left accessible via 246 * ndp->ptr for callers that need the name. Callers needing 247 * the name set the SAVENAME flag. When done, they assume 248 * responsibility for freeing the pathname buffer. 249 */ 250 ndp->ni_hash = 0; 251 for (cp = ndp->ni_ptr; *cp != 0 && *cp != '/'; cp++) { 252 ndp->ni_hash += (unsigned char)*cp; 253 if ((*cp & 0200) == 0) 254 continue; 255 if ((*cp & 0377) == ('/' | 0200) || flag != DELETE) { 256 error = EINVAL; 257 goto bad; 258 } 259 } 260 ndp->ni_namelen = cp - ndp->ni_ptr; 261 if (ndp->ni_namelen >= NAME_MAX) { 262 error = ENAMETOOLONG; 263 goto bad; 264 } 265 #ifdef NAMEI_DIAGNOSTIC 266 { char c = *cp; 267 *cp = '\0'; 268 printf("{%s}: ", ndp->ni_ptr); 269 *cp = c; } 270 #endif 271 ndp->ni_pathlen -= ndp->ni_namelen; 272 ndp->ni_next = cp; 273 ndp->ni_makeentry = 1; 274 if (*cp == '\0' && docache == 0) 275 ndp->ni_makeentry = 0; 276 ndp->ni_isdotdot = (ndp->ni_namelen == 2 && 277 ndp->ni_ptr[1] == '.' && ndp->ni_ptr[0] == '.'); 278 279 /* 280 * Check for degenerate name (e.g. / or "") 281 * which is a way of talking about a directory, 282 * e.g. like "/." or ".". 283 */ 284 if (ndp->ni_ptr[0] == '\0') { 285 if (flag != LOOKUP || wantparent) { 286 error = EISDIR; 287 goto bad; 288 } 289 if (dp->v_type != VDIR) { 290 error = ENOTDIR; 291 goto bad; 292 } 293 if (!(ndp->ni_nameiop & LOCKLEAF)) 294 VOP_UNLOCK(dp); 295 ndp->ni_vp = dp; 296 if (ndp->ni_nameiop & SAVESTART) 297 panic("lookup: SAVESTART"); 298 return (0); 299 } 300 301 /* 302 * Handle "..": two special cases. 303 * 1. If at root directory (e.g. after chroot) 304 * then ignore it so can't get out. 305 * 2. If this vnode is the root of a mounted 306 * filesystem, then replace it with the 307 * vnode which was mounted on so we take the 308 * .. in the other file system. 309 */ 310 if (ndp->ni_isdotdot) { 311 for (;;) { 312 if (dp == ndp->ni_rootdir) { 313 ndp->ni_dvp = dp; 314 ndp->ni_vp = dp; 315 VREF(dp); 316 goto nextname; 317 } 318 if ((dp->v_flag & VROOT) == 0 || 319 (ndp->ni_nameiop & NOCROSSMOUNT)) 320 break; 321 tdp = dp; 322 dp = dp->v_mount->mnt_vnodecovered; 323 vput(tdp); 324 VREF(dp); 325 VOP_LOCK(dp); 326 } 327 } 328 329 /* 330 * We now have a segment name to search for, and a directory to search. 331 */ 332 if (error = VOP_LOOKUP(dp, ndp, p)) { 333 #ifdef DIAGNOSTIC 334 if (ndp->ni_vp != NULL) 335 panic("leaf should be empty"); 336 #endif 337 #ifdef NAMEI_DIAGNOSTIC 338 printf("not found\n"); 339 #endif 340 if (flag == LOOKUP || flag == DELETE || 341 error != ENOENT || *cp != 0) 342 goto bad; 343 /* 344 * If creating and at end of pathname, then can consider 345 * allowing file to be created. 346 */ 347 if (ndp->ni_dvp->v_mount->mnt_flag & rdonly) { 348 error = EROFS; 349 goto bad; 350 } 351 /* 352 * We return with ni_vp NULL to indicate that the entry 353 * doesn't currently exist, leaving a pointer to the 354 * (possibly locked) directory inode in ndp->ni_dvp. 355 */ 356 if (ndp->ni_nameiop & SAVESTART) { 357 ndp->ni_startdir = ndp->ni_dvp; 358 VREF(ndp->ni_startdir); 359 } 360 return (0); 361 } 362 #ifdef NAMEI_DIAGNOSTIC 363 printf("found\n"); 364 #endif 365 366 dp = ndp->ni_vp; 367 /* 368 * Check for symbolic link 369 */ 370 if ((dp->v_type == VLNK) && 371 ((ndp->ni_nameiop & FOLLOW) || *ndp->ni_next == '/')) { 372 ndp->ni_more = 1; 373 return (0); 374 } 375 376 /* 377 * Check to see if the vnode has been mounted on; 378 * if so find the root of the mounted file system. 379 */ 380 mntloop: 381 while (dp->v_type == VDIR && (mp = dp->v_mountedhere) && 382 (ndp->ni_nameiop & NOCROSSMOUNT) == 0) { 383 while(mp->mnt_flag & MNT_MLOCK) { 384 mp->mnt_flag |= MNT_MWAIT; 385 sleep((caddr_t)mp, PVFS); 386 goto mntloop; 387 } 388 if (error = VFS_ROOT(dp->v_mountedhere, &tdp)) 389 goto bad2; 390 vput(dp); 391 ndp->ni_vp = dp = tdp; 392 } 393 394 nextname: 395 /* 396 * Not a symbolic link. If more pathname, 397 * continue at next component, else return. 398 */ 399 if (*ndp->ni_next == '/') { 400 ndp->ni_ptr = ndp->ni_next; 401 while (*ndp->ni_ptr == '/') { 402 ndp->ni_ptr++; 403 ndp->ni_pathlen--; 404 } 405 vrele(ndp->ni_dvp); 406 goto dirloop; 407 } 408 /* 409 * Check for read-only file systems. 410 */ 411 if (flag == DELETE || flag == RENAME) { 412 /* 413 * Disallow directory write attempts on read-only 414 * file systems. 415 */ 416 if ((dp->v_mount->mnt_flag & rdonly) || 417 (wantparent && (ndp->ni_dvp->v_mount->mnt_flag & rdonly))) { 418 error = EROFS; 419 goto bad2; 420 } 421 } 422 if (ndp->ni_nameiop & SAVESTART) { 423 ndp->ni_startdir = ndp->ni_dvp; 424 VREF(ndp->ni_startdir); 425 } 426 if (!wantparent) 427 vrele(ndp->ni_dvp); 428 if ((ndp->ni_nameiop & LOCKLEAF) == 0) 429 VOP_UNLOCK(dp); 430 return (0); 431 432 bad2: 433 if ((ndp->ni_nameiop & LOCKPARENT) && *ndp->ni_next == '\0') 434 VOP_UNLOCK(ndp->ni_dvp); 435 vrele(ndp->ni_dvp); 436 bad: 437 vput(dp); 438 ndp->ni_vp = NULL; 439 return (error); 440 } 441