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