1 /* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94 39 */ 40 41 #include <sys/cdefs.h> 42 __FBSDID("$FreeBSD$"); 43 44 #include "opt_ktrace.h" 45 #include "opt_mac.h" 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/lock.h> 51 #include <sys/mac.h> 52 #include <sys/mutex.h> 53 #include <sys/namei.h> 54 #include <sys/vnode.h> 55 #include <sys/mount.h> 56 #include <sys/filedesc.h> 57 #include <sys/proc.h> 58 #ifdef KTRACE 59 #include <sys/ktrace.h> 60 #endif 61 62 #include <vm/uma.h> 63 64 /* 65 * Allocation zone for namei 66 */ 67 uma_zone_t namei_zone; 68 69 static void 70 nameiinit(void *dummy __unused) 71 { 72 namei_zone = uma_zcreate("NAMEI", MAXPATHLEN, NULL, NULL, NULL, NULL, 73 UMA_ALIGN_PTR, 0); 74 75 } 76 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL) 77 78 /* 79 * Convert a pathname into a pointer to a locked inode. 80 * 81 * The FOLLOW flag is set when symbolic links are to be followed 82 * when they occur at the end of the name translation process. 83 * Symbolic links are always followed for all other pathname 84 * components other than the last. 85 * 86 * The segflg defines whether the name is to be copied from user 87 * space or kernel space. 88 * 89 * Overall outline of namei: 90 * 91 * copy in name 92 * get starting directory 93 * while (!done && !error) { 94 * call lookup to search path. 95 * if symbolic link, massage name in buffer and continue 96 * } 97 */ 98 int 99 namei(ndp) 100 register struct nameidata *ndp; 101 { 102 register struct filedesc *fdp; /* pointer to file descriptor state */ 103 register char *cp; /* pointer into pathname argument */ 104 register struct vnode *dp; /* the directory we are searching */ 105 struct iovec aiov; /* uio for reading symbolic links */ 106 struct uio auio; 107 int error, linklen; 108 struct componentname *cnp = &ndp->ni_cnd; 109 struct thread *td = cnp->cn_thread; 110 struct proc *p = td->td_proc; 111 112 ndp->ni_cnd.cn_cred = ndp->ni_cnd.cn_thread->td_ucred; 113 KASSERT(cnp->cn_cred && p, ("namei: bad cred/proc")); 114 KASSERT((cnp->cn_nameiop & (~OPMASK)) == 0, 115 ("namei: nameiop contaminated with flags")); 116 KASSERT((cnp->cn_flags & OPMASK) == 0, 117 ("namei: flags contaminated with nameiops")); 118 fdp = p->p_fd; 119 120 /* 121 * Get a buffer for the name to be translated, and copy the 122 * name into the buffer. 123 */ 124 if ((cnp->cn_flags & HASBUF) == 0) 125 cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK); 126 if (ndp->ni_segflg == UIO_SYSSPACE) 127 error = copystr(ndp->ni_dirp, cnp->cn_pnbuf, 128 MAXPATHLEN, (size_t *)&ndp->ni_pathlen); 129 else 130 error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf, 131 MAXPATHLEN, (size_t *)&ndp->ni_pathlen); 132 133 /* 134 * Don't allow empty pathnames. 135 */ 136 if (!error && *cnp->cn_pnbuf == '\0') 137 error = ENOENT; 138 139 if (error) { 140 uma_zfree(namei_zone, cnp->cn_pnbuf); 141 #ifdef DIAGNOSTIC 142 cnp->cn_pnbuf = NULL; 143 cnp->cn_nameptr = NULL; 144 #endif 145 ndp->ni_vp = NULL; 146 return (error); 147 } 148 ndp->ni_loopcnt = 0; 149 #ifdef KTRACE 150 if (KTRPOINT(td, KTR_NAMEI)) { 151 KASSERT(cnp->cn_thread == curthread, 152 ("namei not using curthread")); 153 ktrnamei(cnp->cn_pnbuf); 154 } 155 #endif 156 157 /* 158 * Get starting point for the translation. 159 */ 160 FILEDESC_LOCK(fdp); 161 ndp->ni_rootdir = fdp->fd_rdir; 162 ndp->ni_topdir = fdp->fd_jdir; 163 164 dp = fdp->fd_cdir; 165 VREF(dp); 166 FILEDESC_UNLOCK(fdp); 167 for (;;) { 168 /* 169 * Check if root directory should replace current directory. 170 * Done at start of translation and after symbolic link. 171 */ 172 cnp->cn_nameptr = cnp->cn_pnbuf; 173 if (*(cnp->cn_nameptr) == '/') { 174 vrele(dp); 175 while (*(cnp->cn_nameptr) == '/') { 176 cnp->cn_nameptr++; 177 ndp->ni_pathlen--; 178 } 179 dp = ndp->ni_rootdir; 180 VREF(dp); 181 } 182 ndp->ni_startdir = dp; 183 error = lookup(ndp); 184 if (error) { 185 uma_zfree(namei_zone, cnp->cn_pnbuf); 186 #ifdef DIAGNOSTIC 187 cnp->cn_pnbuf = NULL; 188 cnp->cn_nameptr = NULL; 189 #endif 190 return (error); 191 } 192 /* 193 * Check for symbolic link 194 */ 195 if ((cnp->cn_flags & ISSYMLINK) == 0) { 196 if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) { 197 uma_zfree(namei_zone, cnp->cn_pnbuf); 198 #ifdef DIAGNOSTIC 199 cnp->cn_pnbuf = NULL; 200 cnp->cn_nameptr = NULL; 201 #endif 202 } else 203 cnp->cn_flags |= HASBUF; 204 205 if (vn_canvmio(ndp->ni_vp) == TRUE && 206 (cnp->cn_nameiop != DELETE) && 207 ((cnp->cn_flags & (NOOBJ|LOCKLEAF)) == 208 LOCKLEAF)) 209 vfs_object_create(ndp->ni_vp, td, 210 ndp->ni_cnd.cn_cred); 211 212 return (0); 213 } 214 if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1) 215 VOP_UNLOCK(ndp->ni_dvp, 0, td); 216 if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { 217 error = ELOOP; 218 break; 219 } 220 #ifdef MAC 221 if ((cnp->cn_flags & NOMACCHECK) == 0) { 222 error = mac_check_vnode_readlink(td->td_ucred, 223 ndp->ni_vp); 224 if (error) 225 break; 226 } 227 #endif 228 if (ndp->ni_pathlen > 1) 229 cp = uma_zalloc(namei_zone, M_WAITOK); 230 else 231 cp = cnp->cn_pnbuf; 232 aiov.iov_base = cp; 233 aiov.iov_len = MAXPATHLEN; 234 auio.uio_iov = &aiov; 235 auio.uio_iovcnt = 1; 236 auio.uio_offset = 0; 237 auio.uio_rw = UIO_READ; 238 auio.uio_segflg = UIO_SYSSPACE; 239 auio.uio_td = (struct thread *)0; 240 auio.uio_resid = MAXPATHLEN; 241 error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred); 242 if (error) { 243 if (ndp->ni_pathlen > 1) 244 uma_zfree(namei_zone, cp); 245 break; 246 } 247 linklen = MAXPATHLEN - auio.uio_resid; 248 if (linklen == 0) { 249 if (ndp->ni_pathlen > 1) 250 uma_zfree(namei_zone, cp); 251 error = ENOENT; 252 break; 253 } 254 if (linklen + ndp->ni_pathlen >= MAXPATHLEN) { 255 if (ndp->ni_pathlen > 1) 256 uma_zfree(namei_zone, cp); 257 error = ENAMETOOLONG; 258 break; 259 } 260 if (ndp->ni_pathlen > 1) { 261 bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen); 262 uma_zfree(namei_zone, cnp->cn_pnbuf); 263 cnp->cn_pnbuf = cp; 264 } else 265 cnp->cn_pnbuf[linklen] = '\0'; 266 ndp->ni_pathlen += linklen; 267 vput(ndp->ni_vp); 268 dp = ndp->ni_dvp; 269 } 270 uma_zfree(namei_zone, cnp->cn_pnbuf); 271 #ifdef DIAGNOSTIC 272 cnp->cn_pnbuf = NULL; 273 cnp->cn_nameptr = NULL; 274 #endif 275 vrele(ndp->ni_dvp); 276 vput(ndp->ni_vp); 277 ndp->ni_vp = NULL; 278 return (error); 279 } 280 281 /* 282 * Search a pathname. 283 * This is a very central and rather complicated routine. 284 * 285 * The pathname is pointed to by ni_ptr and is of length ni_pathlen. 286 * The starting directory is taken from ni_startdir. The pathname is 287 * descended until done, or a symbolic link is encountered. The variable 288 * ni_more is clear if the path is completed; it is set to one if a 289 * symbolic link needing interpretation is encountered. 290 * 291 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on 292 * whether the name is to be looked up, created, renamed, or deleted. 293 * When CREATE, RENAME, or DELETE is specified, information usable in 294 * creating, renaming, or deleting a directory entry may be calculated. 295 * If flag has LOCKPARENT or'ed into it, the parent directory is returned 296 * locked. If flag has WANTPARENT or'ed into it, the parent directory is 297 * returned unlocked. Otherwise the parent directory is not returned. If 298 * the target of the pathname exists and LOCKLEAF is or'ed into the flag 299 * the target is returned locked, otherwise it is returned unlocked. 300 * When creating or renaming and LOCKPARENT is specified, the target may not 301 * be ".". When deleting and LOCKPARENT is specified, the target may be ".". 302 * 303 * Overall outline of lookup: 304 * 305 * dirloop: 306 * identify next component of name at ndp->ni_ptr 307 * handle degenerate case where name is null string 308 * if .. and crossing mount points and on mounted filesys, find parent 309 * call VOP_LOOKUP routine for next component name 310 * directory vnode returned in ni_dvp, unlocked unless LOCKPARENT set 311 * component vnode returned in ni_vp (if it exists), locked. 312 * if result vnode is mounted on and crossing mount points, 313 * find mounted on vnode 314 * if more components of name, do next level at dirloop 315 * return the answer in ni_vp, locked if LOCKLEAF set 316 * if LOCKPARENT set, return locked parent in ni_dvp 317 * if WANTPARENT set, return unlocked parent in ni_dvp 318 */ 319 int 320 lookup(ndp) 321 register struct nameidata *ndp; 322 { 323 register char *cp; /* pointer into pathname argument */ 324 register struct vnode *dp = 0; /* the directory we are searching */ 325 struct vnode *tdp; /* saved dp */ 326 struct mount *mp; /* mount table entry */ 327 int docache; /* == 0 do not cache last component */ 328 int wantparent; /* 1 => wantparent or lockparent flag */ 329 int rdonly; /* lookup read-only flag bit */ 330 int trailing_slash; 331 int error = 0; 332 int dpunlocked = 0; /* dp has already been unlocked */ 333 struct componentname *cnp = &ndp->ni_cnd; 334 struct thread *td = cnp->cn_thread; 335 336 /* 337 * Setup: break out flag bits into variables. 338 */ 339 wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT); 340 docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; 341 if (cnp->cn_nameiop == DELETE || 342 (wantparent && cnp->cn_nameiop != CREATE && 343 cnp->cn_nameiop != LOOKUP)) 344 docache = 0; 345 rdonly = cnp->cn_flags & RDONLY; 346 ndp->ni_dvp = NULL; 347 cnp->cn_flags &= ~ISSYMLINK; 348 dp = ndp->ni_startdir; 349 ndp->ni_startdir = NULLVP; 350 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td); 351 352 dirloop: 353 /* 354 * Search a new directory. 355 * 356 * The last component of the filename is left accessible via 357 * cnp->cn_nameptr for callers that need the name. Callers needing 358 * the name set the SAVENAME flag. When done, they assume 359 * responsibility for freeing the pathname buffer. 360 */ 361 cnp->cn_consume = 0; 362 for (cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++) 363 continue; 364 cnp->cn_namelen = cp - cnp->cn_nameptr; 365 if (cnp->cn_namelen > NAME_MAX) { 366 error = ENAMETOOLONG; 367 goto bad; 368 } 369 #ifdef NAMEI_DIAGNOSTIC 370 { char c = *cp; 371 *cp = '\0'; 372 printf("{%s}: ", cnp->cn_nameptr); 373 *cp = c; } 374 #endif 375 ndp->ni_pathlen -= cnp->cn_namelen; 376 ndp->ni_next = cp; 377 378 /* 379 * Replace multiple slashes by a single slash and trailing slashes 380 * by a null. This must be done before VOP_LOOKUP() because some 381 * fs's don't know about trailing slashes. Remember if there were 382 * trailing slashes to handle symlinks, existing non-directories 383 * and non-existing files that won't be directories specially later. 384 */ 385 trailing_slash = 0; 386 while (*cp == '/' && (cp[1] == '/' || cp[1] == '\0')) { 387 cp++; 388 ndp->ni_pathlen--; 389 if (*cp == '\0') { 390 trailing_slash = 1; 391 *ndp->ni_next = '\0'; /* XXX for direnter() ... */ 392 } 393 } 394 ndp->ni_next = cp; 395 396 cnp->cn_flags |= MAKEENTRY; 397 if (*cp == '\0' && docache == 0) 398 cnp->cn_flags &= ~MAKEENTRY; 399 if (cnp->cn_namelen == 2 && 400 cnp->cn_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.') 401 cnp->cn_flags |= ISDOTDOT; 402 else 403 cnp->cn_flags &= ~ISDOTDOT; 404 if (*ndp->ni_next == 0) 405 cnp->cn_flags |= ISLASTCN; 406 else 407 cnp->cn_flags &= ~ISLASTCN; 408 409 410 /* 411 * Check for degenerate name (e.g. / or "") 412 * which is a way of talking about a directory, 413 * e.g. like "/." or ".". 414 */ 415 if (cnp->cn_nameptr[0] == '\0') { 416 if (dp->v_type != VDIR) { 417 error = ENOTDIR; 418 goto bad; 419 } 420 if (cnp->cn_nameiop != LOOKUP) { 421 error = EISDIR; 422 goto bad; 423 } 424 if (wantparent) { 425 ndp->ni_dvp = dp; 426 VREF(dp); 427 } 428 ndp->ni_vp = dp; 429 if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF))) 430 VOP_UNLOCK(dp, 0, td); 431 /* XXX This should probably move to the top of function. */ 432 if (cnp->cn_flags & SAVESTART) 433 panic("lookup: SAVESTART"); 434 return (0); 435 } 436 437 /* 438 * Handle "..": two special cases. 439 * 1. If at root directory (e.g. after chroot) 440 * or at absolute root directory 441 * then ignore it so can't get out. 442 * 2. If this vnode is the root of a mounted 443 * filesystem, then replace it with the 444 * vnode which was mounted on so we take the 445 * .. in the other filesystem. 446 * 3. If the vnode is the top directory of 447 * the jail or chroot, don't let them out. 448 */ 449 if (cnp->cn_flags & ISDOTDOT) { 450 for (;;) { 451 if (dp == ndp->ni_rootdir || 452 dp == ndp->ni_topdir || 453 dp == rootvnode) { 454 ndp->ni_dvp = dp; 455 ndp->ni_vp = dp; 456 VREF(dp); 457 goto nextname; 458 } 459 if ((dp->v_vflag & VV_ROOT) == 0 || 460 (cnp->cn_flags & NOCROSSMOUNT)) 461 break; 462 if (dp->v_mount == NULL) { /* forced unmount */ 463 error = EBADF; 464 goto bad; 465 } 466 tdp = dp; 467 dp = dp->v_mount->mnt_vnodecovered; 468 vput(tdp); 469 VREF(dp); 470 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td); 471 } 472 } 473 474 /* 475 * We now have a segment name to search for, and a directory to search. 476 */ 477 unionlookup: 478 #ifdef MAC 479 if ((cnp->cn_flags & NOMACCHECK) == 0) { 480 error = mac_check_vnode_lookup(td->td_ucred, dp, cnp); 481 if (error) 482 goto bad; 483 } 484 #endif 485 ndp->ni_dvp = dp; 486 ndp->ni_vp = NULL; 487 cnp->cn_flags &= ~PDIRUNLOCK; 488 ASSERT_VOP_LOCKED(dp, "lookup"); 489 if ((error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) != 0) { 490 KASSERT(ndp->ni_vp == NULL, ("leaf should be empty")); 491 #ifdef NAMEI_DIAGNOSTIC 492 printf("not found\n"); 493 #endif 494 if ((error == ENOENT) && 495 (dp->v_vflag & VV_ROOT) && (dp->v_mount != NULL) && 496 (dp->v_mount->mnt_flag & MNT_UNION)) { 497 tdp = dp; 498 dp = dp->v_mount->mnt_vnodecovered; 499 if (cnp->cn_flags & PDIRUNLOCK) 500 vrele(tdp); 501 else 502 vput(tdp); 503 VREF(dp); 504 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td); 505 goto unionlookup; 506 } 507 508 if (error != EJUSTRETURN) 509 goto bad; 510 /* 511 * If creating and at end of pathname, then can consider 512 * allowing file to be created. 513 */ 514 if (rdonly) { 515 error = EROFS; 516 goto bad; 517 } 518 if (*cp == '\0' && trailing_slash && 519 !(cnp->cn_flags & WILLBEDIR)) { 520 error = ENOENT; 521 goto bad; 522 } 523 /* 524 * We return with ni_vp NULL to indicate that the entry 525 * doesn't currently exist, leaving a pointer to the 526 * (possibly locked) directory inode in ndp->ni_dvp. 527 */ 528 if (cnp->cn_flags & SAVESTART) { 529 ndp->ni_startdir = ndp->ni_dvp; 530 VREF(ndp->ni_startdir); 531 } 532 return (0); 533 } 534 #ifdef NAMEI_DIAGNOSTIC 535 printf("found\n"); 536 #endif 537 538 ASSERT_VOP_LOCKED(ndp->ni_vp, "lookup"); 539 540 /* 541 * Take into account any additional components consumed by 542 * the underlying filesystem. 543 */ 544 if (cnp->cn_consume > 0) { 545 cnp->cn_nameptr += cnp->cn_consume; 546 ndp->ni_next += cnp->cn_consume; 547 ndp->ni_pathlen -= cnp->cn_consume; 548 cnp->cn_consume = 0; 549 } 550 551 dp = ndp->ni_vp; 552 553 /* 554 * Check to see if the vnode has been mounted on; 555 * if so find the root of the mounted filesystem. 556 */ 557 while (dp->v_type == VDIR && (mp = dp->v_mountedhere) && 558 (cnp->cn_flags & NOCROSSMOUNT) == 0) { 559 if (vfs_busy(mp, 0, 0, td)) 560 continue; 561 VOP_UNLOCK(dp, 0, td); 562 error = VFS_ROOT(mp, &tdp); 563 vfs_unbusy(mp, td); 564 if (error) { 565 dpunlocked = 1; 566 goto bad2; 567 } 568 vrele(dp); 569 ndp->ni_vp = dp = tdp; 570 } 571 572 /* 573 * Check for symbolic link 574 */ 575 if ((dp->v_type == VLNK) && 576 ((cnp->cn_flags & FOLLOW) || trailing_slash || 577 *ndp->ni_next == '/')) { 578 cnp->cn_flags |= ISSYMLINK; 579 if (dp->v_mount == NULL) { 580 /* We can't know whether the directory was mounted with 581 * NOSYMFOLLOW, so we can't follow safely. */ 582 error = EBADF; 583 goto bad2; 584 } 585 if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) { 586 error = EACCES; 587 goto bad2; 588 } 589 return (0); 590 } 591 592 /* 593 * Check for bogus trailing slashes. 594 */ 595 if (trailing_slash && dp->v_type != VDIR) { 596 error = ENOTDIR; 597 goto bad2; 598 } 599 600 nextname: 601 /* 602 * Not a symbolic link. If more pathname, 603 * continue at next component, else return. 604 */ 605 if (*ndp->ni_next == '/') { 606 cnp->cn_nameptr = ndp->ni_next; 607 while (*cnp->cn_nameptr == '/') { 608 cnp->cn_nameptr++; 609 ndp->ni_pathlen--; 610 } 611 if (ndp->ni_dvp != ndp->ni_vp) 612 ASSERT_VOP_UNLOCKED(ndp->ni_dvp, "lookup"); 613 vrele(ndp->ni_dvp); 614 goto dirloop; 615 } 616 /* 617 * Disallow directory write attempts on read-only filesystems. 618 */ 619 if (rdonly && 620 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { 621 error = EROFS; 622 goto bad2; 623 } 624 if (cnp->cn_flags & SAVESTART) { 625 ndp->ni_startdir = ndp->ni_dvp; 626 VREF(ndp->ni_startdir); 627 } 628 if (!wantparent) 629 vrele(ndp->ni_dvp); 630 631 if ((cnp->cn_flags & LOCKLEAF) == 0) 632 VOP_UNLOCK(dp, 0, td); 633 return (0); 634 635 bad2: 636 if ((cnp->cn_flags & (LOCKPARENT | PDIRUNLOCK)) == LOCKPARENT && 637 *ndp->ni_next == '\0') 638 VOP_UNLOCK(ndp->ni_dvp, 0, td); 639 vrele(ndp->ni_dvp); 640 bad: 641 if (dpunlocked) 642 vrele(dp); 643 else 644 vput(dp); 645 ndp->ni_vp = NULL; 646 return (error); 647 } 648 649 /* 650 * relookup - lookup a path name component 651 * Used by lookup to re-aquire things. 652 */ 653 int 654 relookup(dvp, vpp, cnp) 655 struct vnode *dvp, **vpp; 656 struct componentname *cnp; 657 { 658 struct thread *td = cnp->cn_thread; 659 struct vnode *dp = 0; /* the directory we are searching */ 660 int docache; /* == 0 do not cache last component */ 661 int wantparent; /* 1 => wantparent or lockparent flag */ 662 int rdonly; /* lookup read-only flag bit */ 663 int error = 0; 664 #ifdef NAMEI_DIAGNOSTIC 665 int newhash; /* DEBUG: check name hash */ 666 char *cp; /* DEBUG: check name ptr/len */ 667 #endif 668 669 /* 670 * Setup: break out flag bits into variables. 671 */ 672 wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); 673 docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; 674 if (cnp->cn_nameiop == DELETE || 675 (wantparent && cnp->cn_nameiop != CREATE)) 676 docache = 0; 677 rdonly = cnp->cn_flags & RDONLY; 678 cnp->cn_flags &= ~ISSYMLINK; 679 dp = dvp; 680 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td); 681 682 /* dirloop: */ 683 /* 684 * Search a new directory. 685 * 686 * The last component of the filename is left accessible via 687 * cnp->cn_nameptr for callers that need the name. Callers needing 688 * the name set the SAVENAME flag. When done, they assume 689 * responsibility for freeing the pathname buffer. 690 */ 691 #ifdef NAMEI_DIAGNOSTIC 692 if (cnp->cn_namelen != cp - cnp->cn_nameptr) 693 panic ("relookup: bad len"); 694 if (*cp != 0) 695 panic("relookup: not last component"); 696 printf("{%s}: ", cnp->cn_nameptr); 697 #endif 698 699 /* 700 * Check for degenerate name (e.g. / or "") 701 * which is a way of talking about a directory, 702 * e.g. like "/." or ".". 703 */ 704 if (cnp->cn_nameptr[0] == '\0') { 705 if (cnp->cn_nameiop != LOOKUP || wantparent) { 706 error = EISDIR; 707 goto bad; 708 } 709 if (dp->v_type != VDIR) { 710 error = ENOTDIR; 711 goto bad; 712 } 713 if (!(cnp->cn_flags & LOCKLEAF)) 714 VOP_UNLOCK(dp, 0, td); 715 *vpp = dp; 716 /* XXX This should probably move to the top of function. */ 717 if (cnp->cn_flags & SAVESTART) 718 panic("lookup: SAVESTART"); 719 return (0); 720 } 721 722 if (cnp->cn_flags & ISDOTDOT) 723 panic ("relookup: lookup on dot-dot"); 724 725 /* 726 * We now have a segment name to search for, and a directory to search. 727 */ 728 if ((error = VOP_LOOKUP(dp, vpp, cnp)) != 0) { 729 KASSERT(*vpp == NULL, ("leaf should be empty")); 730 if (error != EJUSTRETURN) 731 goto bad; 732 /* 733 * If creating and at end of pathname, then can consider 734 * allowing file to be created. 735 */ 736 if (rdonly) { 737 error = EROFS; 738 goto bad; 739 } 740 /* ASSERT(dvp == ndp->ni_startdir) */ 741 if (cnp->cn_flags & SAVESTART) 742 VREF(dvp); 743 /* 744 * We return with ni_vp NULL to indicate that the entry 745 * doesn't currently exist, leaving a pointer to the 746 * (possibly locked) directory inode in ndp->ni_dvp. 747 */ 748 return (0); 749 } 750 dp = *vpp; 751 752 /* 753 * Check for symbolic link 754 */ 755 KASSERT(dp->v_type != VLNK || !(cnp->cn_flags & FOLLOW), 756 ("relookup: symlink found.\n")); 757 758 /* 759 * Disallow directory write attempts on read-only filesystems. 760 */ 761 if (rdonly && 762 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { 763 error = EROFS; 764 goto bad2; 765 } 766 /* ASSERT(dvp == ndp->ni_startdir) */ 767 if (cnp->cn_flags & SAVESTART) 768 VREF(dvp); 769 770 if (!wantparent) 771 vrele(dvp); 772 773 if (vn_canvmio(dp) == TRUE && 774 ((cnp->cn_flags & (NOOBJ|LOCKLEAF)) == LOCKLEAF)) 775 vfs_object_create(dp, td, cnp->cn_cred); 776 777 if ((cnp->cn_flags & LOCKLEAF) == 0) 778 VOP_UNLOCK(dp, 0, td); 779 return (0); 780 781 bad2: 782 if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN)) 783 VOP_UNLOCK(dvp, 0, td); 784 vrele(dvp); 785 bad: 786 vput(dp); 787 *vpp = NULL; 788 return (error); 789 } 790