]>
git.saurik.com Git - apple/xnu.git/blob - bsd/vfs/vfs_lookup.c
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
27 * Copyright (c) 1982, 1986, 1989, 1993
28 * The Regents of the University of California. All rights reserved.
29 * (c) UNIX System Laboratories, Inc.
30 * All or some portions of this file are derived from material licensed
31 * to the University of California by American Telephone and Telegraph
32 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
33 * the permission of UNIX System Laboratories, Inc.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by the University of
46 * California, Berkeley and its contributors.
47 * 4. Neither the name of the University nor the names of its contributors
48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission.
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95
66 #include <sys/param.h>
67 #include <sys/systm.h>
68 #include <sys/syslimits.h>
70 #include <sys/namei.h>
72 #include <sys/vnode.h>
73 #include <sys/mount.h>
74 #include <sys/errno.h>
75 #include <sys/malloc.h>
76 #include <sys/filedesc.h>
78 #include <sys/kdebug.h>
79 #include <sys/unistd.h> /* For _PC_NAME_MAX */
80 #include <sys/kern_audit.h>
83 #include <sys/ktrace.h>
86 static void kdebug_lookup(struct vnode
*dp
, struct componentname
*cnp
);
89 * Convert a pathname into a pointer to a locked inode.
91 * The FOLLOW flag is set when symbolic links are to be followed
92 * when they occur at the end of the name translation process.
93 * Symbolic links are always followed for all other pathname
94 * components other than the last.
96 * The segflg defines whether the name is to be copied from user
97 * space or kernel space.
99 * Overall outline of namei:
102 * get starting directory
103 * while (!done && !error) {
104 * call lookup to search path.
105 * if symbolic link, massage name in buffer and continue
110 register struct nameidata
*ndp
;
112 register struct filedesc
*fdp
; /* pointer to file descriptor state */
113 register char *cp
; /* pointer into pathname argument */
114 register struct vnode
*dp
; /* the directory we are searching */
115 struct iovec aiov
; /* uio for reading symbolic links */
118 struct componentname
*cnp
= &ndp
->ni_cnd
;
119 struct proc
*p
= cnp
->cn_proc
;
122 ndp
->ni_cnd
.cn_cred
= ndp
->ni_cnd
.cn_proc
->p_ucred
;
124 if (!cnp
->cn_cred
|| !cnp
->cn_proc
)
125 panic ("namei: bad cred/proc");
126 if (cnp
->cn_nameiop
& (~OPMASK
))
127 panic ("namei: nameiop contaminated with flags");
128 if (cnp
->cn_flags
& OPMASK
)
129 panic ("namei: flags contaminated with nameiops");
134 * Get a buffer for the name to be translated, and copy the
135 * name into the buffer.
137 if ((cnp
->cn_flags
& HASBUF
) == 0) {
138 MALLOC_ZONE(cnp
->cn_pnbuf
, caddr_t
,
139 MAXPATHLEN
, M_NAMEI
, M_WAITOK
);
140 cnp
->cn_pnlen
= MAXPATHLEN
;
141 cnp
->cn_flags
|= HASBUF
;
143 if (ndp
->ni_segflg
== UIO_SYSSPACE
)
144 error
= copystr(ndp
->ni_dirp
, cnp
->cn_pnbuf
,
145 MAXPATHLEN
, (size_t *)&ndp
->ni_pathlen
);
147 error
= copyinstr(ndp
->ni_dirp
, cnp
->cn_pnbuf
,
148 MAXPATHLEN
, (size_t *)&ndp
->ni_pathlen
);
150 /* If we are auditing the kernel pathname, save the user pathname */
151 if (cnp
->cn_flags
& AUDITVNPATH1
)
152 AUDIT_ARG(upath
, p
, cnp
->cn_pnbuf
, ARG_UPATH1
);
153 if (cnp
->cn_flags
& AUDITVNPATH2
)
154 AUDIT_ARG(upath
, p
, cnp
->cn_pnbuf
, ARG_UPATH2
);
157 * Do not allow empty pathnames
159 if (!error
&& *cnp
->cn_pnbuf
== '\0')
162 if (!error
&& ((dp
= fdp
->fd_cdir
) == NULL
))
163 error
= EPERM
; /* 3382843 */
166 tmppn
= cnp
->cn_pnbuf
;
167 cnp
->cn_pnbuf
= NULL
;
168 cnp
->cn_flags
&= ~HASBUF
;
169 FREE_ZONE(tmppn
, cnp
->cn_pnlen
, M_NAMEI
);
175 if (KTRPOINT(p
, KTR_NAMEI
))
176 ktrnamei(p
->p_tracep
, cnp
->cn_pnbuf
);
180 * Get starting point for the translation.
182 if ((ndp
->ni_rootdir
= fdp
->fd_rdir
) == NULL
)
183 ndp
->ni_rootdir
= rootvnode
;
184 if (ndp
->ni_cnd
.cn_flags
& USEDVP
) {
194 * Check if root directory should replace current directory.
195 * Done at start of translation and after symbolic link.
197 cnp
->cn_nameptr
= cnp
->cn_pnbuf
;
198 if (*(cnp
->cn_nameptr
) == '/') {
200 while (*(cnp
->cn_nameptr
) == '/') {
204 dp
= ndp
->ni_rootdir
;
207 ndp
->ni_startdir
= dp
;
208 if (error
= lookup(ndp
)) {
209 long len
= cnp
->cn_pnlen
;
210 tmppn
= cnp
->cn_pnbuf
;
211 cnp
->cn_pnbuf
= NULL
;
212 cnp
->cn_flags
&= ~HASBUF
;
213 FREE_ZONE(tmppn
, len
, M_NAMEI
);
217 * Check for symbolic link
219 if ((cnp
->cn_flags
& ISSYMLINK
) == 0) {
220 if ((cnp
->cn_flags
& (SAVENAME
| SAVESTART
)) == 0) {
221 tmppn
= cnp
->cn_pnbuf
;
222 cnp
->cn_pnbuf
= NULL
;
223 cnp
->cn_flags
&= ~HASBUF
;
224 FREE_ZONE(tmppn
, cnp
->cn_pnlen
, M_NAMEI
);
226 cnp
->cn_flags
|= HASBUF
;
230 if ((cnp
->cn_flags
& LOCKPARENT
) && ndp
->ni_pathlen
== 1)
231 VOP_UNLOCK(ndp
->ni_dvp
, 0, p
);
232 if (ndp
->ni_loopcnt
++ >= MAXSYMLINKS
) {
236 if (ndp
->ni_pathlen
> 1) {
237 MALLOC_ZONE(cp
, char *, MAXPATHLEN
, M_NAMEI
, M_WAITOK
);
242 aiov
.iov_len
= MAXPATHLEN
;
243 auio
.uio_iov
= &aiov
;
246 auio
.uio_rw
= UIO_READ
;
247 auio
.uio_segflg
= UIO_SYSSPACE
;
248 auio
.uio_procp
= (struct proc
*)0;
249 auio
.uio_resid
= MAXPATHLEN
;
250 if (error
= VOP_READLINK(ndp
->ni_vp
, &auio
, cnp
->cn_cred
)) {
251 if (ndp
->ni_pathlen
> 1)
252 FREE_ZONE(cp
, MAXPATHLEN
, M_NAMEI
);
255 linklen
= MAXPATHLEN
- auio
.uio_resid
;
256 if (linklen
+ ndp
->ni_pathlen
>= MAXPATHLEN
) {
257 if (ndp
->ni_pathlen
> 1)
258 FREE_ZONE(cp
, MAXPATHLEN
, M_NAMEI
);
259 error
= ENAMETOOLONG
;
262 if (ndp
->ni_pathlen
> 1) {
263 long len
= cnp
->cn_pnlen
;
264 tmppn
= cnp
->cn_pnbuf
;
265 bcopy(ndp
->ni_next
, cp
+ linklen
, ndp
->ni_pathlen
);
267 cnp
->cn_pnlen
= MAXPATHLEN
;
268 FREE_ZONE(tmppn
, len
, M_NAMEI
);
270 cnp
->cn_pnbuf
[linklen
] = '\0';
271 ndp
->ni_pathlen
+= linklen
;
276 tmppn
= cnp
->cn_pnbuf
;
277 cnp
->cn_pnbuf
= NULL
;
278 cnp
->cn_flags
&= ~HASBUF
;
279 FREE_ZONE(tmppn
, cnp
->cn_pnlen
, M_NAMEI
);
289 * This is a very central and rather complicated routine.
291 * The pathname is pointed to by ni_ptr and is of length ni_pathlen.
292 * The starting directory is taken from ni_startdir. The pathname is
293 * descended until done, or a symbolic link is encountered. The variable
294 * ni_more is clear if the path is completed; it is set to one if a
295 * symbolic link needing interpretation is encountered.
297 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
298 * whether the name is to be looked up, created, renamed, or deleted.
299 * When CREATE, RENAME, or DELETE is specified, information usable in
300 * creating, renaming, or deleting a directory entry may be calculated.
301 * If flag has LOCKPARENT or'ed into it, the parent directory is returned
302 * locked. If flag has WANTPARENT or'ed into it, the parent directory is
303 * returned unlocked. Otherwise the parent directory is not returned. If
304 * the target of the pathname exists and LOCKLEAF is or'ed into the flag
305 * the target is returned locked, otherwise it is returned unlocked.
306 * When creating or renaming and LOCKPARENT is specified, the target may not
307 * be ".". When deleting and LOCKPARENT is specified, the target may be ".".
309 * Overall outline of lookup:
312 * identify next component of name at ndp->ni_ptr
313 * handle degenerate case where name is null string
314 * if .. and crossing mount points and on mounted filesys, find parent
315 * call VOP_LOOKUP routine for next component name
316 * directory vnode returned in ni_dvp, unlocked unless LOCKPARENT set
317 * component vnode returned in ni_vp (if it exists), locked.
318 * if result vnode is mounted on and crossing mount points,
319 * find mounted on vnode
320 * if more components of name, do next level at dirloop
321 * return the answer in ni_vp, locked if LOCKLEAF set
322 * if LOCKPARENT set, return locked parent in ni_dvp
323 * if WANTPARENT set, return unlocked parent in ni_dvp
327 register struct nameidata
*ndp
;
329 register char *cp
; /* pointer into pathname argument */
330 register struct vnode
*dp
= 0; /* the directory we are searching */
331 struct vnode
*tdp
; /* saved dp */
332 struct mount
*mp
; /* mount table entry */
333 int namemax
= 0; /* maximun number of bytes for filename returned by pathconf() */
334 int docache
; /* == 0 do not cache last component */
335 int wantparent
; /* 1 => wantparent or lockparent flag */
336 int dp_unlocked
= 0; /* 1 => dp already VOP_UNLOCK()-ed */
337 int rdonly
; /* lookup read-only flag bit */
338 int trailing_slash
= 0;
340 struct componentname
*cnp
= &ndp
->ni_cnd
;
341 struct proc
*p
= cnp
->cn_proc
;
345 * Setup: break out flag bits into variables.
347 wantparent
= cnp
->cn_flags
& (LOCKPARENT
| WANTPARENT
);
348 docache
= (cnp
->cn_flags
& NOCACHE
) ^ NOCACHE
;
349 if (cnp
->cn_nameiop
== DELETE
||
350 (wantparent
&& cnp
->cn_nameiop
!= CREATE
&&
351 cnp
->cn_nameiop
!= LOOKUP
))
353 rdonly
= cnp
->cn_flags
& RDONLY
;
355 cnp
->cn_flags
&= ~ISSYMLINK
;
356 dp
= ndp
->ni_startdir
;
357 ndp
->ni_startdir
= NULLVP
;
358 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
363 * Search a new directory.
365 * The cn_hash value is for use by vfs_cache.
366 * The last component of the filename is left accessible via
367 * cnp->cn_nameptr for callers that need the name. Callers needing
368 * the name set the SAVENAME flag. When done, they assume
369 * responsibility for freeing the pathname buffer.
372 register unsigned int hash
;
373 register unsigned int ch
;
377 cp
= cnp
->cn_nameptr
;
384 for (i
= 1; (ch
!= '/') && (ch
!= '\0'); i
++) {
390 cnp
->cn_namelen
= cp
- cnp
->cn_nameptr
;
391 if (cnp
->cn_namelen
> NCHNAMLEN
) {
392 if (VOP_PATHCONF(dp
, _PC_NAME_MAX
, &namemax
))
394 if (cnp
->cn_namelen
> namemax
) {
395 error
= ENAMETOOLONG
;
399 #ifdef NAMEI_DIAGNOSTIC
402 printf("{%s}: ", cnp
->cn_nameptr
);
405 ndp
->ni_pathlen
-= cnp
->cn_namelen
;
409 * Replace multiple slashes by a single slash and trailing slashes
410 * by a null. This must be done before VOP_LOOKUP() because some
411 * fs's don't know about trailing slashes. Remember if there were
412 * trailing slashes to handle symlinks, existing non-directories
413 * and non-existing files that won't be directories specially later.
416 while (*cp
== '/' && (cp
[1] == '/' || cp
[1] == '\0')) {
421 *ndp
->ni_next
= '\0';
426 cnp
->cn_flags
|= MAKEENTRY
;
427 if (*cp
== '\0' && docache
== 0)
428 cnp
->cn_flags
&= ~MAKEENTRY
;
430 if (*ndp
->ni_next
== 0)
431 cnp
->cn_flags
|= ISLASTCN
;
433 cnp
->cn_flags
&= ~ISLASTCN
;
436 * Handle "..": two special cases.
437 * 1. If at root directory (e.g. after chroot)
438 * or at absolute root directory
439 * then ignore it so can't get out.
440 * 2. If this vnode is the root of a mounted
441 * filesystem, then replace it with the
442 * vnode which was mounted on so we take the
443 * .. in the other file system.
445 if (cnp
->cn_namelen
== 2 &&
446 cnp
->cn_nameptr
[1] == '.' && cnp
->cn_nameptr
[0] == '.') {
447 cnp
->cn_flags
|= ISDOTDOT
;
450 if (dp
== ndp
->ni_rootdir
|| dp
== rootvnode
) {
456 if ((dp
->v_flag
& VROOT
) == 0 ||
457 (cnp
->cn_flags
& NOCROSSMOUNT
))
459 if (dp
->v_mount
== NULL
) { /* forced umount */
465 dp
= dp
->v_mount
->mnt_vnodecovered
;
468 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
471 cnp
->cn_flags
&= ~ISDOTDOT
;
475 * We now have a segment name to search for, and a directory to search.
480 if (error
= VOP_LOOKUP(dp
, &ndp
->ni_vp
, cnp
)) {
482 if (ndp
->ni_vp
!= NULL
)
483 panic("leaf should be empty");
485 #ifdef NAMEI_DIAGNOSTIC
486 printf("not found\n");
488 if ((error
== ENOENT
) &&
489 (dp
->v_flag
& VROOT
) && (dp
->v_mount
!= NULL
) &&
490 (dp
->v_mount
->mnt_flag
& MNT_UNION
)) {
492 dp
= dp
->v_mount
->mnt_vnodecovered
;
495 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
499 if (error
!= EJUSTRETURN
)
502 * If creating and at end of pathname, then can consider
503 * allowing file to be created.
509 if (*cp
== '\0' && trailing_slash
&&
510 !(cnp
->cn_flags
& WILLBEDIR
)) {
515 * We return with ni_vp NULL to indicate that the entry
516 * doesn't currently exist, leaving a pointer to the
517 * (possibly locked) directory inode in ndp->ni_dvp.
519 if (cnp
->cn_flags
& SAVESTART
) {
520 ndp
->ni_startdir
= ndp
->ni_dvp
;
521 VREF(ndp
->ni_startdir
);
524 kdebug_lookup(ndp
->ni_dvp
, cnp
);
527 #ifdef NAMEI_DIAGNOSTIC
532 * Take into account any additional components consumed by
533 * the underlying filesystem.
535 if (cnp
->cn_consume
> 0) {
536 cnp
->cn_nameptr
+= cnp
->cn_consume
;
537 ndp
->ni_next
+= cnp
->cn_consume
;
538 ndp
->ni_pathlen
-= cnp
->cn_consume
;
543 isdot_or_dotdot
= (cnp
->cn_namelen
== 1 && cnp
->cn_nameptr
[0] == '.') || (cnp
->cn_flags
& ISDOTDOT
);
545 if (VNAME(ndp
->ni_vp
) == NULL
&& isdot_or_dotdot
== 0) {
546 VNAME(ndp
->ni_vp
) = add_name(cnp
->cn_nameptr
, cnp
->cn_namelen
, cnp
->cn_hash
, 0);
548 if (VPARENT(ndp
->ni_vp
) == NULL
&& isdot_or_dotdot
== 0) {
549 if (vget(ndp
->ni_dvp
, 0, p
) == 0) {
550 VPARENT(ndp
->ni_vp
) = ndp
->ni_dvp
;
557 * Check to see if the vnode has been mounted on;
558 * if so find the root of the mounted file system.
560 while (dp
->v_type
== VDIR
&& (mp
= dp
->v_mountedhere
) &&
561 (cnp
->cn_flags
& NOCROSSMOUNT
) == 0) {
562 if (vfs_busy(mp
, LK_NOWAIT
, 0, p
)) {
566 VOP_UNLOCK(dp
, 0, p
);
567 error
= VFS_ROOT(mp
, &tdp
);
570 dp_unlocked
= 1; /* Signal error path 'dp' has already been unlocked */
574 ndp
->ni_vp
= dp
= tdp
;
578 * Check for symbolic link
580 if ((dp
->v_type
== VLNK
) &&
581 ((cnp
->cn_flags
& FOLLOW
) || trailing_slash
||
582 *ndp
->ni_next
== '/')) {
583 cnp
->cn_flags
|= ISSYMLINK
;
588 * Check for bogus trailing slashes.
590 if (trailing_slash
) {
591 if (dp
->v_type
!= VDIR
) {
600 * Not a symbolic link. If more pathname,
601 * continue at next component, else return.
603 if (*ndp
->ni_next
== '/') {
604 cnp
->cn_nameptr
= ndp
->ni_next
+ 1;
606 while (*cnp
->cn_nameptr
== '/') {
615 * Disallow directory write attempts on read-only file systems.
618 (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
)) {
622 if (cnp
->cn_flags
& SAVESTART
) {
623 ndp
->ni_startdir
= ndp
->ni_dvp
;
624 VREF(ndp
->ni_startdir
);
628 if (cnp
->cn_flags
& AUDITVNPATH1
)
629 AUDIT_ARG(vnpath
, dp
, ARG_VNODE1
);
630 else if (cnp
->cn_flags
& AUDITVNPATH2
)
631 AUDIT_ARG(vnpath
, dp
, ARG_VNODE2
);
632 if ((cnp
->cn_flags
& LOCKLEAF
) == 0)
633 VOP_UNLOCK(dp
, 0, p
);
635 kdebug_lookup(dp
, cnp
);
640 * A degenerate name (e.g. / or "") which is a way of
641 * talking about a directory, e.g. like "/." or ".".
643 if (dp
->v_type
!= VDIR
) {
647 if (cnp
->cn_nameiop
!= LOOKUP
) {
655 cnp
->cn_flags
&= ~ISDOTDOT
;
656 cnp
->cn_flags
|= ISLASTCN
;
659 if (cnp
->cn_flags
& AUDITVNPATH1
)
660 AUDIT_ARG(vnpath
, dp
, ARG_VNODE1
);
661 else if (cnp
->cn_flags
& AUDITVNPATH2
)
662 AUDIT_ARG(vnpath
, dp
, ARG_VNODE2
);
663 if (!(cnp
->cn_flags
& (LOCKPARENT
| LOCKLEAF
)))
664 VOP_UNLOCK(dp
, 0, p
);
665 if (cnp
->cn_flags
& SAVESTART
)
666 panic("lookup: SAVESTART");
670 if ((cnp
->cn_flags
& LOCKPARENT
) && *ndp
->ni_next
== '\0')
671 VOP_UNLOCK(ndp
->ni_dvp
, 0, p
);
681 kdebug_lookup(dp
, cnp
);
686 * relookup - lookup a path name component
687 * Used by lookup to re-aquire things.
690 relookup(dvp
, vpp
, cnp
)
691 struct vnode
*dvp
, **vpp
;
692 struct componentname
*cnp
;
694 struct proc
*p
= cnp
->cn_proc
;
695 struct vnode
*dp
= 0; /* the directory we are searching */
696 int docache
; /* == 0 do not cache last component */
697 int wantparent
; /* 1 => wantparent or lockparent flag */
698 int rdonly
; /* lookup read-only flag bit */
700 #ifdef NAMEI_DIAGNOSTIC
701 int i
, newhash
; /* DEBUG: check name hash */
702 char *cp
; /* DEBUG: check name ptr/len */
706 * Setup: break out flag bits into variables.
708 wantparent
= cnp
->cn_flags
& (LOCKPARENT
|WANTPARENT
);
709 docache
= (cnp
->cn_flags
& NOCACHE
) ^ NOCACHE
;
710 if (cnp
->cn_nameiop
== DELETE
||
711 (wantparent
&& cnp
->cn_nameiop
!= CREATE
))
713 rdonly
= cnp
->cn_flags
& RDONLY
;
714 cnp
->cn_flags
&= ~ISSYMLINK
;
716 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
720 * Search a new directory.
722 * The cn_hash value is for use by vfs_cache.
723 * The last component of the filename is left accessible via
724 * cnp->cn_nameptr for callers that need the name. Callers needing
725 * the name set the SAVENAME flag. When done, they assume
726 * responsibility for freeing the pathname buffer.
728 #ifdef NAMEI_DIAGNOSTIC
729 for (i
=1, newhash
= 0, cp
= cnp
->cn_nameptr
; *cp
!= 0 && *cp
!= '/'; cp
++)
730 newhash
+= (unsigned char)*cp
* i
;
731 if (newhash
!= cnp
->cn_hash
)
732 panic("relookup: bad hash");
733 if (cnp
->cn_namelen
!= cp
- cnp
->cn_nameptr
)
734 panic ("relookup: bad len");
736 panic("relookup: not last component");
737 printf("{%s}: ", cnp
->cn_nameptr
);
741 * Check for degenerate name (e.g. / or "")
742 * which is a way of talking about a directory,
743 * e.g. like "/." or ".".
745 if (cnp
->cn_nameptr
[0] == '\0') {
746 if (cnp
->cn_nameiop
!= LOOKUP
|| wantparent
) {
750 if (dp
->v_type
!= VDIR
) {
754 if (!(cnp
->cn_flags
& LOCKLEAF
))
755 VOP_UNLOCK(dp
, 0, p
);
757 if (cnp
->cn_flags
& SAVESTART
)
758 panic("lookup: SAVESTART");
762 if (cnp
->cn_flags
& ISDOTDOT
)
763 panic ("relookup: lookup on dot-dot");
766 * We now have a segment name to search for, and a directory to search.
768 if (error
= VOP_LOOKUP(dp
, vpp
, cnp
)) {
771 panic("leaf should be empty");
773 if (error
!= EJUSTRETURN
)
776 * If creating and at end of pathname, then can consider
777 * allowing file to be created.
783 /* ASSERT(dvp == ndp->ni_startdir) */
784 if (cnp
->cn_flags
& SAVESTART
)
787 * We return with ni_vp NULL to indicate that the entry
788 * doesn't currently exist, leaving a pointer to the
789 * (possibly locked) directory inode in ndp->ni_dvp.
797 * Check for symbolic link
799 if (dp
->v_type
== VLNK
&& (cnp
->cn_flags
& FOLLOW
))
800 panic ("relookup: symlink found.\n");
804 * Disallow directory write attempts on read-only file systems.
807 (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
)) {
811 /* ASSERT(dvp == ndp->ni_startdir) */
812 if (cnp
->cn_flags
& SAVESTART
)
817 if ((cnp
->cn_flags
& LOCKLEAF
) == 0)
818 VOP_UNLOCK(dp
, 0, p
);
822 if ((cnp
->cn_flags
& LOCKPARENT
) && (cnp
->cn_flags
& ISLASTCN
))
823 VOP_UNLOCK(dvp
, 0, p
);
835 kdebug_lookup(dp
, cnp
)
837 struct componentname
*cnp
;
840 register int dbg_namelen
;
841 register int save_dbg_namelen
;
842 register char *dbg_nameptr
;
843 long dbg_parms
[NUMPARMS
];
845 static char *dbg_filler
= ">>>>";
847 /* Collect the pathname for tracing */
848 dbg_namelen
= (cnp
->cn_nameptr
- cnp
->cn_pnbuf
) + cnp
->cn_namelen
;
849 dbg_nameptr
= cnp
->cn_nameptr
+ cnp
->cn_namelen
;
851 if (dbg_namelen
> sizeof(dbg_parms
))
852 dbg_namelen
= sizeof(dbg_parms
);
853 dbg_nameptr
-= dbg_namelen
;
854 save_dbg_namelen
= dbg_namelen
;
858 while (dbg_namelen
> 0) {
859 if (dbg_namelen
>= 4) {
860 dbg_parms
[i
++] = *(long *)dbg_nameptr
;
861 dbg_nameptr
+= sizeof(long);
862 dbg_namelen
-= sizeof(long);
864 for (n
= 0; n
< dbg_namelen
; n
++)
865 dbg_buf
[n
] = *dbg_nameptr
++;
872 dbg_parms
[i
++] = *(long *)&dbg_buf
[0];
877 while (i
< NUMPARMS
) {
879 dbg_parms
[i
++] = *(long *)dbg_filler
;
885 In the event that we collect multiple, consecutive pathname
886 entries, we must mark the start of the path's string.
888 KERNEL_DEBUG_CONSTANT((FSDBG_CODE(DBG_FSRW
,36)) | DBG_FUNC_START
,
889 (unsigned int)dp
, dbg_parms
[0], dbg_parms
[1], dbg_parms
[2], 0);
891 for (dbg_namelen
= save_dbg_namelen
-12, i
=3;
893 dbg_namelen
-=(4 * sizeof(long)), i
+= 4)
895 KERNEL_DEBUG_CONSTANT((FSDBG_CODE(DBG_FSRW
,36)) | DBG_FUNC_NONE
,
896 dbg_parms
[i
], dbg_parms
[i
+1], dbg_parms
[i
+2], dbg_parms
[i
+3], 0);