vfs_lookup.c revision 69405
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: head/sys/kern/vfs_lookup.c 69405 2000-11-30 20:04:44Z alfred $
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 */
78int
79namei(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	KASSERT(cnp->cn_cred && cnp->cn_proc, ("namei: bad cred/proc"));
93	KASSERT((cnp->cn_nameiop & (~OPMASK)) == 0,
94	    ("namei: nameiop contaminated with flags"));
95	KASSERT((cnp->cn_flags & OPMASK) == 0,
96	    ("namei: flags contaminated with nameiops"));
97	fdp = cnp->cn_proc->p_fd;
98
99	/*
100	 * Get a buffer for the name to be translated, and copy the
101	 * name into the buffer.
102	 */
103	if ((cnp->cn_flags & HASBUF) == 0)
104		cnp->cn_pnbuf = zalloc(namei_zone);
105	if (ndp->ni_segflg == UIO_SYSSPACE)
106		error = copystr(ndp->ni_dirp, cnp->cn_pnbuf,
107			    MAXPATHLEN, (size_t *)&ndp->ni_pathlen);
108	else
109		error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf,
110			    MAXPATHLEN, (size_t *)&ndp->ni_pathlen);
111
112	/*
113	 * Don't allow empty pathnames.
114	 */
115	if (!error && *cnp->cn_pnbuf == '\0')
116		error = ENOENT;
117
118	if (error) {
119		zfree(namei_zone, cnp->cn_pnbuf);
120		ndp->ni_vp = NULL;
121		return (error);
122	}
123	ndp->ni_loopcnt = 0;
124#ifdef KTRACE
125	if (KTRPOINT(cnp->cn_proc, KTR_NAMEI))
126		ktrnamei(cnp->cn_proc->p_tracep, cnp->cn_pnbuf);
127#endif
128
129	/*
130	 * Get starting point for the translation.
131	 */
132	ndp->ni_rootdir = fdp->fd_rdir;
133	ndp->ni_topdir = fdp->fd_jdir;
134
135	dp = fdp->fd_cdir;
136	VREF(dp);
137	for (;;) {
138		/*
139		 * Check if root directory should replace current directory.
140		 * Done at start of translation and after symbolic link.
141		 */
142		cnp->cn_nameptr = cnp->cn_pnbuf;
143		if (*(cnp->cn_nameptr) == '/') {
144			vrele(dp);
145			while (*(cnp->cn_nameptr) == '/') {
146				cnp->cn_nameptr++;
147				ndp->ni_pathlen--;
148			}
149			dp = ndp->ni_rootdir;
150			VREF(dp);
151		}
152		ndp->ni_startdir = dp;
153		error = lookup(ndp);
154		if (error) {
155			zfree(namei_zone, cnp->cn_pnbuf);
156			return (error);
157		}
158		/*
159		 * Check for symbolic link
160		 */
161		if ((cnp->cn_flags & ISSYMLINK) == 0) {
162			if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0)
163				zfree(namei_zone, cnp->cn_pnbuf);
164			else
165				cnp->cn_flags |= HASBUF;
166
167			if (vn_canvmio(ndp->ni_vp) == TRUE &&
168				(cnp->cn_nameiop != DELETE) &&
169				((cnp->cn_flags & (NOOBJ|LOCKLEAF)) ==
170				 LOCKLEAF))
171				vfs_object_create(ndp->ni_vp,
172					ndp->ni_cnd.cn_proc,
173					ndp->ni_cnd.cn_cred);
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 */
264int
265lookup(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	int dpunlocked = 0;		/* dp has already been unlocked */
278	struct componentname *cnp = &ndp->ni_cnd;
279	struct proc *p = cnp->cn_proc;
280
281	/*
282	 * Setup: break out flag bits into variables.
283	 */
284	wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
285	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
286	if (cnp->cn_nameiop == DELETE ||
287	    (wantparent && cnp->cn_nameiop != CREATE &&
288	     cnp->cn_nameiop != LOOKUP))
289		docache = 0;
290	rdonly = cnp->cn_flags & RDONLY;
291	ndp->ni_dvp = NULL;
292	cnp->cn_flags &= ~ISSYMLINK;
293	dp = ndp->ni_startdir;
294	ndp->ni_startdir = NULLVP;
295	vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
296
297dirloop:
298	/*
299	 * Search a new directory.
300	 *
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	for (cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
308		continue;
309	cnp->cn_namelen = cp - cnp->cn_nameptr;
310	if (cnp->cn_namelen > NAME_MAX) {
311		error = ENAMETOOLONG;
312		goto bad;
313	}
314#ifdef NAMEI_DIAGNOSTIC
315	{ char c = *cp;
316	*cp = '\0';
317	printf("{%s}: ", cnp->cn_nameptr);
318	*cp = c; }
319#endif
320	ndp->ni_pathlen -= cnp->cn_namelen;
321	ndp->ni_next = cp;
322
323	/*
324	 * Replace multiple slashes by a single slash and trailing slashes
325	 * by a null.  This must be done before VOP_LOOKUP() because some
326	 * fs's don't know about trailing slashes.  Remember if there were
327	 * trailing slashes to handle symlinks, existing non-directories
328	 * and non-existing files that won't be directories specially later.
329	 */
330	trailing_slash = 0;
331	while (*cp == '/' && (cp[1] == '/' || cp[1] == '\0')) {
332		cp++;
333		ndp->ni_pathlen--;
334		if (*cp == '\0') {
335			trailing_slash = 1;
336			*ndp->ni_next = '\0';	/* XXX for direnter() ... */
337		}
338	}
339	ndp->ni_next = cp;
340
341	cnp->cn_flags |= MAKEENTRY;
342	if (*cp == '\0' && docache == 0)
343		cnp->cn_flags &= ~MAKEENTRY;
344	if (cnp->cn_namelen == 2 &&
345	    cnp->cn_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.')
346		cnp->cn_flags |= ISDOTDOT;
347	else
348		cnp->cn_flags &= ~ISDOTDOT;
349	if (*ndp->ni_next == 0)
350		cnp->cn_flags |= ISLASTCN;
351	else
352		cnp->cn_flags &= ~ISLASTCN;
353
354
355	/*
356	 * Check for degenerate name (e.g. / or "")
357	 * which is a way of talking about a directory,
358	 * e.g. like "/." or ".".
359	 */
360	if (cnp->cn_nameptr[0] == '\0') {
361		if (dp->v_type != VDIR) {
362			error = ENOTDIR;
363			goto bad;
364		}
365		if (cnp->cn_nameiop != LOOKUP) {
366			error = EISDIR;
367			goto bad;
368		}
369		if (wantparent) {
370			ndp->ni_dvp = dp;
371			VREF(dp);
372		}
373		ndp->ni_vp = dp;
374		if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF)))
375			VOP_UNLOCK(dp, 0, p);
376		/* XXX This should probably move to the top of function. */
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	 * 3. If the vnode is the top directory of
392	 *    the jail or chroot, don't let them out.
393	 */
394	if (cnp->cn_flags & ISDOTDOT) {
395		for (;;) {
396			if (dp == ndp->ni_rootdir ||
397			    dp == ndp->ni_topdir ||
398			    dp == rootvnode) {
399				ndp->ni_dvp = dp;
400				ndp->ni_vp = dp;
401				VREF(dp);
402				goto nextname;
403			}
404			if ((dp->v_flag & VROOT) == 0 ||
405			    (cnp->cn_flags & NOCROSSMOUNT))
406				break;
407			if (dp->v_mount == NULL) {	/* forced unmount */
408				error = EBADF;
409				goto bad;
410			}
411			tdp = dp;
412			dp = dp->v_mount->mnt_vnodecovered;
413			vput(tdp);
414			VREF(dp);
415			vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
416		}
417	}
418
419	/*
420	 * We now have a segment name to search for, and a directory to search.
421	 */
422unionlookup:
423	ndp->ni_dvp = dp;
424	ndp->ni_vp = NULL;
425	cnp->cn_flags &= ~PDIRUNLOCK;
426	ASSERT_VOP_LOCKED(dp, "lookup");
427	if ((error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) != 0) {
428		KASSERT(ndp->ni_vp == NULL, ("leaf should be empty"));
429#ifdef NAMEI_DIAGNOSTIC
430		printf("not found\n");
431#endif
432		if ((error == ENOENT) &&
433		    (dp->v_flag & VROOT) && (dp->v_mount != NULL) &&
434		    (dp->v_mount->mnt_flag & MNT_UNION)) {
435			tdp = dp;
436			dp = dp->v_mount->mnt_vnodecovered;
437			if (cnp->cn_flags & PDIRUNLOCK)
438				vrele(tdp);
439			else
440				vput(tdp);
441			VREF(dp);
442			vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
443			goto unionlookup;
444		}
445
446		if (error != EJUSTRETURN)
447			goto bad;
448		/*
449		 * If creating and at end of pathname, then can consider
450		 * allowing file to be created.
451		 */
452		if (rdonly) {
453			error = EROFS;
454			goto bad;
455		}
456		if (*cp == '\0' && trailing_slash &&
457		     !(cnp->cn_flags & WILLBEDIR)) {
458			error = ENOENT;
459			goto bad;
460		}
461		/*
462		 * We return with ni_vp NULL to indicate that the entry
463		 * doesn't currently exist, leaving a pointer to the
464		 * (possibly locked) directory inode in ndp->ni_dvp.
465		 */
466		if (cnp->cn_flags & SAVESTART) {
467			ndp->ni_startdir = ndp->ni_dvp;
468			VREF(ndp->ni_startdir);
469		}
470		return (0);
471	}
472#ifdef NAMEI_DIAGNOSTIC
473	printf("found\n");
474#endif
475
476	ASSERT_VOP_LOCKED(ndp->ni_vp, "lookup");
477
478	/*
479	 * Take into account any additional components consumed by
480	 * the underlying filesystem.
481	 */
482	if (cnp->cn_consume > 0) {
483		cnp->cn_nameptr += cnp->cn_consume;
484		ndp->ni_next += cnp->cn_consume;
485		ndp->ni_pathlen -= cnp->cn_consume;
486		cnp->cn_consume = 0;
487	}
488
489	dp = ndp->ni_vp;
490
491	/*
492	 * Check to see if the vnode has been mounted on;
493	 * if so find the root of the mounted file system.
494	 */
495	while (dp->v_type == VDIR && (mp = dp->v_mountedhere) &&
496	       (cnp->cn_flags & NOCROSSMOUNT) == 0) {
497		if (vfs_busy(mp, 0, 0, p))
498			continue;
499		VOP_UNLOCK(dp, 0, p);
500		error = VFS_ROOT(mp, &tdp);
501		vfs_unbusy(mp, p);
502		if (error) {
503			dpunlocked = 1;
504			goto bad2;
505		}
506		vrele(dp);
507		ndp->ni_vp = dp = tdp;
508	}
509
510	/*
511	 * Check for symbolic link
512	 */
513	if ((dp->v_type == VLNK) &&
514	    ((cnp->cn_flags & FOLLOW) || trailing_slash ||
515	     *ndp->ni_next == '/')) {
516		cnp->cn_flags |= ISSYMLINK;
517		if (dp->v_mount == NULL) {
518			/* We can't know whether the directory was mounted with
519			 * NOSYMFOLLOW, so we can't follow safely. */
520			error = EBADF;
521			goto bad2;
522		}
523		if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) {
524			error = EACCES;
525			goto bad2;
526		}
527		return (0);
528	}
529
530	/*
531	 * Check for bogus trailing slashes.
532	 */
533	if (trailing_slash && dp->v_type != VDIR) {
534		error = ENOTDIR;
535		goto bad2;
536	}
537
538nextname:
539	/*
540	 * Not a symbolic link.  If more pathname,
541	 * continue at next component, else return.
542	 */
543	if (*ndp->ni_next == '/') {
544		cnp->cn_nameptr = ndp->ni_next;
545		while (*cnp->cn_nameptr == '/') {
546			cnp->cn_nameptr++;
547			ndp->ni_pathlen--;
548		}
549		if (ndp->ni_dvp != ndp->ni_vp)
550			ASSERT_VOP_UNLOCKED(ndp->ni_dvp, "lookup");
551		vrele(ndp->ni_dvp);
552		goto dirloop;
553	}
554	/*
555	 * Disallow directory write attempts on read-only file systems.
556	 */
557	if (rdonly &&
558	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
559		error = EROFS;
560		goto bad2;
561	}
562	if (cnp->cn_flags & SAVESTART) {
563		ndp->ni_startdir = ndp->ni_dvp;
564		VREF(ndp->ni_startdir);
565	}
566	if (!wantparent)
567		vrele(ndp->ni_dvp);
568
569	if ((cnp->cn_flags & LOCKLEAF) == 0)
570		VOP_UNLOCK(dp, 0, p);
571	return (0);
572
573bad2:
574	if ((cnp->cn_flags & (LOCKPARENT | PDIRUNLOCK)) == LOCKPARENT &&
575	    *ndp->ni_next == '\0')
576		VOP_UNLOCK(ndp->ni_dvp, 0, p);
577	vrele(ndp->ni_dvp);
578bad:
579	if (dpunlocked)
580		vrele(dp);
581	else
582		vput(dp);
583	ndp->ni_vp = NULL;
584	return (error);
585}
586
587/*
588 * relookup - lookup a path name component
589 *    Used by lookup to re-aquire things.
590 */
591int
592relookup(dvp, vpp, cnp)
593	struct vnode *dvp, **vpp;
594	struct componentname *cnp;
595{
596	struct proc *p = cnp->cn_proc;
597	struct vnode *dp = 0;		/* the directory we are searching */
598	int docache;			/* == 0 do not cache last component */
599	int wantparent;			/* 1 => wantparent or lockparent flag */
600	int rdonly;			/* lookup read-only flag bit */
601	int error = 0;
602#ifdef NAMEI_DIAGNOSTIC
603	int newhash;			/* DEBUG: check name hash */
604	char *cp;			/* DEBUG: check name ptr/len */
605#endif
606
607	/*
608	 * Setup: break out flag bits into variables.
609	 */
610	wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
611	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
612	if (cnp->cn_nameiop == DELETE ||
613	    (wantparent && cnp->cn_nameiop != CREATE))
614		docache = 0;
615	rdonly = cnp->cn_flags & RDONLY;
616	cnp->cn_flags &= ~ISSYMLINK;
617	dp = dvp;
618	vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
619
620/* dirloop: */
621	/*
622	 * Search a new directory.
623	 *
624	 * The last component of the filename is left accessible via
625	 * cnp->cn_nameptr for callers that need the name. Callers needing
626	 * the name set the SAVENAME flag. When done, they assume
627	 * responsibility for freeing the pathname buffer.
628	 */
629#ifdef NAMEI_DIAGNOSTIC
630	if (cnp->cn_namelen != cp - cnp->cn_nameptr)
631		panic ("relookup: bad len");
632	if (*cp != 0)
633		panic("relookup: not last component");
634	printf("{%s}: ", cnp->cn_nameptr);
635#endif
636
637	/*
638	 * Check for degenerate name (e.g. / or "")
639	 * which is a way of talking about a directory,
640	 * e.g. like "/." or ".".
641	 */
642	if (cnp->cn_nameptr[0] == '\0') {
643		if (cnp->cn_nameiop != LOOKUP || wantparent) {
644			error = EISDIR;
645			goto bad;
646		}
647		if (dp->v_type != VDIR) {
648			error = ENOTDIR;
649			goto bad;
650		}
651		if (!(cnp->cn_flags & LOCKLEAF))
652			VOP_UNLOCK(dp, 0, p);
653		*vpp = dp;
654		/* XXX This should probably move to the top of function. */
655		if (cnp->cn_flags & SAVESTART)
656			panic("lookup: SAVESTART");
657		return (0);
658	}
659
660	if (cnp->cn_flags & ISDOTDOT)
661		panic ("relookup: lookup on dot-dot");
662
663	/*
664	 * We now have a segment name to search for, and a directory to search.
665	 */
666	if ((error = VOP_LOOKUP(dp, vpp, cnp)) != 0) {
667		KASSERT(*vpp == NULL, ("leaf should be empty"));
668		if (error != EJUSTRETURN)
669			goto bad;
670		/*
671		 * If creating and at end of pathname, then can consider
672		 * allowing file to be created.
673		 */
674		if (rdonly) {
675			error = EROFS;
676			goto bad;
677		}
678		/* ASSERT(dvp == ndp->ni_startdir) */
679		if (cnp->cn_flags & SAVESTART)
680			VREF(dvp);
681		/*
682		 * We return with ni_vp NULL to indicate that the entry
683		 * doesn't currently exist, leaving a pointer to the
684		 * (possibly locked) directory inode in ndp->ni_dvp.
685		 */
686		return (0);
687	}
688	dp = *vpp;
689
690	/*
691	 * Check for symbolic link
692	 */
693	KASSERT(dp->v_type != VLNK || !(cnp->cn_flags & FOLLOW),
694	    ("relookup: symlink found.\n"));
695
696	/*
697	 * Disallow directory write attempts on read-only file systems.
698	 */
699	if (rdonly &&
700	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
701		error = EROFS;
702		goto bad2;
703	}
704	/* ASSERT(dvp == ndp->ni_startdir) */
705	if (cnp->cn_flags & SAVESTART)
706		VREF(dvp);
707
708	if (!wantparent)
709		vrele(dvp);
710
711	if (vn_canvmio(dp) == TRUE &&
712		((cnp->cn_flags & (NOOBJ|LOCKLEAF)) == LOCKLEAF))
713		vfs_object_create(dp, cnp->cn_proc, cnp->cn_cred);
714
715	if ((cnp->cn_flags & LOCKLEAF) == 0)
716		VOP_UNLOCK(dp, 0, p);
717	return (0);
718
719bad2:
720	if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
721		VOP_UNLOCK(dvp, 0, p);
722	vrele(dvp);
723bad:
724	vput(dp);
725	*vpp = NULL;
726	return (error);
727}
728