]> git.saurik.com Git - apple/xnu.git/blame - bsd/vfs/vfs_lookup.c
xnu-792.22.5.tar.gz
[apple/xnu.git] / bsd / vfs / vfs_lookup.c
CommitLineData
1c79356b 1/*
5d5c5d0d
A
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
8f6c56a5
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29/*
30 * Copyright (c) 1982, 1986, 1989, 1993
31 * The Regents of the University of California. All rights reserved.
32 * (c) UNIX System Laboratories, Inc.
33 * All or some portions of this file are derived from material licensed
34 * to the University of California by American Telephone and Telegraph
35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
36 * the permission of UNIX System Laboratories, Inc.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95
67 */
68
69#include <sys/param.h>
55e303ae 70#include <sys/systm.h>
1c79356b
A
71#include <sys/syslimits.h>
72#include <sys/time.h>
73#include <sys/namei.h>
74#include <sys/vm.h>
91447636
A
75#include <sys/vnode_internal.h>
76#include <sys/mount_internal.h>
1c79356b
A
77#include <sys/errno.h>
78#include <sys/malloc.h>
79#include <sys/filedesc.h>
91447636 80#include <sys/proc_internal.h>
1c79356b
A
81#include <sys/kdebug.h>
82#include <sys/unistd.h> /* For _PC_NAME_MAX */
91447636
A
83#include <sys/uio_internal.h>
84#include <sys/kauth.h>
e5568f75
A
85
86#include <bsm/audit_kernel.h>
1c79356b
A
87
88#if KTRACE
89#include <sys/ktrace.h>
90#endif
91
91447636
A
92
93static void kdebug_lookup(struct vnode *dp, struct componentname *cnp);
55e303ae 94
1c79356b
A
95/*
96 * Convert a pathname into a pointer to a locked inode.
97 *
98 * The FOLLOW flag is set when symbolic links are to be followed
99 * when they occur at the end of the name translation process.
100 * Symbolic links are always followed for all other pathname
101 * components other than the last.
102 *
103 * The segflg defines whether the name is to be copied from user
104 * space or kernel space.
105 *
106 * Overall outline of namei:
107 *
108 * copy in name
109 * get starting directory
110 * while (!done && !error) {
111 * call lookup to search path.
112 * if symbolic link, massage name in buffer and continue
113 * }
114 */
91447636 115
1c79356b
A
116int
117namei(ndp)
118 register struct nameidata *ndp;
119{
120 register struct filedesc *fdp; /* pointer to file descriptor state */
121 register char *cp; /* pointer into pathname argument */
122 register struct vnode *dp; /* the directory we are searching */
91447636
A
123 uio_t auio;
124 int error;
1c79356b 125 struct componentname *cnp = &ndp->ni_cnd;
91447636
A
126 vfs_context_t ctx = cnp->cn_context;
127 struct proc *p = vfs_context_proc(ctx);
55e303ae 128 char *tmppn;
91447636 129 char uio_buf[ UIO_SIZEOF(1) ];
1c79356b 130
1c79356b 131#if DIAGNOSTIC
91447636 132 if (!vfs_context_ucred(ctx) || !p)
1c79356b
A
133 panic ("namei: bad cred/proc");
134 if (cnp->cn_nameiop & (~OPMASK))
135 panic ("namei: nameiop contaminated with flags");
136 if (cnp->cn_flags & OPMASK)
137 panic ("namei: flags contaminated with nameiops");
138#endif
55e303ae 139 fdp = p->p_fd;
1c79356b
A
140
141 /*
142 * Get a buffer for the name to be translated, and copy the
143 * name into the buffer.
144 */
145 if ((cnp->cn_flags & HASBUF) == 0) {
91447636
A
146 cnp->cn_pnbuf = &ndp->ni_pathbuf;
147 cnp->cn_pnlen = PATHBUFLEN;
1c79356b 148 }
91447636
A
149#if LP64_DEBUG
150 if (IS_VALID_UIO_SEGFLG(ndp->ni_segflg) == 0) {
151 panic("%s :%d - invalid ni_segflg\n", __FILE__, __LINE__);
152 }
153#endif /* LP64_DEBUG */
154
155retry_copy:
156 if (UIO_SEG_IS_USER_SPACE(ndp->ni_segflg))
1c79356b 157 error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf,
91447636
A
158 cnp->cn_pnlen, (size_t *)&ndp->ni_pathlen);
159 else
160 error = copystr(CAST_DOWN(void *, ndp->ni_dirp), cnp->cn_pnbuf,
161 cnp->cn_pnlen, (size_t *)&ndp->ni_pathlen);
162
163 if (error == ENAMETOOLONG && !(cnp->cn_flags & HASBUF)) {
164 MALLOC_ZONE(cnp->cn_pnbuf, caddr_t,
165 MAXPATHLEN, M_NAMEI, M_WAITOK);
166
167 cnp->cn_flags |= HASBUF;
168 cnp->cn_pnlen = MAXPATHLEN;
169
170 goto retry_copy;
171 }
172 if (error)
173 goto error_out;
55e303ae
A
174
175 /* If we are auditing the kernel pathname, save the user pathname */
176 if (cnp->cn_flags & AUDITVNPATH1)
177 AUDIT_ARG(upath, p, cnp->cn_pnbuf, ARG_UPATH1);
178 if (cnp->cn_flags & AUDITVNPATH2)
179 AUDIT_ARG(upath, p, cnp->cn_pnbuf, ARG_UPATH2);
180
1c79356b
A
181 /*
182 * Do not allow empty pathnames
183 */
91447636 184 if (*cnp->cn_pnbuf == '\0') {
1c79356b 185 error = ENOENT;
91447636 186 goto error_out;
1c79356b
A
187 }
188 ndp->ni_loopcnt = 0;
189#if KTRACE
55e303ae
A
190 if (KTRPOINT(p, KTR_NAMEI))
191 ktrnamei(p->p_tracep, cnp->cn_pnbuf);
1c79356b
A
192#endif
193
194 /*
91447636 195 * determine the starting point for the translation.
1c79356b 196 */
91447636
A
197 if ((ndp->ni_rootdir = fdp->fd_rdir) == NULLVP) {
198 if ( !(fdp->fd_flags & FD_CHROOT))
199 ndp->ni_rootdir = rootvnode;
55e303ae 200 }
91447636 201 cnp->cn_nameptr = cnp->cn_pnbuf;
55e303ae 202
91447636
A
203 ndp->ni_usedvp = NULLVP;
204
205 if (*(cnp->cn_nameptr) == '/') {
206 while (*(cnp->cn_nameptr) == '/') {
207 cnp->cn_nameptr++;
208 ndp->ni_pathlen--;
1c79356b 209 }
91447636
A
210 dp = ndp->ni_rootdir;
211 } else if (cnp->cn_flags & USEDVP) {
212 dp = ndp->ni_dvp;
213 ndp->ni_usedvp = dp;
214 } else
215 dp = fdp->fd_cdir;
216
217 if (dp == NULLVP) {
218 error = ENOENT;
219 goto error_out;
220 }
221 ndp->ni_dvp = NULLVP;
222 ndp->ni_vp = NULLVP;
223
224 for (;;) {
225 int need_newpathbuf;
226 int linklen;
227
1c79356b 228 ndp->ni_startdir = dp;
91447636
A
229
230 if ( (error = lookup(ndp)) ) {
231 goto error_out;
1c79356b
A
232 }
233 /*
234 * Check for symbolic link
235 */
236 if ((cnp->cn_flags & ISSYMLINK) == 0) {
1c79356b
A
237 return (0);
238 }
91447636
A
239 if ((cnp->cn_flags & FSNODELOCKHELD)) {
240 cnp->cn_flags &= ~FSNODELOCKHELD;
241 unlock_fsnode(ndp->ni_dvp, NULL);
242 }
1c79356b
A
243 if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
244 error = ELOOP;
245 break;
246 }
91447636
A
247 if (ndp->ni_pathlen > 1 || !(cnp->cn_flags & HASBUF))
248 need_newpathbuf = 1;
249 else
250 need_newpathbuf = 0;
251
252 if (need_newpathbuf) {
1c79356b
A
253 MALLOC_ZONE(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
254 } else {
255 cp = cnp->cn_pnbuf;
256 }
91447636
A
257 auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_READ, &uio_buf[0], sizeof(uio_buf));
258
259 uio_addiov(auio, CAST_USER_ADDR_T(cp), MAXPATHLEN);
260
261 error = VNOP_READLINK(ndp->ni_vp, auio, ctx);
262 if (error) {
263 if (need_newpathbuf)
55e303ae 264 FREE_ZONE(cp, MAXPATHLEN, M_NAMEI);
1c79356b
A
265 break;
266 }
91447636
A
267 // LP64todo - fix this
268 linklen = MAXPATHLEN - uio_resid(auio);
269 if (linklen + ndp->ni_pathlen > MAXPATHLEN) {
270 if (need_newpathbuf)
55e303ae 271 FREE_ZONE(cp, MAXPATHLEN, M_NAMEI);
91447636 272
1c79356b
A
273 error = ENAMETOOLONG;
274 break;
275 }
91447636 276 if (need_newpathbuf) {
55e303ae 277 long len = cnp->cn_pnlen;
91447636 278
55e303ae 279 tmppn = cnp->cn_pnbuf;
1c79356b 280 bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen);
1c79356b
A
281 cnp->cn_pnbuf = cp;
282 cnp->cn_pnlen = MAXPATHLEN;
91447636
A
283
284 if ( (cnp->cn_flags & HASBUF) )
285 FREE_ZONE(tmppn, len, M_NAMEI);
286 else
287 cnp->cn_flags |= HASBUF;
1c79356b
A
288 } else
289 cnp->cn_pnbuf[linklen] = '\0';
91447636 290
1c79356b 291 ndp->ni_pathlen += linklen;
91447636
A
292 cnp->cn_nameptr = cnp->cn_pnbuf;
293
294 /*
295 * starting point for 'relative'
296 * symbolic link path
297 */
1c79356b 298 dp = ndp->ni_dvp;
91447636
A
299 /*
300 * get rid of references returned via 'lookup'
301 */
302 vnode_put(ndp->ni_vp);
303 vnode_put(ndp->ni_dvp);
304
305 ndp->ni_vp = NULLVP;
306 ndp->ni_dvp = NULLVP;
55e303ae 307
91447636
A
308 /*
309 * Check if symbolic link restarts us at the root
310 */
311 if (*(cnp->cn_nameptr) == '/') {
312 while (*(cnp->cn_nameptr) == '/') {
313 cnp->cn_nameptr++;
314 ndp->ni_pathlen--;
315 }
316 if ((dp = ndp->ni_rootdir) == NULLVP) {
317 error = ENOENT;
318 goto error_out;
319 }
320 }
321 }
322 /*
323 * only come here if we fail to handle a SYMLINK...
324 * if either ni_dvp or ni_vp is non-NULL, then
325 * we need to drop the iocount that was picked
326 * up in the lookup routine
327 */
328 if (ndp->ni_dvp)
329 vnode_put(ndp->ni_dvp);
330 if (ndp->ni_vp)
331 vnode_put(ndp->ni_vp);
332 error_out:
333 if ( (cnp->cn_flags & HASBUF) ) {
334 cnp->cn_flags &= ~HASBUF;
335 FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
336 }
55e303ae 337 cnp->cn_pnbuf = NULL;
91447636 338 ndp->ni_vp = NULLVP;
55e303ae 339
1c79356b
A
340 return (error);
341}
342
91447636 343
1c79356b
A
344/*
345 * Search a pathname.
346 * This is a very central and rather complicated routine.
347 *
348 * The pathname is pointed to by ni_ptr and is of length ni_pathlen.
349 * The starting directory is taken from ni_startdir. The pathname is
350 * descended until done, or a symbolic link is encountered. The variable
351 * ni_more is clear if the path is completed; it is set to one if a
352 * symbolic link needing interpretation is encountered.
353 *
354 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
355 * whether the name is to be looked up, created, renamed, or deleted.
356 * When CREATE, RENAME, or DELETE is specified, information usable in
357 * creating, renaming, or deleting a directory entry may be calculated.
358 * If flag has LOCKPARENT or'ed into it, the parent directory is returned
359 * locked. If flag has WANTPARENT or'ed into it, the parent directory is
360 * returned unlocked. Otherwise the parent directory is not returned. If
361 * the target of the pathname exists and LOCKLEAF is or'ed into the flag
362 * the target is returned locked, otherwise it is returned unlocked.
363 * When creating or renaming and LOCKPARENT is specified, the target may not
364 * be ".". When deleting and LOCKPARENT is specified, the target may be ".".
365 *
366 * Overall outline of lookup:
367 *
368 * dirloop:
369 * identify next component of name at ndp->ni_ptr
370 * handle degenerate case where name is null string
371 * if .. and crossing mount points and on mounted filesys, find parent
91447636 372 * call VNOP_LOOKUP routine for next component name
1c79356b
A
373 * directory vnode returned in ni_dvp, unlocked unless LOCKPARENT set
374 * component vnode returned in ni_vp (if it exists), locked.
375 * if result vnode is mounted on and crossing mount points,
376 * find mounted on vnode
377 * if more components of name, do next level at dirloop
378 * return the answer in ni_vp, locked if LOCKLEAF set
379 * if LOCKPARENT set, return locked parent in ni_dvp
380 * if WANTPARENT set, return unlocked parent in ni_dvp
381 */
382int
383lookup(ndp)
384 register struct nameidata *ndp;
385{
91447636
A
386 register char *cp; /* pointer into pathname argument */
387 vnode_t tdp; /* saved dp */
388 vnode_t dp; /* the directory we are searching */
389 mount_t mp; /* mount table entry */
390 int docache = 1; /* == 0 do not cache last component */
1c79356b
A
391 int wantparent; /* 1 => wantparent or lockparent flag */
392 int rdonly; /* lookup read-only flag bit */
55e303ae 393 int trailing_slash = 0;
91447636 394 int dp_authorized = 0;
1c79356b
A
395 int error = 0;
396 struct componentname *cnp = &ndp->ni_cnd;
91447636 397 vfs_context_t ctx = cnp->cn_context;
1c79356b
A
398
399 /*
400 * Setup: break out flag bits into variables.
401 */
91447636
A
402 if (cnp->cn_flags & (NOCACHE | DOWHITEOUT)) {
403 if ((cnp->cn_flags & NOCACHE) || (cnp->cn_nameiop == DELETE))
404 docache = 0;
405 }
1c79356b 406 wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
1c79356b 407 rdonly = cnp->cn_flags & RDONLY;
1c79356b 408 cnp->cn_flags &= ~ISSYMLINK;
91447636
A
409 cnp->cn_consume = 0;
410
1c79356b
A
411 dp = ndp->ni_startdir;
412 ndp->ni_startdir = NULLVP;
1c79356b 413
91447636 414 cp = cnp->cn_nameptr;
55e303ae 415
91447636
A
416 if (*cp == '\0') {
417 if ( (vnode_getwithref(dp)) ) {
418 dp = NULLVP;
419 error = ENOENT;
55e303ae
A
420 goto bad;
421 }
91447636 422 goto emptyname;
1c79356b 423 }
91447636
A
424dirloop:
425 ndp->ni_vp = NULLVP;
9bccf70c 426
91447636
A
427 if ( (error = cache_lookup_path(ndp, cnp, dp, ctx, &trailing_slash, &dp_authorized)) ) {
428 dp = NULLVP;
429 goto bad;
430 }
431 if ((cnp->cn_flags & ISLASTCN)) {
432 if (docache)
433 cnp->cn_flags |= MAKEENTRY;
434 } else
435 cnp->cn_flags |= MAKEENTRY;
436
437 dp = ndp->ni_dvp;
438
439 if (ndp->ni_vp != NULLVP) {
440 /*
441 * cache_lookup_path returned a non-NULL ni_vp then,
442 * we're guaranteed that the dp is a VDIR, it's
443 * been authorized, and vp is not ".."
444 */
445 goto returned_from_lookup_path;
9bccf70c 446 }
1c79356b 447
1c79356b
A
448 /*
449 * Handle "..": two special cases.
450 * 1. If at root directory (e.g. after chroot)
451 * or at absolute root directory
452 * then ignore it so can't get out.
453 * 2. If this vnode is the root of a mounted
454 * filesystem, then replace it with the
455 * vnode which was mounted on so we take the
456 * .. in the other file system.
457 */
91447636 458 if ( (cnp->cn_flags & ISDOTDOT) ) {
1c79356b 459 for (;;) {
91447636
A
460 if (dp == ndp->ni_rootdir || dp == rootvnode) {
461 ndp->ni_dvp = dp;
1c79356b 462 ndp->ni_vp = dp;
91447636
A
463 /*
464 * we're pinned at the root
465 * we've already got one reference on 'dp'
466 * courtesy of cache_lookup_path... take
467 * another one for the ".."
468 * if we fail to get the new reference, we'll
469 * drop our original down in 'bad'
470 */
471 if ( (vnode_get(dp)) ) {
472 error = ENOENT;
473 goto bad;
474 }
1c79356b
A
475 goto nextname;
476 }
477 if ((dp->v_flag & VROOT) == 0 ||
478 (cnp->cn_flags & NOCROSSMOUNT))
91447636 479 break;
0b4e3aa0 480 if (dp->v_mount == NULL) { /* forced umount */
91447636 481 error = EBADF;
0b4e3aa0
A
482 goto bad;
483 }
1c79356b 484 tdp = dp;
91447636
A
485 dp = tdp->v_mount->mnt_vnodecovered;
486
487 vnode_put(tdp);
488
489 if ( (vnode_getwithref(dp)) ) {
490 dp = NULLVP;
491 error = ENOENT;
492 goto bad;
493 }
494 ndp->ni_dvp = dp;
495 dp_authorized = 0;
1c79356b
A
496 }
497 }
498
499 /*
500 * We now have a segment name to search for, and a directory to search.
501 */
502unionlookup:
91447636
A
503 ndp->ni_vp = NULLVP;
504
505 if (dp->v_type != VDIR) {
506 error = ENOTDIR;
507 goto lookup_error;
508 }
509 if ( !(dp_authorized || (cnp->cn_flags & DONOTAUTH)) ) {
510 if ( (error = vnode_authorize(dp, NULL, KAUTH_VNODE_SEARCH, ctx)) )
511 goto lookup_error;
512 }
513 if ( (error = VNOP_LOOKUP(dp, &ndp->ni_vp, cnp, ctx)) ) {
514lookup_error:
1c79356b 515 if ((error == ENOENT) &&
0b4e3aa0 516 (dp->v_flag & VROOT) && (dp->v_mount != NULL) &&
1c79356b 517 (dp->v_mount->mnt_flag & MNT_UNION)) {
91447636
A
518 if ((cnp->cn_flags & FSNODELOCKHELD)) {
519 cnp->cn_flags &= ~FSNODELOCKHELD;
520 unlock_fsnode(dp, NULL);
521 }
1c79356b 522 tdp = dp;
91447636
A
523 dp = tdp->v_mount->mnt_vnodecovered;
524
525 vnode_put(tdp);
526
527 if ( (vnode_getwithref(dp)) ) {
528 dp = NULLVP;
529 error = ENOENT;
530 goto bad;
531 }
532 ndp->ni_dvp = dp;
533 dp_authorized = 0;
1c79356b
A
534 goto unionlookup;
535 }
536
537 if (error != EJUSTRETURN)
538 goto bad;
91447636
A
539
540 if (ndp->ni_vp != NULLVP)
541 panic("leaf should be empty");
542
1c79356b
A
543 /*
544 * If creating and at end of pathname, then can consider
545 * allowing file to be created.
546 */
547 if (rdonly) {
548 error = EROFS;
549 goto bad;
550 }
91447636 551 if ((cnp->cn_flags & ISLASTCN) && trailing_slash && !(cnp->cn_flags & WILLBEDIR)) {
9bccf70c
A
552 error = ENOENT;
553 goto bad;
554 }
1c79356b
A
555 /*
556 * We return with ni_vp NULL to indicate that the entry
557 * doesn't currently exist, leaving a pointer to the
91447636 558 * referenced directory vnode in ndp->ni_dvp.
1c79356b
A
559 */
560 if (cnp->cn_flags & SAVESTART) {
91447636
A
561 if ( (vnode_get(ndp->ni_dvp)) ) {
562 error = ENOENT;
563 goto bad;
564 }
1c79356b 565 ndp->ni_startdir = ndp->ni_dvp;
1c79356b 566 }
91447636
A
567 if (!wantparent)
568 vnode_put(ndp->ni_dvp);
569
1c79356b
A
570 if (kdebug_enable)
571 kdebug_lookup(ndp->ni_dvp, cnp);
572 return (0);
573 }
91447636
A
574returned_from_lookup_path:
575 dp = ndp->ni_vp;
1c79356b
A
576
577 /*
578 * Take into account any additional components consumed by
579 * the underlying filesystem.
580 */
581 if (cnp->cn_consume > 0) {
582 cnp->cn_nameptr += cnp->cn_consume;
583 ndp->ni_next += cnp->cn_consume;
584 ndp->ni_pathlen -= cnp->cn_consume;
585 cnp->cn_consume = 0;
55e303ae 586 } else {
91447636
A
587 if (dp->v_name == NULL || dp->v_parent == NULLVP) {
588 int isdot_or_dotdot;
589 int update_flags = 0;
55e303ae 590
91447636 591 isdot_or_dotdot = (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') || (cnp->cn_flags & ISDOTDOT);
55e303ae 592
91447636
A
593 if (isdot_or_dotdot == 0) {
594 if (dp->v_name == NULL)
595 update_flags |= VNODE_UPDATE_NAME;
596 if (ndp->ni_dvp != NULLVP && dp->v_parent == NULLVP)
597 update_flags |= VNODE_UPDATE_PARENT;
598
599 if (update_flags)
600 vnode_update_identity(dp, ndp->ni_dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, update_flags);
601 }
602 }
603
604 if ( (cnp->cn_flags & MAKEENTRY) && (dp->v_flag & VNCACHEABLE) && LIST_FIRST(&dp->v_nclinks) == NULL) {
605 /*
606 * missing from name cache, but should
607 * be in it... this can happen if volfs
608 * causes the vnode to be created or the
609 * name cache entry got recycled but the
610 * vnode didn't...
611 * check to make sure that ni_dvp is valid
612 * cache_lookup_path may return a NULL
613 */
614 if (ndp->ni_dvp != NULL)
615 cache_enter(ndp->ni_dvp, dp, cnp);
55e303ae 616 }
1c79356b
A
617 }
618
1c79356b 619 /*
91447636 620 * Check to see if the vnode has been mounted on...
1c79356b
A
621 * if so find the root of the mounted file system.
622 */
91447636
A
623check_mounted_on:
624 if ((dp->v_type == VDIR) && dp->v_mountedhere &&
625 ((cnp->cn_flags & NOCROSSMOUNT) == 0)) {
626
627 vnode_lock(dp);
628
629 if ((dp->v_type == VDIR) && (mp = dp->v_mountedhere)) {
630
631 mp->mnt_crossref++;
632 vnode_unlock(dp);
633
634 if (vfs_busy(mp, 0)) {
635 mount_dropcrossref(mp, dp, 0);
636 goto check_mounted_on;
637 }
638 error = VFS_ROOT(mp, &tdp, ctx);
639 /*
640 * mount_dropcrossref does a vnode_put
641 * on dp if the 3rd arg is non-zero
642 */
643 mount_dropcrossref(mp, dp, 1);
644 dp = NULL;
645 vfs_unbusy(mp);
646
647 if (error) {
648 goto bad2;
649 }
650 ndp->ni_vp = dp = tdp;
651
652 goto check_mounted_on;
653 }
654 vnode_unlock(dp);
1c79356b
A
655 }
656
657 /*
658 * Check for symbolic link
659 */
660 if ((dp->v_type == VLNK) &&
91447636 661 ((cnp->cn_flags & FOLLOW) || trailing_slash || *ndp->ni_next == '/')) {
1c79356b
A
662 cnp->cn_flags |= ISSYMLINK;
663 return (0);
664 }
665
9bccf70c
A
666 /*
667 * Check for bogus trailing slashes.
668 */
55e303ae
A
669 if (trailing_slash) {
670 if (dp->v_type != VDIR) {
671 error = ENOTDIR;
672 goto bad2;
673 }
674 trailing_slash = 0;
91447636 675 }
9bccf70c 676
1c79356b
A
677nextname:
678 /*
679 * Not a symbolic link. If more pathname,
680 * continue at next component, else return.
681 */
682 if (*ndp->ni_next == '/') {
55e303ae
A
683 cnp->cn_nameptr = ndp->ni_next + 1;
684 ndp->ni_pathlen--;
1c79356b
A
685 while (*cnp->cn_nameptr == '/') {
686 cnp->cn_nameptr++;
687 ndp->ni_pathlen--;
688 }
91447636
A
689 vnode_put(ndp->ni_dvp);
690
691 cp = cnp->cn_nameptr;
692
693 if (*cp == '\0')
694 goto emptyname;
695
696 vnode_put(dp);
1c79356b
A
697 goto dirloop;
698 }
699
700 /*
701 * Disallow directory write attempts on read-only file systems.
702 */
703 if (rdonly &&
704 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
705 error = EROFS;
706 goto bad2;
707 }
708 if (cnp->cn_flags & SAVESTART) {
91447636
A
709 /*
710 * note that we already hold a reference
711 * on both dp and ni_dvp, but for some reason
712 * can't get another one... in this case we
713 * need to do vnode_put on dp in 'bad2'
714 */
715 if ( (vnode_get(ndp->ni_dvp)) ) {
716 error = ENOENT;
717 goto bad2;
718 }
1c79356b 719 ndp->ni_startdir = ndp->ni_dvp;
1c79356b 720 }
91447636
A
721 if (!wantparent && ndp->ni_dvp)
722 vnode_put(ndp->ni_dvp);
723
55e303ae
A
724 if (cnp->cn_flags & AUDITVNPATH1)
725 AUDIT_ARG(vnpath, dp, ARG_VNODE1);
726 else if (cnp->cn_flags & AUDITVNPATH2)
727 AUDIT_ARG(vnpath, dp, ARG_VNODE2);
91447636 728
1c79356b
A
729 if (kdebug_enable)
730 kdebug_lookup(dp, cnp);
731 return (0);
732
55e303ae 733emptyname:
91447636 734 cnp->cn_namelen = 0;
55e303ae
A
735 /*
736 * A degenerate name (e.g. / or "") which is a way of
737 * talking about a directory, e.g. like "/." or ".".
738 */
739 if (dp->v_type != VDIR) {
740 error = ENOTDIR;
741 goto bad;
742 }
743 if (cnp->cn_nameiop != LOOKUP) {
744 error = EISDIR;
745 goto bad;
746 }
747 if (wantparent) {
91447636
A
748 /*
749 * note that we already hold a reference
750 * on dp, but for some reason can't
751 * get another one... in this case we
752 * need to do vnode_put on dp in 'bad'
753 */
754 if ( (vnode_get(dp)) ) {
755 error = ENOENT;
756 goto bad;
757 }
55e303ae 758 ndp->ni_dvp = dp;
55e303ae
A
759 }
760 cnp->cn_flags &= ~ISDOTDOT;
761 cnp->cn_flags |= ISLASTCN;
762 ndp->ni_next = cp;
763 ndp->ni_vp = dp;
91447636 764
55e303ae
A
765 if (cnp->cn_flags & AUDITVNPATH1)
766 AUDIT_ARG(vnpath, dp, ARG_VNODE1);
767 else if (cnp->cn_flags & AUDITVNPATH2)
768 AUDIT_ARG(vnpath, dp, ARG_VNODE2);
55e303ae
A
769 if (cnp->cn_flags & SAVESTART)
770 panic("lookup: SAVESTART");
771 return (0);
772
1c79356b 773bad2:
91447636
A
774 if ((cnp->cn_flags & FSNODELOCKHELD)) {
775 cnp->cn_flags &= ~FSNODELOCKHELD;
776 unlock_fsnode(ndp->ni_dvp, NULL);
777 }
778 if (ndp->ni_dvp)
779 vnode_put(ndp->ni_dvp);
780 if (dp)
781 vnode_put(dp);
782 ndp->ni_vp = NULLVP;
783
784 if (kdebug_enable)
785 kdebug_lookup(dp, cnp);
786 return (error);
787
1c79356b 788bad:
91447636
A
789 if ((cnp->cn_flags & FSNODELOCKHELD)) {
790 cnp->cn_flags &= ~FSNODELOCKHELD;
791 unlock_fsnode(ndp->ni_dvp, NULL);
792 }
793 if (dp)
794 vnode_put(dp);
795 ndp->ni_vp = NULLVP;
796
1c79356b
A
797 if (kdebug_enable)
798 kdebug_lookup(dp, cnp);
799 return (error);
800}
801
802/*
803 * relookup - lookup a path name component
804 * Used by lookup to re-aquire things.
805 */
806int
807relookup(dvp, vpp, cnp)
808 struct vnode *dvp, **vpp;
809 struct componentname *cnp;
810{
1c79356b 811 struct vnode *dp = 0; /* the directory we are searching */
1c79356b
A
812 int wantparent; /* 1 => wantparent or lockparent flag */
813 int rdonly; /* lookup read-only flag bit */
814 int error = 0;
815#ifdef NAMEI_DIAGNOSTIC
55e303ae 816 int i, newhash; /* DEBUG: check name hash */
1c79356b
A
817 char *cp; /* DEBUG: check name ptr/len */
818#endif
91447636 819 vfs_context_t ctx = cnp->cn_context;;
1c79356b
A
820
821 /*
822 * Setup: break out flag bits into variables.
823 */
824 wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
1c79356b
A
825 rdonly = cnp->cn_flags & RDONLY;
826 cnp->cn_flags &= ~ISSYMLINK;
1c79356b 827
91447636
A
828 if (cnp->cn_flags & NOCACHE)
829 cnp->cn_flags &= ~MAKEENTRY;
830 else
831 cnp->cn_flags |= MAKEENTRY;
832
833 dp = dvp;
1c79356b
A
834
835 /*
836 * Check for degenerate name (e.g. / or "")
837 * which is a way of talking about a directory,
838 * e.g. like "/." or ".".
839 */
840 if (cnp->cn_nameptr[0] == '\0') {
841 if (cnp->cn_nameiop != LOOKUP || wantparent) {
842 error = EISDIR;
843 goto bad;
844 }
845 if (dp->v_type != VDIR) {
846 error = ENOTDIR;
847 goto bad;
848 }
91447636
A
849 if ( (vnode_get(dp)) ) {
850 error = ENOENT;
851 goto bad;
852 }
1c79356b 853 *vpp = dp;
91447636 854
1c79356b
A
855 if (cnp->cn_flags & SAVESTART)
856 panic("lookup: SAVESTART");
857 return (0);
858 }
1c79356b
A
859 /*
860 * We now have a segment name to search for, and a directory to search.
861 */
91447636
A
862 if ( (error = VNOP_LOOKUP(dp, vpp, cnp, ctx)) ) {
863 if (error != EJUSTRETURN)
864 goto bad;
1c79356b
A
865#if DIAGNOSTIC
866 if (*vpp != NULL)
867 panic("leaf should be empty");
868#endif
1c79356b
A
869 /*
870 * If creating and at end of pathname, then can consider
871 * allowing file to be created.
872 */
873 if (rdonly) {
874 error = EROFS;
875 goto bad;
876 }
1c79356b
A
877 /*
878 * We return with ni_vp NULL to indicate that the entry
879 * doesn't currently exist, leaving a pointer to the
880 * (possibly locked) directory inode in ndp->ni_dvp.
881 */
882 return (0);
883 }
884 dp = *vpp;
885
886#if DIAGNOSTIC
887 /*
888 * Check for symbolic link
889 */
890 if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))
891 panic ("relookup: symlink found.\n");
892#endif
893
894 /*
895 * Disallow directory write attempts on read-only file systems.
896 */
897 if (rdonly &&
898 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
899 error = EROFS;
900 goto bad2;
901 }
902 /* ASSERT(dvp == ndp->ni_startdir) */
1c79356b 903
1c79356b
A
904 return (0);
905
906bad2:
91447636
A
907 vnode_put(dp);
908bad:
1c79356b 909 *vpp = NULL;
91447636 910
1c79356b
A
911 return (error);
912}
913
91447636
A
914/*
915 * Free pathname buffer
916 */
917void
918nameidone(struct nameidata *ndp)
919{
920 if ((ndp->ni_cnd.cn_flags & FSNODELOCKHELD)) {
921 ndp->ni_cnd.cn_flags &= ~FSNODELOCKHELD;
922 unlock_fsnode(ndp->ni_dvp, NULL);
923 }
924 if (ndp->ni_cnd.cn_flags & HASBUF) {
925 char *tmp = ndp->ni_cnd.cn_pnbuf;
926
927 ndp->ni_cnd.cn_pnbuf = NULL;
928 ndp->ni_cnd.cn_flags &= ~HASBUF;
929 FREE_ZONE(tmp, ndp->ni_cnd.cn_pnlen, M_NAMEI);
930 }
931}
932
1c79356b 933
0b4e3aa0 934#define NUMPARMS 23
1c79356b 935
55e303ae 936static void
1c79356b 937kdebug_lookup(dp, cnp)
55e303ae 938 struct vnode *dp;
1c79356b
A
939 struct componentname *cnp;
940{
4452a7af 941 register unsigned int i, n, code;
1c79356b 942 register int dbg_namelen;
0b4e3aa0 943 register int save_dbg_namelen;
1c79356b
A
944 register char *dbg_nameptr;
945 long dbg_parms[NUMPARMS];
946 char dbg_buf[4];
947 static char *dbg_filler = ">>>>";
948
949 /* Collect the pathname for tracing */
950 dbg_namelen = (cnp->cn_nameptr - cnp->cn_pnbuf) + cnp->cn_namelen;
951 dbg_nameptr = cnp->cn_nameptr + cnp->cn_namelen;
952
953 if (dbg_namelen > sizeof(dbg_parms))
954 dbg_namelen = sizeof(dbg_parms);
955 dbg_nameptr -= dbg_namelen;
0b4e3aa0 956 save_dbg_namelen = dbg_namelen;
1c79356b
A
957
958 i = 0;
959
960 while (dbg_namelen > 0) {
961 if (dbg_namelen >= 4) {
962 dbg_parms[i++] = *(long *)dbg_nameptr;
963 dbg_nameptr += sizeof(long);
964 dbg_namelen -= sizeof(long);
965 } else {
966 for (n = 0; n < dbg_namelen; n++)
967 dbg_buf[n] = *dbg_nameptr++;
968 while (n <= 3) {
969 if (*dbg_nameptr)
970 dbg_buf[n++] = '>';
971 else
972 dbg_buf[n++] = 0;
973 }
974 dbg_parms[i++] = *(long *)&dbg_buf[0];
975
976 break;
977 }
978 }
979 while (i < NUMPARMS) {
980 if (*dbg_nameptr)
981 dbg_parms[i++] = *(long *)dbg_filler;
982 else
983 dbg_parms[i++] = 0;
984 }
4452a7af 985 dbg_namelen = save_dbg_namelen - 12;
0b4e3aa0 986
9bccf70c 987 /*
4452a7af
A
988 * In the event that we collect multiple, consecutive pathname
989 * entries, we must mark the start of the path's string and the end
990 */
991 code = (FSDBG_CODE(DBG_FSRW,36)) | DBG_FUNC_START;
992
993 if (dbg_namelen <= 0)
994 code |= DBG_FUNC_END;
995
996 KERNEL_DEBUG_CONSTANT(code, (unsigned int)dp, dbg_parms[0], dbg_parms[1], dbg_parms[2], 0);
997
998 code &= ~DBG_FUNC_START;
999
1000 for (i = 3; dbg_namelen > 0; i += 4) {
1001
1002 dbg_namelen -= (4 * sizeof(long));
1003 if (dbg_namelen <= 0)
1004 code |= DBG_FUNC_END;
1005
1006 KERNEL_DEBUG_CONSTANT(code, dbg_parms[i], dbg_parms[i+1], dbg_parms[i+2], dbg_parms[i+3], 0);
1007 }
1c79356b 1008}