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