]>
git.saurik.com Git - apple/xnu.git/blob - bsd/vfs/vfs_lookup.c
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1982, 1986, 1989, 1993
25 * The Regents of the University of California. All rights reserved.
26 * (c) UNIX System Laboratories, Inc.
27 * All or some portions of this file are derived from material licensed
28 * to the University of California by American Telephone and Telegraph
29 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
30 * the permission of UNIX System Laboratories, Inc.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/syslimits.h>
67 #include <sys/namei.h>
69 #include <sys/vnode.h>
70 #include <sys/mount.h>
71 #include <sys/errno.h>
72 #include <sys/malloc.h>
73 #include <sys/filedesc.h>
75 #include <sys/kdebug.h>
76 #include <sys/unistd.h> /* For _PC_NAME_MAX */
78 #include <bsm/audit_kernel.h>
81 #include <sys/ktrace.h>
84 static void kdebug_lookup(struct vnode
*dp
, struct componentname
*cnp
);
87 * Convert a pathname into a pointer to a locked inode.
89 * The FOLLOW flag is set when symbolic links are to be followed
90 * when they occur at the end of the name translation process.
91 * Symbolic links are always followed for all other pathname
92 * components other than the last.
94 * The segflg defines whether the name is to be copied from user
95 * space or kernel space.
97 * Overall outline of namei:
100 * get starting directory
101 * while (!done && !error) {
102 * call lookup to search path.
103 * if symbolic link, massage name in buffer and continue
108 register struct nameidata
*ndp
;
110 register struct filedesc
*fdp
; /* pointer to file descriptor state */
111 register char *cp
; /* pointer into pathname argument */
112 register struct vnode
*dp
; /* the directory we are searching */
113 struct iovec aiov
; /* uio for reading symbolic links */
116 struct componentname
*cnp
= &ndp
->ni_cnd
;
117 struct proc
*p
= cnp
->cn_proc
;
120 ndp
->ni_cnd
.cn_cred
= ndp
->ni_cnd
.cn_proc
->p_ucred
;
122 if (!cnp
->cn_cred
|| !cnp
->cn_proc
)
123 panic ("namei: bad cred/proc");
124 if (cnp
->cn_nameiop
& (~OPMASK
))
125 panic ("namei: nameiop contaminated with flags");
126 if (cnp
->cn_flags
& OPMASK
)
127 panic ("namei: flags contaminated with nameiops");
132 * Get a buffer for the name to be translated, and copy the
133 * name into the buffer.
135 if ((cnp
->cn_flags
& HASBUF
) == 0) {
136 MALLOC_ZONE(cnp
->cn_pnbuf
, caddr_t
,
137 MAXPATHLEN
, M_NAMEI
, M_WAITOK
);
138 cnp
->cn_pnlen
= MAXPATHLEN
;
139 cnp
->cn_flags
|= HASBUF
;
141 if (ndp
->ni_segflg
== UIO_SYSSPACE
)
142 error
= copystr(ndp
->ni_dirp
, cnp
->cn_pnbuf
,
143 MAXPATHLEN
, (size_t *)&ndp
->ni_pathlen
);
145 error
= copyinstr(ndp
->ni_dirp
, cnp
->cn_pnbuf
,
146 MAXPATHLEN
, (size_t *)&ndp
->ni_pathlen
);
148 /* If we are auditing the kernel pathname, save the user pathname */
149 if (cnp
->cn_flags
& AUDITVNPATH1
)
150 AUDIT_ARG(upath
, p
, cnp
->cn_pnbuf
, ARG_UPATH1
);
151 if (cnp
->cn_flags
& AUDITVNPATH2
)
152 AUDIT_ARG(upath
, p
, cnp
->cn_pnbuf
, ARG_UPATH2
);
155 * Do not allow empty pathnames
157 if (!error
&& *cnp
->cn_pnbuf
== '\0')
160 if (!error
&& ((dp
= fdp
->fd_cdir
) == NULL
))
161 error
= EPERM
; /* 3382843 */
164 tmppn
= cnp
->cn_pnbuf
;
165 cnp
->cn_pnbuf
= NULL
;
166 cnp
->cn_flags
&= ~HASBUF
;
167 FREE_ZONE(tmppn
, cnp
->cn_pnlen
, M_NAMEI
);
173 if (KTRPOINT(p
, KTR_NAMEI
))
174 ktrnamei(p
->p_tracep
, cnp
->cn_pnbuf
);
178 * Get starting point for the translation.
180 if ((ndp
->ni_rootdir
= fdp
->fd_rdir
) == NULL
)
181 ndp
->ni_rootdir
= rootvnode
;
182 if (ndp
->ni_cnd
.cn_flags
& USEDVP
) {
192 * Check if root directory should replace current directory.
193 * Done at start of translation and after symbolic link.
195 cnp
->cn_nameptr
= cnp
->cn_pnbuf
;
196 if (*(cnp
->cn_nameptr
) == '/') {
198 while (*(cnp
->cn_nameptr
) == '/') {
202 dp
= ndp
->ni_rootdir
;
205 ndp
->ni_startdir
= dp
;
206 if (error
= lookup(ndp
)) {
207 long len
= cnp
->cn_pnlen
;
208 tmppn
= cnp
->cn_pnbuf
;
209 cnp
->cn_pnbuf
= NULL
;
210 cnp
->cn_flags
&= ~HASBUF
;
211 FREE_ZONE(tmppn
, len
, M_NAMEI
);
215 * Check for symbolic link
217 if ((cnp
->cn_flags
& ISSYMLINK
) == 0) {
218 if ((cnp
->cn_flags
& (SAVENAME
| SAVESTART
)) == 0) {
219 tmppn
= cnp
->cn_pnbuf
;
220 cnp
->cn_pnbuf
= NULL
;
221 cnp
->cn_flags
&= ~HASBUF
;
222 FREE_ZONE(tmppn
, cnp
->cn_pnlen
, M_NAMEI
);
224 cnp
->cn_flags
|= HASBUF
;
228 if ((cnp
->cn_flags
& LOCKPARENT
) && ndp
->ni_pathlen
== 1)
229 VOP_UNLOCK(ndp
->ni_dvp
, 0, p
);
230 if (ndp
->ni_loopcnt
++ >= MAXSYMLINKS
) {
234 if (ndp
->ni_pathlen
> 1) {
235 MALLOC_ZONE(cp
, char *, MAXPATHLEN
, M_NAMEI
, M_WAITOK
);
240 aiov
.iov_len
= MAXPATHLEN
;
241 auio
.uio_iov
= &aiov
;
244 auio
.uio_rw
= UIO_READ
;
245 auio
.uio_segflg
= UIO_SYSSPACE
;
246 auio
.uio_procp
= (struct proc
*)0;
247 auio
.uio_resid
= MAXPATHLEN
;
248 if (error
= VOP_READLINK(ndp
->ni_vp
, &auio
, cnp
->cn_cred
)) {
249 if (ndp
->ni_pathlen
> 1)
250 FREE_ZONE(cp
, MAXPATHLEN
, M_NAMEI
);
253 linklen
= MAXPATHLEN
- auio
.uio_resid
;
254 if (linklen
+ ndp
->ni_pathlen
>= MAXPATHLEN
) {
255 if (ndp
->ni_pathlen
> 1)
256 FREE_ZONE(cp
, MAXPATHLEN
, M_NAMEI
);
257 error
= ENAMETOOLONG
;
260 if (ndp
->ni_pathlen
> 1) {
261 long len
= cnp
->cn_pnlen
;
262 tmppn
= cnp
->cn_pnbuf
;
263 bcopy(ndp
->ni_next
, cp
+ linklen
, ndp
->ni_pathlen
);
265 cnp
->cn_pnlen
= MAXPATHLEN
;
266 FREE_ZONE(tmppn
, len
, M_NAMEI
);
268 cnp
->cn_pnbuf
[linklen
] = '\0';
269 ndp
->ni_pathlen
+= linklen
;
274 tmppn
= cnp
->cn_pnbuf
;
275 cnp
->cn_pnbuf
= NULL
;
276 cnp
->cn_flags
&= ~HASBUF
;
277 FREE_ZONE(tmppn
, cnp
->cn_pnlen
, M_NAMEI
);
287 * This is a very central and rather complicated routine.
289 * The pathname is pointed to by ni_ptr and is of length ni_pathlen.
290 * The starting directory is taken from ni_startdir. The pathname is
291 * descended until done, or a symbolic link is encountered. The variable
292 * ni_more is clear if the path is completed; it is set to one if a
293 * symbolic link needing interpretation is encountered.
295 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
296 * whether the name is to be looked up, created, renamed, or deleted.
297 * When CREATE, RENAME, or DELETE is specified, information usable in
298 * creating, renaming, or deleting a directory entry may be calculated.
299 * If flag has LOCKPARENT or'ed into it, the parent directory is returned
300 * locked. If flag has WANTPARENT or'ed into it, the parent directory is
301 * returned unlocked. Otherwise the parent directory is not returned. If
302 * the target of the pathname exists and LOCKLEAF is or'ed into the flag
303 * the target is returned locked, otherwise it is returned unlocked.
304 * When creating or renaming and LOCKPARENT is specified, the target may not
305 * be ".". When deleting and LOCKPARENT is specified, the target may be ".".
307 * Overall outline of lookup:
310 * identify next component of name at ndp->ni_ptr
311 * handle degenerate case where name is null string
312 * if .. and crossing mount points and on mounted filesys, find parent
313 * call VOP_LOOKUP routine for next component name
314 * directory vnode returned in ni_dvp, unlocked unless LOCKPARENT set
315 * component vnode returned in ni_vp (if it exists), locked.
316 * if result vnode is mounted on and crossing mount points,
317 * find mounted on vnode
318 * if more components of name, do next level at dirloop
319 * return the answer in ni_vp, locked if LOCKLEAF set
320 * if LOCKPARENT set, return locked parent in ni_dvp
321 * if WANTPARENT set, return unlocked parent in ni_dvp
325 register struct nameidata
*ndp
;
327 register char *cp
; /* pointer into pathname argument */
328 register struct vnode
*dp
= 0; /* the directory we are searching */
329 struct vnode
*tdp
; /* saved dp */
330 struct mount
*mp
; /* mount table entry */
331 int namemax
= 0; /* maximun number of bytes for filename returned by pathconf() */
332 int docache
; /* == 0 do not cache last component */
333 int wantparent
; /* 1 => wantparent or lockparent flag */
334 int dp_unlocked
= 0; /* 1 => dp already VOP_UNLOCK()-ed */
335 int rdonly
; /* lookup read-only flag bit */
336 int trailing_slash
= 0;
338 struct componentname
*cnp
= &ndp
->ni_cnd
;
339 struct proc
*p
= cnp
->cn_proc
;
343 * Setup: break out flag bits into variables.
345 wantparent
= cnp
->cn_flags
& (LOCKPARENT
| WANTPARENT
);
346 docache
= (cnp
->cn_flags
& NOCACHE
) ^ NOCACHE
;
347 if (cnp
->cn_nameiop
== DELETE
||
348 (wantparent
&& cnp
->cn_nameiop
!= CREATE
&&
349 cnp
->cn_nameiop
!= LOOKUP
))
351 rdonly
= cnp
->cn_flags
& RDONLY
;
353 cnp
->cn_flags
&= ~ISSYMLINK
;
354 dp
= ndp
->ni_startdir
;
355 ndp
->ni_startdir
= NULLVP
;
356 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
361 * Search a new directory.
363 * The cn_hash value is for use by vfs_cache.
364 * The last component of the filename is left accessible via
365 * cnp->cn_nameptr for callers that need the name. Callers needing
366 * the name set the SAVENAME flag. When done, they assume
367 * responsibility for freeing the pathname buffer.
370 register unsigned int hash
;
371 register unsigned int ch
;
375 cp
= cnp
->cn_nameptr
;
382 for (i
= 1; (ch
!= '/') && (ch
!= '\0'); i
++) {
388 cnp
->cn_namelen
= cp
- cnp
->cn_nameptr
;
389 if (cnp
->cn_namelen
> NCHNAMLEN
) {
390 if (VOP_PATHCONF(dp
, _PC_NAME_MAX
, &namemax
))
392 if (cnp
->cn_namelen
> namemax
) {
393 error
= ENAMETOOLONG
;
397 #ifdef NAMEI_DIAGNOSTIC
400 printf("{%s}: ", cnp
->cn_nameptr
);
403 ndp
->ni_pathlen
-= cnp
->cn_namelen
;
407 * Replace multiple slashes by a single slash and trailing slashes
408 * by a null. This must be done before VOP_LOOKUP() because some
409 * fs's don't know about trailing slashes. Remember if there were
410 * trailing slashes to handle symlinks, existing non-directories
411 * and non-existing files that won't be directories specially later.
414 while (*cp
== '/' && (cp
[1] == '/' || cp
[1] == '\0')) {
419 *ndp
->ni_next
= '\0';
424 cnp
->cn_flags
|= MAKEENTRY
;
425 if (*cp
== '\0' && docache
== 0)
426 cnp
->cn_flags
&= ~MAKEENTRY
;
428 if (*ndp
->ni_next
== 0)
429 cnp
->cn_flags
|= ISLASTCN
;
431 cnp
->cn_flags
&= ~ISLASTCN
;
434 * Handle "..": two special cases.
435 * 1. If at root directory (e.g. after chroot)
436 * or at absolute root directory
437 * then ignore it so can't get out.
438 * 2. If this vnode is the root of a mounted
439 * filesystem, then replace it with the
440 * vnode which was mounted on so we take the
441 * .. in the other file system.
443 if (cnp
->cn_namelen
== 2 &&
444 cnp
->cn_nameptr
[1] == '.' && cnp
->cn_nameptr
[0] == '.') {
445 cnp
->cn_flags
|= ISDOTDOT
;
448 if (dp
== ndp
->ni_rootdir
|| dp
== rootvnode
) {
454 if ((dp
->v_flag
& VROOT
) == 0 ||
455 (cnp
->cn_flags
& NOCROSSMOUNT
))
457 if (dp
->v_mount
== NULL
) { /* forced umount */
463 dp
= dp
->v_mount
->mnt_vnodecovered
;
466 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
469 cnp
->cn_flags
&= ~ISDOTDOT
;
473 * We now have a segment name to search for, and a directory to search.
478 if (error
= VOP_LOOKUP(dp
, &ndp
->ni_vp
, cnp
)) {
480 if (ndp
->ni_vp
!= NULL
)
481 panic("leaf should be empty");
483 #ifdef NAMEI_DIAGNOSTIC
484 printf("not found\n");
486 if ((error
== ENOENT
) &&
487 (dp
->v_flag
& VROOT
) && (dp
->v_mount
!= NULL
) &&
488 (dp
->v_mount
->mnt_flag
& MNT_UNION
)) {
490 dp
= dp
->v_mount
->mnt_vnodecovered
;
493 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
497 if (error
!= EJUSTRETURN
)
500 * If creating and at end of pathname, then can consider
501 * allowing file to be created.
507 if (*cp
== '\0' && trailing_slash
&&
508 !(cnp
->cn_flags
& WILLBEDIR
)) {
513 * We return with ni_vp NULL to indicate that the entry
514 * doesn't currently exist, leaving a pointer to the
515 * (possibly locked) directory inode in ndp->ni_dvp.
517 if (cnp
->cn_flags
& SAVESTART
) {
518 ndp
->ni_startdir
= ndp
->ni_dvp
;
519 VREF(ndp
->ni_startdir
);
522 kdebug_lookup(ndp
->ni_dvp
, cnp
);
525 #ifdef NAMEI_DIAGNOSTIC
530 * Take into account any additional components consumed by
531 * the underlying filesystem.
533 if (cnp
->cn_consume
> 0) {
534 cnp
->cn_nameptr
+= cnp
->cn_consume
;
535 ndp
->ni_next
+= cnp
->cn_consume
;
536 ndp
->ni_pathlen
-= cnp
->cn_consume
;
541 isdot_or_dotdot
= (cnp
->cn_namelen
== 1 && cnp
->cn_nameptr
[0] == '.') || (cnp
->cn_flags
& ISDOTDOT
);
543 if (VNAME(ndp
->ni_vp
) == NULL
&& isdot_or_dotdot
== 0) {
544 VNAME(ndp
->ni_vp
) = add_name(cnp
->cn_nameptr
, cnp
->cn_namelen
, cnp
->cn_hash
, 0);
546 if (VPARENT(ndp
->ni_vp
) == NULL
&& isdot_or_dotdot
== 0) {
547 if (vget(ndp
->ni_dvp
, 0, p
) == 0) {
548 VPARENT(ndp
->ni_vp
) = ndp
->ni_dvp
;
555 * Check to see if the vnode has been mounted on;
556 * if so find the root of the mounted file system.
558 while (dp
->v_type
== VDIR
&& (mp
= dp
->v_mountedhere
) &&
559 (cnp
->cn_flags
& NOCROSSMOUNT
) == 0) {
560 if (vfs_busy(mp
, LK_NOWAIT
, 0, p
)) {
564 VOP_UNLOCK(dp
, 0, p
);
565 error
= VFS_ROOT(mp
, &tdp
);
568 dp_unlocked
= 1; /* Signal error path 'dp' has already been unlocked */
572 ndp
->ni_vp
= dp
= tdp
;
576 * Check for symbolic link
578 if ((dp
->v_type
== VLNK
) &&
579 ((cnp
->cn_flags
& FOLLOW
) || trailing_slash
||
580 *ndp
->ni_next
== '/')) {
581 cnp
->cn_flags
|= ISSYMLINK
;
586 * Check for bogus trailing slashes.
588 if (trailing_slash
) {
589 if (dp
->v_type
!= VDIR
) {
598 * Not a symbolic link. If more pathname,
599 * continue at next component, else return.
601 if (*ndp
->ni_next
== '/') {
602 cnp
->cn_nameptr
= ndp
->ni_next
+ 1;
604 while (*cnp
->cn_nameptr
== '/') {
613 * Disallow directory write attempts on read-only file systems.
616 (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
)) {
620 if (cnp
->cn_flags
& SAVESTART
) {
621 ndp
->ni_startdir
= ndp
->ni_dvp
;
622 VREF(ndp
->ni_startdir
);
626 if (cnp
->cn_flags
& AUDITVNPATH1
)
627 AUDIT_ARG(vnpath
, dp
, ARG_VNODE1
);
628 else if (cnp
->cn_flags
& AUDITVNPATH2
)
629 AUDIT_ARG(vnpath
, dp
, ARG_VNODE2
);
630 if ((cnp
->cn_flags
& LOCKLEAF
) == 0)
631 VOP_UNLOCK(dp
, 0, p
);
633 kdebug_lookup(dp
, cnp
);
638 * A degenerate name (e.g. / or "") which is a way of
639 * talking about a directory, e.g. like "/." or ".".
641 if (dp
->v_type
!= VDIR
) {
645 if (cnp
->cn_nameiop
!= LOOKUP
) {
653 cnp
->cn_flags
&= ~ISDOTDOT
;
654 cnp
->cn_flags
|= ISLASTCN
;
657 if (cnp
->cn_flags
& AUDITVNPATH1
)
658 AUDIT_ARG(vnpath
, dp
, ARG_VNODE1
);
659 else if (cnp
->cn_flags
& AUDITVNPATH2
)
660 AUDIT_ARG(vnpath
, dp
, ARG_VNODE2
);
661 if (!(cnp
->cn_flags
& (LOCKPARENT
| LOCKLEAF
)))
662 VOP_UNLOCK(dp
, 0, p
);
663 if (cnp
->cn_flags
& SAVESTART
)
664 panic("lookup: SAVESTART");
668 if ((cnp
->cn_flags
& LOCKPARENT
) && *ndp
->ni_next
== '\0')
669 VOP_UNLOCK(ndp
->ni_dvp
, 0, p
);
679 kdebug_lookup(dp
, cnp
);
684 * relookup - lookup a path name component
685 * Used by lookup to re-aquire things.
688 relookup(dvp
, vpp
, cnp
)
689 struct vnode
*dvp
, **vpp
;
690 struct componentname
*cnp
;
692 struct proc
*p
= cnp
->cn_proc
;
693 struct vnode
*dp
= 0; /* the directory we are searching */
694 int docache
; /* == 0 do not cache last component */
695 int wantparent
; /* 1 => wantparent or lockparent flag */
696 int rdonly
; /* lookup read-only flag bit */
698 #ifdef NAMEI_DIAGNOSTIC
699 int i
, newhash
; /* DEBUG: check name hash */
700 char *cp
; /* DEBUG: check name ptr/len */
704 * Setup: break out flag bits into variables.
706 wantparent
= cnp
->cn_flags
& (LOCKPARENT
|WANTPARENT
);
707 docache
= (cnp
->cn_flags
& NOCACHE
) ^ NOCACHE
;
708 if (cnp
->cn_nameiop
== DELETE
||
709 (wantparent
&& cnp
->cn_nameiop
!= CREATE
))
711 rdonly
= cnp
->cn_flags
& RDONLY
;
712 cnp
->cn_flags
&= ~ISSYMLINK
;
714 vn_lock(dp
, LK_EXCLUSIVE
| LK_RETRY
, p
);
718 * Search a new directory.
720 * The cn_hash value is for use by vfs_cache.
721 * The last component of the filename is left accessible via
722 * cnp->cn_nameptr for callers that need the name. Callers needing
723 * the name set the SAVENAME flag. When done, they assume
724 * responsibility for freeing the pathname buffer.
726 #ifdef NAMEI_DIAGNOSTIC
727 for (i
=1, newhash
= 0, cp
= cnp
->cn_nameptr
; *cp
!= 0 && *cp
!= '/'; cp
++)
728 newhash
+= (unsigned char)*cp
* i
;
729 if (newhash
!= cnp
->cn_hash
)
730 panic("relookup: bad hash");
731 if (cnp
->cn_namelen
!= cp
- cnp
->cn_nameptr
)
732 panic ("relookup: bad len");
734 panic("relookup: not last component");
735 printf("{%s}: ", cnp
->cn_nameptr
);
739 * Check for degenerate name (e.g. / or "")
740 * which is a way of talking about a directory,
741 * e.g. like "/." or ".".
743 if (cnp
->cn_nameptr
[0] == '\0') {
744 if (cnp
->cn_nameiop
!= LOOKUP
|| wantparent
) {
748 if (dp
->v_type
!= VDIR
) {
752 if (!(cnp
->cn_flags
& LOCKLEAF
))
753 VOP_UNLOCK(dp
, 0, p
);
755 if (cnp
->cn_flags
& SAVESTART
)
756 panic("lookup: SAVESTART");
760 if (cnp
->cn_flags
& ISDOTDOT
)
761 panic ("relookup: lookup on dot-dot");
764 * We now have a segment name to search for, and a directory to search.
766 if (error
= VOP_LOOKUP(dp
, vpp
, cnp
)) {
769 panic("leaf should be empty");
771 if (error
!= EJUSTRETURN
)
774 * If creating and at end of pathname, then can consider
775 * allowing file to be created.
781 /* ASSERT(dvp == ndp->ni_startdir) */
782 if (cnp
->cn_flags
& SAVESTART
)
785 * We return with ni_vp NULL to indicate that the entry
786 * doesn't currently exist, leaving a pointer to the
787 * (possibly locked) directory inode in ndp->ni_dvp.
795 * Check for symbolic link
797 if (dp
->v_type
== VLNK
&& (cnp
->cn_flags
& FOLLOW
))
798 panic ("relookup: symlink found.\n");
802 * Disallow directory write attempts on read-only file systems.
805 (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
)) {
809 /* ASSERT(dvp == ndp->ni_startdir) */
810 if (cnp
->cn_flags
& SAVESTART
)
815 if ((cnp
->cn_flags
& LOCKLEAF
) == 0)
816 VOP_UNLOCK(dp
, 0, p
);
820 if ((cnp
->cn_flags
& LOCKPARENT
) && (cnp
->cn_flags
& ISLASTCN
))
821 VOP_UNLOCK(dvp
, 0, p
);
833 kdebug_lookup(dp
, cnp
)
835 struct componentname
*cnp
;
838 register int dbg_namelen
;
839 register int save_dbg_namelen
;
840 register char *dbg_nameptr
;
841 long dbg_parms
[NUMPARMS
];
843 static char *dbg_filler
= ">>>>";
845 /* Collect the pathname for tracing */
846 dbg_namelen
= (cnp
->cn_nameptr
- cnp
->cn_pnbuf
) + cnp
->cn_namelen
;
847 dbg_nameptr
= cnp
->cn_nameptr
+ cnp
->cn_namelen
;
849 if (dbg_namelen
> sizeof(dbg_parms
))
850 dbg_namelen
= sizeof(dbg_parms
);
851 dbg_nameptr
-= dbg_namelen
;
852 save_dbg_namelen
= dbg_namelen
;
856 while (dbg_namelen
> 0) {
857 if (dbg_namelen
>= 4) {
858 dbg_parms
[i
++] = *(long *)dbg_nameptr
;
859 dbg_nameptr
+= sizeof(long);
860 dbg_namelen
-= sizeof(long);
862 for (n
= 0; n
< dbg_namelen
; n
++)
863 dbg_buf
[n
] = *dbg_nameptr
++;
870 dbg_parms
[i
++] = *(long *)&dbg_buf
[0];
875 while (i
< NUMPARMS
) {
877 dbg_parms
[i
++] = *(long *)dbg_filler
;
883 In the event that we collect multiple, consecutive pathname
884 entries, we must mark the start of the path's string.
886 KERNEL_DEBUG_CONSTANT((FSDBG_CODE(DBG_FSRW
,36)) | DBG_FUNC_START
,
887 (unsigned int)dp
, dbg_parms
[0], dbg_parms
[1], dbg_parms
[2], 0);
889 for (dbg_namelen
= save_dbg_namelen
-12, i
=3;
891 dbg_namelen
-=(4 * sizeof(long)), i
+= 4)
893 KERNEL_DEBUG_CONSTANT((FSDBG_CODE(DBG_FSRW
,36)) | DBG_FUNC_NONE
,
894 dbg_parms
[i
], dbg_parms
[i
+1], dbg_parms
[i
+2], dbg_parms
[i
+3], 0);