xref: /freebsd/sys/kern/vfs_lookup.c (revision 7660b554bc59a07be0431c17e0e33815818baa69)
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