xref: /netbsd-src/share/man/man9/namei.9 (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1.\"     $NetBSD: namei.9,v 1.37 2016/05/07 08:52:10 wiz Exp $
2.\"
3.\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Gregory McGarry.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd May 6, 2016
31.Dt NAMEI 9
32.Os
33.Sh NAME
34.Nm namei ,
35.Nm NDINIT ,
36.Nm NDAT ,
37.Nm namei_simple_kernel ,
38.Nm namei_simple_user
39.Nm relookup ,
40.Nm lookup_for_nfsd ,
41.Nm lookup_for_nfsd_index ,
42.Nd pathname lookup
43.Sh SYNOPSIS
44.In sys/namei.h
45.In sys/uio.h
46.In sys/vnode.h
47.Fn NDINIT "struct nameidata *ndp" "u_long op" "u_long flags" \
48"struct pathbuf *pathbuf"
49.Fn NDAT "struct nameidata *ndp" "struct vnode *dvp"
50.Ft int
51.Fn namei "struct nameidata *ndp"
52.Ft int
53.Fn namei_simple_kernel "const char *path" "namei_simple_flags_t sflags" \
54"struct vnode **ret"
55.Ft int
56.Fn namei_simple_user "const char *path" "namei_simple_flags_t sflags" \
57"struct vnode **ret"
58.Ft int
59.Fn relookup "struct vnode *dvp" "struct vnode **vpp" \
60"struct componentname *cnp"
61.Ft int
62.Fn lookup_for_nfsd "struct nameidata *ndp" "struct vnode *startdir" \
63"int neverfollow"
64.Ft int
65.Fn lookup_for_nfsd_index "struct nameidata *ndp"
66.Sh DESCRIPTION
67The
68.Nm
69interface is used to convert pathnames to file system vnodes.
70The
71name of the interface is actually a contraction of the words
72.Em name
73and
74.Em inode
75for name-to-inode conversion, in the days before the
76.Xr vfs 9
77interface was implemented.
78.Pp
79Except for the simple forms, the arguments passed to the functions are
80encapsulated in the
81.Em nameidata
82structure.
83The public interface to this structure is as follows.
84.Bl -offset indent
85.It
86It contains a member
87.Em ni_erootdir
88that may be set to the emulation root directory before the call if
89the
90.Dv EMULROOTSET
91flag is also set and
92.Dv TRYEMULROOT
93is in effect.
94This is only necessary (or allowed) if the emulation root is not yet
95set in the current process.
96.It
97It contains a member
98.Em ni_vp
99that upon successful return contains the result vnode.
100.It
101It contains a member
102.Em ni_dvp
103that upon successful return contains the vnode of the directory
104containing the result vnode or
105.Dv NULL .
106If the
107.Dv LOCKPARENT
108flag is set, the containing vnode is returned; otherwise this field is
109left set to
110.Dv NULL .
111.It
112It contains a member
113.Em ni_cnd
114that is a
115.Em componentname
116structure (described in just a moment).
117This may be used by callers to pass to certain vnode operations that
118operate on pathnames.
119.El
120.Pp
121The other fields in the structure should not be examined or altered
122directly.
123Note that the
124.Xr nfs 4
125code misuses the
126.Em nameidata
127structure and currently has an incestuous relationship with the
128.Nm
129code.
130This is gradually being cleaned up.
131Other code should initialize the
132.Em nameidata
133structure with the
134.Fn NDINIT
135macro and perhaps also the
136.Fn NDAT
137macro.
138.Pp
139The
140.Em componentname
141structure has the following layout:
142.Bd -literal
143struct componentname {
144	/*
145	 * Arguments to VOP_LOOKUP and directory VOP routines.
146	 */
147	uint32_t	cn_nameiop;	/* namei operation */
148	uint32_t	cn_flags;	/* flags to namei */
149	kauth_cred_t 	cn_cred;	/* credentials */
150	const char 	*cn_nameptr;	/* pointer to looked up name */
151	size_t		cn_namelen;	/* length of looked up comp */
152	/*
153	 * Side result from VOP_LOOKUP.
154	 */
155	size_t		cn_consume;	/* chars to consume in lookup */
156};
157.Ed
158This structure contains the information about a single directory
159component name, along with certain other information required by vnode
160operations.
161See
162.Xr vnodeops 9
163for more information about these vnode operations.
164.Pp
165The members:
166.Bl -tag -offset indent -width cn_consumexx -compact
167.It cn_nameiop
168The type of operation in progress; indicates the basic operating mode
169of namei.
170May be one of
171.Dv LOOKUP ,
172.Dv CREATE ,
173.Dv DELETE ,
174or
175.Dv RENAME .
176These modes are described below.
177.It cn_flags
178Additional flags affecting the operation of namei.
179These are described below as well.
180.It cn_cred
181The credentials to use for the lookup or other operation the
182.Em componentname
183is passed to.
184This may match the credentials of the current process or it may not,
185depending on where the original operation request came from and how it
186has been routed.
187.It cn_nameptr
188The name of this directory component, followed by the rest of the path
189being looked up.
190.It cn_namelen
191The length of the name of this directory component.
192The name is not in general null terminated, although the complete
193string (the full remaining path) always is.
194.It cn_consume
195This field starts at zero; it may be set to a larger value by
196implementations of
197.Xr VOP_LOOKUP 9
198to indicate how many more characters beyond
199.Em cn_namelen
200are being consumed.
201New uses of this feature are discouraged and should be discussed.
202.El
203.Ss Operating modes
204The
205.Dv LOOKUP
206mode is the baseline behavior, for all ordinary lookups that simply
207return a vnode.
208In this mode, if the requested object does not exist,
209.Er ENOENT
210is returned.
211.Pp
212The
213.Dv CREATE
214mode is used when doing the lookup for operations that create names in
215the file system namespace, such as
216.Xr mkdir 2 .
217In this mode, if the requested name already exists,
218.Er EEXIST
219is returned.
220Otherwise if the requested name does not exist, the lookup succeeds
221and the returned vnode
222.Em ni_vp
223is set to
224.Dv NULL .
225.Pp
226The
227.Dv DELETE
228mode is used when doing the lookup for operations that remove names
229from the file system namespace, such as
230.Xr rmdir 2 ;
231and the
232.Dv RENAME
233mode is used when doing (one of the) lookups for
234.Xr rename 2 .
235.Pp
236The mode may affect both the
237.Xr VOP_LOOKUP 9
238implementation of the file system involved and the internal operation
239of
240.Nm ,
241such as interactions with the
242.Xr namecache 9 .
243In
244.Xr ffs 4 ,
245for example, the
246.Xr VOP_LOOKUP 9
247implementation reacts to
248.Dv CREATE ,
249.Dv DELETE ,
250and
251.Dv RENAME
252by computing additional information needed to operate on directory
253entries.
254This information is consumed by the vnode operations expected to be
255called subsequently.
256If one of these modes is used (and owing to failure or whatever other
257circumstances) the eventual vnode operation is not called,
258.Xr VOP_ABORTOP 9
259should be used to ensure the state involved is cleaned up correctly.
260.Ss Flags
261The following flags may appear.
262Some are set by
263.Nm ;
264some are set by
265.Xr VOP_LOOKUP 9 ;
266some are set by the caller in the
267.Fa flags
268argument of
269.Fn NDINIT .
270Not all possible combinations are sensible or legal.
271.Bl -tag -offset indent -width NOCROSSMOUNT -compact
272.It Dv FOLLOW
273Follow symbolic links encountered as the last path component.
274Used by operations that do not address symbolic links directly, e.g.
275.Xr stat 2 .
276Does not affect symbolic links found in the middle of a path.
277Set by the caller.
278Used internally.
279.It Dv NOFOLLOW
280Do not follow symbolic links encountered as the last path component.
281Used by operations that address symbolic links explicitly, such as
282.Xr lstat 2 .
283Set by the caller.
284Used internally.
285Note: the value of
286.Dv NOFOLLOW is 0 ;
287it exists on the grounds that every
288.Nm
289call should explicitly choose either
290.Dv FOLLOW
291or
292.Dv NOFOLLOW .
293.It Dv LOCKLEAF
294Upon successful completion, the resultant named vnode
295.Em ni_vp
296is to be left locked.
297(Otherwise, the vnode is unlocked before
298.Nm
299returns.)
300Set by the caller; used internally.
301.It Dv LOCKPARENT
302Upon successful completion, the parent directory containing the named
303vnode is left locked and returned in
304.Em ni_dvp
305as described above.
306Otherwise,
307.Em ni_dvp
308is set to
309.Dv NULL .
310Set by the caller; used internally.
311.It Dv TRYEMULROOT
312If set, the path is looked up in emulation root of the current process
313first.
314If that fails, the system root is used.
315Set by the caller; used internally.
316.It Dv EMULROOTSET
317As described above, indicates that the caller has set
318.Em ni_erootdir
319prior to calling
320.Nm .
321This is only useful or permitted when the emulation in the
322current process is partway through being set up.
323Set by the caller; used internally.
324.It Dv NOCHROOT
325Bypass normal
326.Xr chroot 8
327handling for absolute paths.
328Set by the caller and used internally.
329.It Dv NOCROSSMOUNT
330Do not cross mount points.
331Set by the caller and used internally.
332.It Dv RDONLY
333Enforce read-only behavior.
334Set by the caller and used internally.
335May also be used by file-system-level vnode functions.
336.It Dv DOWHITEOUT
337Allow whiteouts to be seen as objects instead of functioning as
338.Dq nothing there .
339Set by the caller; used by vnode functions.
340.It Dv ISWHITEOUT
341The current path component is a whiteout.
342Set by
343.Xr VOP_LOOKUP 9
344implementations and consumed by other vnode functions and the
345.Xr namecache 9 .
346.It Dv ISDOTDOT
347The current pathname component is ``..''.
348Set internally; used by vnode operations.
349.It Dv ISLASTCN
350The current path component is the last component found in the
351pathname.
352Set internally; used by vnode functions.
353.It Dv REQUIREDIR
354The current object to be looked up must be a directory.
355Set and used internally; any external references are abusive.
356.It Dv CREATEDIR
357Accept slashes after a component name that does not exist.
358This only makes sense in
359.Dv CREATE
360mode and when creating a directory.
361Set by the caller and used internally.
362.It Dv NOCACHE
363The name looked up should not be entered in the
364.Xr namecache 9 .
365Set and used internally.
366(Currently sometimes set by callers, but most likely this is
367improper/incorrect.)
368May also be used by file-system-level vnode functions.
369.It Dv MAKEENTRY
370The current pathname component should be added to the
371.Xr namecache 9 .
372Set and used internally.
373Also abused by the
374.Xr nfs 4
375code.
376.El
377.Pp
378The following additional historic flags have been removed from
379.Nx
380and should be handled as follows if porting code from elsewhere:
381.Bl -tag -offset indent -width NOCROSSMOUNT -compact
382.It Dv INRENAME
383Part of a misbegotten and incorrect locking scheme.
384Any file-system-level code using this is presumptively incorrect.
385File systems should use the
386.Xr genfs_rename 9
387interface to handle locking in
388.Fn VOP_RENAME .
389.It Dv INRELOOKUP
390Used at one point for signaling to
391.Xr puffs 3
392to work around a protocol deficiency that was later rectified.
393.It Dv ISSYMLINK
394Useless internal state.
395.It Dv SAVESTART
396Unclean setting affect vnode reference counting.
397Now effectively never in effect.
398Any code referring to this is suspect.
399.It Dv SAVENAME
400Unclean setting relating to responsibility for freeing pathname buffers
401in the days before the
402.Em pathbuf
403structure.
404Now effectively always in effect; the caller of
405.Nm
406owns the
407.Em pathbuf
408structure and is always responsible for destroying it.
409.It Dv HASBUF
410Related to SAVENAME.
411Any uses can be replaced with
412.Dq true .
413.El
414All access to the
415.Nm
416interface must be in process context.
417Pathname lookups cannot be done in interrupt context.
418.Sh FUNCTIONS
419.Bl -tag -width compact
420.It Fn NDINIT "ndp" "op" "flags" "pathbuf"
421Initialise a nameidata structure pointed to by
422.Fa ndp
423for use by the
424.Nm
425interface.
426The operating mode and flags (as documented above) are specified by
427.Fa op
428and
429.Fa flags
430respectively.
431The pathname is passed as a pathbuf structure, which should be
432initialized using one of the
433.Xr pathbuf 9
434operations.
435Destroying the pathbuf is the responsibility of the caller; this must
436not be done until the caller is finished with all of the
437.Nm
438results and all of the nameidata contents except for the result vnode.
439.Pp
440This routine stores the credentials of the calling thread
441.Va ( curlwp )
442in
443.Fa ndp .
444.Fn NDINIT
445sets the credentials using
446.Xr kauth_cred_get 9 .
447In the rare case that another set of credentials is required for the
448namei operation,
449.Em ndp-\*[Gt]ni_cnd.cn_cred
450must be set manually after
451.Fn NDINIT .
452.It Fn NDAT "ndp" "dvp"
453This macro is used after
454.Fn NDINIT
455to set the starting directory.
456This supersedes the current process's current working directory as the
457initial point of departure for looking up relative paths.
458This mechanism is used by
459.Xr openat 2
460and related calls.
461.It Fn namei "ndp"
462Convert a pathname into a pointer to a vnode.
463The nameidata structure pointed to by
464.Fa ndp
465should be initialized with the
466.Fn NDINIT
467macro, and perhaps also the
468.Fn NDAT
469macro.
470Direct initialization of members of struct nameidata is
471.Em not
472supported and may (will) break silently in the future.
473.Pp
474The vnode for the pathname is returned in
475.Em ndp-\*[Gt]ni_vp .
476The parent directory is returned locked in
477.Em ndp-\*[Gt]ni_dvp
478iff
479.Dv LOCKPARENT
480is specified.
481.Pp
482Any or all of the flags documented above as set by the caller can be
483enabled by passing them (OR'd together) as the
484.Fa flags
485argument of
486.Fn NDINIT .
487As discussed above every such call should explicitly contain either
488.Dv FOLLOW
489or
490.Dv NOFOLLOW
491to control the behavior regarding final symbolic links.
492.It Fn namei_simple_kernel "path" "sflags" "ret"
493Look up the path
494.Fa path
495and translate it to a vnode, returned in
496.Fa ret .
497The
498.Fa path
499argument must be a kernel
500.Pq Dv UIO_SYSSPACE
501pointer.
502The
503.Fa sflags
504argument chooses the precise behavior.
505It may be set to one of the following symbols:
506.Bl -tag -offset indent -width NSM_NOFOLLOW_TRYEMULROOT -compact
507.It Dv NSM_NOFOLLOW_NOEMULROOT
508.It Dv NSM_NOFOLLOW_TRYEMULROOT
509.It Dv NSM_FOLLOW_NOEMULROOT
510.It Dv NSM_FOLLOW_TRYEMULROOT
511.El
512These select (or not) the
513.Dv FOLLOW/NOFOLLOW
514and
515.Dv TRYEMULROOT
516flags.
517Other flags are not available through this interface, which is
518nonetheless sufficient for more than half the
519.Fn namei
520usage in the kernel.
521Note that the encoding of
522.Fa sflags
523has deliberately been arranged to be type-incompatible with anything
524else.
525This prevents various possible accidents while the
526.Fn namei
527interface is being rototilled.
528.It Fn namei_simple_user "path" "sflags" "ret"
529This function is the same as
530.Fn namei_simple_kernel
531except that the
532.Fa path
533argument shall be a user pointer
534.Pq Dv UIO_USERSPACE
535rather than a kernel pointer.
536.It Fn relookup "dvp" "vpp" "cnp"
537Reacquire a path name component is a directory.
538This is a quicker way to lookup a pathname component when the parent
539directory is known.
540The locked parent directory vnode is specified by
541.Fa dvp
542and the pathname component by
543.Fa cnp .
544The vnode of the pathname is returned in the address specified by
545.Fa vpp .
546Note that one may only use
547.Fn relookup
548to repeat a lookup of a final path component previously done by
549.Nm ,
550and one must use the same
551.Em componentname
552structure that call produced.
553Otherwise the behavior is undefined and likely adverse.
554.It Fn lookup_for_nfsd "ndp" "startdir" "neverfollow"
555This is a private entry point into
556.Nm
557used by the NFS server code.
558It looks up a path starting from
559.Fa startdir .
560If
561.Fa neverfollow
562is set,
563.Em any
564symbolic link (not just at the end of the path) will cause an error.
565Otherwise, it follows symlinks normally.
566It should not be used by new code.
567.It Fn lookup_for_nfsd_index "ndp"
568This is a (second) private entry point into
569.Nm
570used by the NFS server code.
571It looks up a single path component.
572It should not be used by new code.
573.El
574.Sh INTERNALS
575The
576.Em nameidata
577structure has the following layout:
578.Bd -literal
579struct nameidata {
580	/*
581	 * Arguments to namei.
582	 */
583	struct vnode *ni_atdir;		/* startup dir, cwd if null */
584	struct pathbuf *ni_pathbuf;	/* pathname container */
585	char *ni_pnbuf;			/* extra pathname buffer ref (XXX) */
586	/*
587	 * Internal starting state. (But see notes.)
588	 */
589	struct	vnode *ni_rootdir;	/* logical root directory */
590	struct	vnode *ni_erootdir;	/* emulation root directory */
591	/*
592	 * Results from namei.
593	 */
594	struct	vnode *ni_vp;		/* vnode of result */
595	struct	vnode *ni_dvp;		/* vnode of intermediate directory */
596	/*
597	 * Internal current state.
598	 */
599	size_t		ni_pathlen;	/* remaining chars in path */
600	const char	*ni_next;	/* next location in pathname */
601	unsigned int	ni_loopcnt;	/* count of symlinks encountered */
602	/*
603	 * Lookup parameters: this structure describes the subset of
604	 * information from the nameidata structure that is passed
605	 * through the VOP interface.
606	 */
607	struct componentname ni_cnd;
608};
609.Ed
610.Pp
611These fields are:
612.Bl -tag -offset indent -width ni_erootdirx -compact
613.It ni_atdir
614The directory to use for the starting point of relative paths.
615If null, the current process's current directory is used.
616This is initialized to
617.Dv NULL
618by
619.Fn NDINIT
620and set by
621.Fn NDAT .
622.It ni_pathbuf
623The abstract path buffer in use, passed as an argument to
624.Fn NDINIT .
625The name pointers that appear elsewhere, such as in the
626.Em componentname
627structure, point into this buffer.
628It is owned by the caller and must not be destroyed until all
629.Nm
630operations are complete.
631See
632.Xr pathbuf 9 .
633.It ni_pnbuf
634This is the name pointer used during
635.Nm .
636It points into
637.Fa ni_pathbuf .
638It is not initialized until entry into
639.Nm .
640.It ni_rootdir
641The root directory to use as the starting point for absolute paths.
642This is retrieved from the current process's current root directory
643when
644.Nm
645starts up.
646It is not initialized by
647.Fn NDINIT .
648.It ni_erootdir
649The root directory to use as the emulation root, for processes running
650in emulation.
651This is retrieved from the current process's emulation root directory
652when
653.Nm
654starts up and not initialized by
655.Fn NDINIT .
656As described elsewhere, it may be set by the caller if the
657.Dv EMULROOTSET
658flag is used, but this should only be done when the current process's
659emulation root directory is not yet initialized.
660(And ideally in the future things would be tidied so that this is not
661necessary.)
662.It ni_vp
663.It ni_dvp
664Returned vnodes, as described above.
665These only contain valid values if
666.Nm
667returns successfully.
668.It ni_pathlen
669The length of the full current remaining path string in
670.Fa ni_pnbuf .
671This is not initialized by
672.Fn NDINIT
673and is used only internally.
674.It ni_next
675The remaining part of the path, after the current component found in
676the
677.Em componentname
678structure.
679This is not initialized by
680.Fn NDINIT
681and is used only internally.
682.It ni_loopcnt
683The number of symbolic links encountered (and traversed) so far.
684If this exceeds a limit,
685.Nm
686fails with
687.Er ELOOP .
688This is not initialized by
689.Fn NDINIT
690and is used only internally.
691.It ni_cnd
692The
693.Em componentname
694structure holding the current directory component, and also the
695mode, flags, and credentials.
696The mode, flags, and credentials are initialized by
697.Fn NDINIT ;
698the rest is not initialized until
699.Nm
700runs.
701.El
702.Pp
703There is also a
704.Em namei_state
705structure that is hidden within
706.Pa vfs_lookup.c .
707This contains the following additional state:
708.Bl -tag -offset indent -width attempt_retry -compact
709.It docache
710A flag indicating whether to cache the last pathname component.
711.It rdonly
712The read-only state, initialized from the
713.Dv RDONLY
714flag.
715.It slashes
716The number of trailing slashes found after the current pathname
717component.
718.It attempt_retry
719Set on some error cases (and not others) to indicate that a failure in
720the emulation root should be followed by a retry in the real system
721root.
722.El
723.Pp
724The state in
725.Em namei_state
726is genuinely private to
727.Nm .
728Note that much of the state in
729.Em nameidata
730should also be private, but is currently not because it is misused in
731some fashion by outside code, usually
732.Xr nfs 4 .
733.Pp
734The control flow within the
735.Nm
736portions of
737.Pa vfs_lookup.c
738is as follows.
739.Bl -tag
740.It Fn namei
741does a complete path lookup by calling
742.Fn namei_init ,
743.Fn namei_tryemulroot ,
744and
745.Fn namei_cleanup .
746.It Fn namei_init
747sets up the basic internal state and makes some (precondition-type)
748assertions.
749.It Fn namei_cleanup
750makes some postcondition-type assertions; it currently does nothing
751besides this.
752.It Fn namei_tryemulroot
753handles
754.Dv TRYEMULROOT
755by calling
756.Fn namei_oneroot
757once or twice as needed, and attends to making sure the original
758pathname is preserved for the second try.
759.It Fn namei_oneroot
760does a complete path search from a single root directory.
761It begins with
762.Fn namei_start ,
763then calls
764.Fn lookup_once
765(and if necessary,
766.Fn namei_follow )
767repeatedly until done.
768It also handles returning the result vnode(s) in the requested state.
769.It Fn namei_start
770sets up the initial state and locking; it calls
771.Fn namei_getstartdir .
772.It Fn namei_getstartdir
773initializes the root directory state (both
774.Fa ni_rootdir
775and
776.Fa ni_erootdir )
777and picks the starting directory, consuming the leading slashes of an
778absolute path and handling the magic
779.Dq /../
780string for bypassing the emulation root.
781A different version
782.Fn namei_getstartdir_for_nfsd
783is used for lookups coming from
784.Xr nfsd 8
785as those are required to have different semantics.
786.It Fn lookup_once
787calls
788.Fn VOP_LOOKUP
789for one path component, also handling any needed crossing of mount
790points (either up or down) and coping with locking requirements.
791.It Fn lookup_parsepath
792is called prior to each
793.Fn lookup_once
794call to examine the pathname and find where the next component
795starts.
796.It Fn namei_follow
797reads the contents of a symbolic link and updates both the path buffer
798and the search directory accordingly.
799.El
800.Pp
801As a final note be advised that the magic return value associated with
802.Dv CREATE
803mode is different for
804.Nm
805than it is for
806.Fn VOP_LOOKUP .
807The latter
808.Dq fails
809with
810.Er EJUSTRETURN .
811.Nm
812translates this into succeeding and returning a null vnode.
813.Sh CODE REFERENCES
814The name lookup subsystem is implemented within the file
815.Pa sys/kern/vfs_lookup.c .
816.Sh SEE ALSO
817.Xr intro 9 ,
818.Xr namecache 9 ,
819.Xr vfs 9 ,
820.Xr vnode 9 ,
821.Xr vnodeops 9
822.Sh BUGS
823There should be no such thing as operating modes.
824Only
825.Dv LOOKUP
826is actually needed.
827The behavior where removing an object looks it up within
828.Nm
829and then calls into the file system (which must look it up again
830internally or cache state from
831.Fn VOP_LOOKUP )
832is particularly contorted.
833.Pp
834Most of the flags are equally bogus.
835.Pp
836Most of the contents of the
837.Em nameidata
838structure should be private and hidden within
839.Nm ;
840currently it cannot be because of abuse elsewhere.
841.Pp
842The
843.Dv EMULROOTSET
844flag is messy.
845.Pp
846There is no good way to support file systems that want to use
847a more elaborate pathname schema than the customary slash-delimited
848components.
849