xref: /netbsd-src/share/man/man9/namei.9 (revision ca8f8e9eb0c5c319fbb6a9c046ff3507d1d52269)
1.\"     $NetBSD: namei.9,v 1.52 2021/12/26 16:41:09 andvar Exp $
2.\"
3.\" Copyright (c) 2001, 2005, 2006, 2017 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 5, 2019
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" "int dummy"
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" "struct vnode *startdir"
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
79All access to the
80.Nm
81interface must be in process context.
82Pathname lookups cannot be done in interrupt context.
83.Pp
84In the general form of
85.Nm ,
86a caller must:
87.Bl -enum -compact
88.It
89Allocate storage for a
90.Ft struct nameidata
91object
92.Fa nd .
93.It
94Initialize
95.Fa nd
96with
97.Fn NDINIT
98and optionally
99.Fn NDAT
100to specify the arguments to a lookup.
101.It
102Call
103.Fn namei
104and handle failure if it returns a nonzero error code.
105.It
106Read the resulting vnode out of
107.Fa nd Ns Li .ni_vp .
108If requested with
109.Dv LOCKPARENT ,
110read the directory vnode out of
111.Fa nd Ns Li .ni_dvp .
112.It
113For directory operations, use the
114.Ft struct componentname
115object stored at
116.Fa nd Ns Li .ni_cnd .
117.El
118.Pp
119The other fields of
120.Ft struct nameidata
121should not be examined or altered directly.
122.Pp
123Note that the
124.Xr nfs 4
125code misuses
126.Ft struct nameidata
127and currently has an incestuous relationship with the
128.Nm
129code.
130This is gradually being cleaned up.
131.Pp
132The
133.Ft struct componentname
134type has the following layout:
135.Bd -literal
136struct componentname {
137	/*
138	 * Arguments to VOP_LOOKUP and directory VOP routines.
139	 */
140	uint32_t	cn_nameiop;	/* namei operation */
141	uint32_t	cn_flags;	/* flags to namei */
142	kauth_cred_t 	cn_cred;	/* credentials */
143	const char 	*cn_nameptr;	/* pointer to looked up name */
144	size_t		cn_namelen;	/* length of looked up comp */
145	/*
146	 * Side result from VOP_LOOKUP.
147	 */
148	size_t		cn_consume;	/* chars to consume in lookup */
149};
150.Ed
151.Pp
152This structure contains the information about a single directory
153component name, along with certain other information required by vnode
154operations.
155See
156.Xr vnodeops 9
157for more information about these vnode operations.
158.Pp
159The members:
160.Bl -tag -offset indent -width cn_consumexx -compact
161.It cn_nameiop
162The type of operation in progress; indicates the basic operating mode
163of namei.
164May be one of
165.Dv LOOKUP ,
166.Dv CREATE ,
167.Dv DELETE ,
168or
169.Dv RENAME .
170These modes are described below.
171.It cn_flags
172Additional flags affecting the operation of namei.
173These are described below as well.
174.It cn_cred
175The credentials to use for the lookup or other operation the
176.Em componentname
177is passed to.
178This may match the credentials of the current process or it may not,
179depending on where the original operation request came from and how it
180has been routed.
181.It cn_nameptr
182The name of this directory component, followed by the rest of the path
183being looked up.
184.It cn_namelen
185The length of the name of this directory component.
186The name is not in general null terminated, although the complete
187string (the full remaining path) always is.
188.It cn_consume
189This field starts at zero; it may be set to a larger value by
190implementations of
191.Xr VOP_LOOKUP 9
192to indicate how many more characters beyond
193.Em cn_namelen
194are being consumed.
195New uses of this feature are discouraged and should be discussed.
196.El
197.Ss Operating modes
198Each lookup happens in one of the following modes, specified by
199callers of
200.Nm
201with
202.Fn NDINIT
203and specified internally by
204.Nm
205to
206.Xr VOP_LOOKUP 9 :
207.Bl -bullet -compact
208.It
209Callers of
210.Nm
211specify the mode for the last component of a lookup.
212.It
213Internally,
214.Nm
215recursively calls
216.Xr VOP_LOOKUP 9
217in
218.Dv LOOKUP
219mode for each directory component, and then finally calls
220.Xr VOP_LOOKUP 9
221in the caller-specified mode for the last component.
222.El
223Each mode can fail in different ways \(em for example,
224.Dv LOOKUP
225mode fails with
226.Er ENOENT
227if no entry exists, but
228.Dv CREATE
229mode succeeds with a
230.Dv NULL
231vnode.
232.Bl -tag -width LOOKUP
233.It Dv LOOKUP
234Yield the vnode for an existing entry.
235Callers specify
236.Dv LOOKUP
237for operations on existing vnodes:
238.Xr stat 2 ,
239.Xr open 2
240without
241.Dv O_CREATE ,
242etc.
243.Pp
244File systems:
245.Bl -dash -compact
246.It
247MUST refuse if user lacks lookup permission for directory.
248.It
249SHOULD use
250.Xr namecache 9
251to cache lookup results.
252.El
253.Pp
254.Bl -tag -compact -width ENAMETOOLONG
255.It Bq Er ENOENT
256No entry exists.
257.El
258.It Dv CREATE
259Yield the vnode for an existing entry; or, if there is none, yield
260.Dv NULL
261and hint that it will soon be created.
262Callers specify
263.Dv CREATE
264for operations that may create directory entries:
265.Xr mkdir 2 ,
266.Xr open 2
267with
268.Dv O_CREATE ,
269etc.
270.Pp
271File systems:
272.Bl -dash -compact
273.It
274MUST refuse if user lacks lookup permission for directory.
275.It
276MUST refuse if no entry exists and user lacks write permission for
277directory.
278.It
279MUST refuse if no entry exists and file system is read-only.
280.It
281SHOULD NOT use
282.Xr namecache 9
283to cache negative lookup results.
284.It
285SHOULD save lookup hints internally in the directory for a subsequent
286operation to create a directory entry.
287.El
288.Pp
289.Bl -tag -compact -width ENAMETOOLONG
290.It Bq Er EPERM
291The user lacks lookup permission for the directory.
292.It Bq Er EPERM
293No entry exists and the user lacks write permission for the directory.
294.It Bq Er EROFS
295No entry exists and the file system is read-only.
296.El
297.It Dv DELETE
298Yield the vnode of an existing entry, and hint that it will soon be
299deleted.
300Callers specify
301.Dv DELETE
302for operations that delete directory entries:
303.Xr unlink 2 ,
304.Xr rmdir 2 ,
305etc.
306.Pp
307File systems:
308.Bl -dash -compact
309.It
310MUST refuse if user lacks lookup permission for directory.
311.It
312MUST refuse if entry exists and user lacks write permission for
313directory.
314.It
315MUST refuse if entry exists and file system is read-only.
316.It
317SHOULD NOT use
318.Xr namecache 9
319to cache lookup results.
320.It
321SHOULD save lookup hints internally in the directory for a subsequent
322operation to delete a directory entry.
323.El
324.Pp
325.Bl -tag -compact -width ENAMETOOLONG
326.It Bq Er ENOENT
327No entry exists.
328.It Bq Er EPERM
329The user lacks lookup permission for the directory.
330.It Bq Er EPERM
331An entry exists and the user lacks write permission for the directory.
332.It Bq Er EROFS
333An entry exists and the file system is read-only.
334.El
335.It Dv RENAME
336Yield the vnode of an existing entry, and hint that it will soon be
337overwritten; or, if there is none, yield
338.Dv NULL ,
339and hint that it will soon be created.
340.Pp
341Callers specify
342.Dv RENAME
343for an entry that is about to be created or overwritten, namely for the
344target of
345.Xr rename 2 .
346.Pp
347File systems:
348.Bl -dash -compact
349.It
350MUST refuse if user lacks lookup permission for directory.
351.It
352MUST refuse if user lacks write permission for directory.
353.It
354MUST refuse if file system is read-only.
355.It
356SHOULD NOT use
357.Xr namecache 9
358to cache lookup results.
359.It
360SHOULD save lookup hints internally in the directory for a subsequent
361operation to create or overwrite a directory entry.
362.El
363.Pp
364.Bl -tag -compact -width ENAMETOOLONG
365.It Bq Er EPERM
366The user lacks lookup permission for the directory.
367.It Bq Er EPERM
368The user lacks write permission for the directory.
369.It Bq Er EROFS
370The file system is read-only.
371.El
372.El
373.Pp
374If a caller decides not to perform an operation it hinted at by a
375destructive operating mode
376.Pq Dv CREATE , Dv DELETE , No or Dv RENAME ,
377it SHOULD call
378.Xr VOP_ABORTOP 9
379to release the hints.
380If a file system fails to perform such an operation, it SHOULD call
381.Xr VOP_ABORTOP 9
382to release the hints.
383However, the current code is inconsistent about this, and every
384implementation of
385.Xr VOP_ABORTOP 9
386does nothing.
387.Ss Flags
388The following flags may be specified by
389.Em callers
390of
391.Nm ,
392and MUST NOT be used by file systems:
393.Bl -tag -width NOCROSSMOUNT
394.It Dv FOLLOW
395Follow symbolic links in the last path component.
396Used by operations that do not address symbolic links directly, such as
397.Xr stat 2 .
398(Does not affect symbolic links found in the middle of a path.)
399.It Dv NOFOLLOW
400Do not follow symbolic links in the last path component.
401Used by operations that address symbolic links directly, such as
402.Xr lstat 2 .
403.Pp
404Note: The value of
405.Dv NOFOLLOW
406is 0.
407We define the constant to let callers say either
408.Dv FOLLOW
409or
410.Dv NOFOLLOW
411explicitly.
412.It Dv LOCKLEAF
413On successful lookup, lock the vnode, if any, in
414.Fa ndp Ns Li ->ni_vp .
415Without this flag, it would be unlocked.
416.It Dv LOCKPARENT
417On successful lookup, lock and return the directory vnode in
418.Fa ndp Ns Li ->ni_dvp .
419Without this flag, it is not returned at all.
420.It Dv TRYEMULROOT
421If set, the path is looked up in the emulation root of the current
422process first.
423If that fails, the system root is used.
424.It Dv EMULROOTSET
425Indicates that the caller has set
426.Fa ndp Ns Li ->ni_erootdir
427prior to calling
428.Nm .
429This is only useful or permitted when the emulation in the current
430process is partway through being set up.
431.It Dv NOCHROOT
432Bypass normal
433.Xr chroot 8
434handling for absolute paths.
435.It Dv NOCROSSMOUNT
436Do not cross mount points.
437.It Dv RDONLY
438Enforce read-only behavior.
439.It Dv CREATEDIR
440Accept slashes after a component name that does not exist.
441This only makes sense in
442.Dv CREATE
443mode and when creating a directory.
444.It Dv NOCACHE
445Do not cache the lookup result for the last component name.
446This is used only with the
447.Dv RENAME
448mode for the target; the cache entry would be invalidated immediately.
449.El
450.Pp
451The following flag may be set by a caller of
452.Nm
453and tested by a file system in
454.Xr VOP_LOOKUP 9
455or other subsequent directory operations:
456.Bl -tag -width NOCROSSMOUNT
457.It Dv DOWHITEOUT
458Allow whiteouts to be seen as objects instead of functioning as
459.Dq nothing there .
460.El
461.Pp
462The following flags are set by namei for calling
463.Xr VOP_LOOKUP 9 :
464.Bl -tag -width NOCROSSMOUNT
465.It Dv ISDOTDOT
466The current pathname component is
467.Dq Li .. .
468May be tested by subsequent directory operations too.
469.It Dv ISLASTCN
470The current pathname component is the last component found in the
471pathname.
472Guaranteed to remain set in subsequent directory operations.
473.It Dv REQUIREDIR
474The current object to be looked up must be a directory.
475May not be used by subsequent directory operations.
476.It Dv MAKEENTRY
477The lookup result for the current pathname component should be added to
478the
479.Xr namecache 9 .
480May be used to make additional caching decisions, e.g. to store an
481mtime for determining whether our cache for a remote vnode is stale.
482May not be used by subsequent directory operations.
483.El
484.Pp
485A file system may set the following flag on return from
486.Xr VOP_LOOKUP 9
487for use by
488.Nm ,
489.Xr namecache 9 ,
490and subsequent directory operations:
491.Bl -tag -width NOCROSSMOUNT
492.It Dv ISWHITEOUT
493The object at the current pathname component is a whiteout.
494.El
495.Pp
496The following additional historic flags have been removed from
497.Nx
498and should be handled as follows if porting code from elsewhere:
499.Bl -tag -width NOCROSSMOUNT
500.It Dv INRENAME
501Part of a misbegotten and incorrect locking scheme.
502Any file-system-level code using this is presumptively incorrect.
503File systems should use the
504.Xr genfs_rename 9
505interface to handle locking in
506.Fn VOP_RENAME .
507.It Dv INRELOOKUP
508Used at one point for signaling to
509.Xr puffs 3
510to work around a protocol deficiency that was later rectified.
511.It Dv ISSYMLINK
512Useless internal state.
513.It Dv SAVESTART
514Unclean setting affect vnode reference counting.
515Now effectively never in effect.
516Any code referring to this is suspect.
517.It Dv SAVENAME
518Unclean setting relating to responsibility for freeing pathname buffers
519in the days before the
520.Em pathbuf
521structure.
522Now effectively always in effect; the caller of
523.Nm
524owns the
525.Em pathbuf
526structure and is always responsible for destroying it.
527.It Dv HASBUF
528Related to SAVENAME.
529Any uses can be replaced with
530.Dq true .
531.El
532.Sh FUNCTIONS
533.Bl -tag -width abcd
534.It Fn NDINIT "ndp" "op" "flags" "pathbuf"
535Initialise a nameidata structure pointed to by
536.Fa ndp
537for use by the
538.Nm
539interface.
540The operating mode and flags (as documented above) are specified by
541.Fa op
542and
543.Fa flags
544respectively.
545The pathname is passed as a pathbuf structure, which should be
546initialized using one of the
547.Xr pathbuf 9
548operations.
549Destroying the pathbuf is the responsibility of the caller; this must
550not be done until the caller is finished with all of the
551.Nm
552results and all of the nameidata contents except for the result vnode.
553.Pp
554This routine stores the credentials of the calling thread
555.Va ( curlwp )
556in
557.Fa ndp .
558.Fn NDINIT
559sets the credentials using
560.Xr kauth_cred_get 9 .
561In the rare case that another set of credentials is required for the
562namei operation,
563.Em ndp->ni_cnd.cn_cred
564must be set manually after
565.Fn NDINIT .
566.It Fn NDAT "ndp" "dvp"
567This macro is used after
568.Fn NDINIT
569to set the starting directory.
570This supersedes the current process's current working directory as the
571initial point of departure for looking up relative paths.
572This mechanism is used by
573.Xr openat 2
574and related calls.
575.It Fn namei "ndp"
576Convert a pathname into a pointer to a vnode.
577The nameidata structure pointed to by
578.Fa ndp
579should be initialized with the
580.Fn NDINIT
581macro, and perhaps also the
582.Fn NDAT
583macro.
584Direct initialization of members of struct nameidata is
585.Em not
586supported and may (will) break silently in the future.
587.Pp
588The vnode for the pathname is returned in
589.Em ndp->ni_vp .
590The parent directory is returned locked in
591.Em ndp->ni_dvp
592iff
593.Dv LOCKPARENT
594is specified.
595.Pp
596Any or all of the flags documented above as set by the caller can be
597enabled by passing them (OR'd together) as the
598.Fa flags
599argument of
600.Fn NDINIT .
601As discussed above every such call should explicitly contain either
602.Dv FOLLOW
603or
604.Dv NOFOLLOW
605to control the behavior regarding final symbolic links.
606.It Fn namei_simple_kernel "path" "sflags" "ret"
607Look up the path
608.Fa path
609and translate it to a vnode, returned in
610.Fa ret .
611The
612.Fa path
613argument must be a kernel
614.Pq Dv UIO_SYSSPACE
615pointer.
616The
617.Fa sflags
618argument chooses the precise behavior.
619It may be set to one of the following symbols:
620.Bl -tag -offset indent -width NSM_NOFOLLOW_TRYEMULROOT -compact
621.It Dv NSM_NOFOLLOW_NOEMULROOT
622.It Dv NSM_NOFOLLOW_TRYEMULROOT
623.It Dv NSM_FOLLOW_NOEMULROOT
624.It Dv NSM_FOLLOW_TRYEMULROOT
625.El
626These select (or not) the
627.Dv FOLLOW/NOFOLLOW
628and
629.Dv TRYEMULROOT
630flags.
631Other flags are not available through this interface, which is
632nonetheless sufficient for more than half the
633.Fn namei
634usage in the kernel.
635Note that the encoding of
636.Fa sflags
637has deliberately been arranged to be type-incompatible with anything
638else.
639This prevents various possible accidents while the
640.Fn namei
641interface is being rototilled.
642.It Fn namei_simple_user "path" "sflags" "ret"
643This function is the same as
644.Fn namei_simple_kernel
645except that the
646.Fa path
647argument shall be a user pointer
648.Pq Dv UIO_USERSPACE
649rather than a kernel pointer.
650.It Fn relookup "dvp" "vpp" "cnp" "dummy"
651Reacquire a path name component is a directory.
652This is a quicker way to lookup a pathname component when the parent
653directory is known.
654The locked parent directory vnode is specified by
655.Fa dvp
656and the pathname component by
657.Fa cnp .
658The vnode of the pathname is returned in the address specified by
659.Fa vpp .
660The
661.Fa dummy
662argument is unused.
663Note that one may only use
664.Fn relookup
665to repeat a lookup of a final path component previously done by
666.Nm ,
667and one must use the same
668.Em componentname
669structure that call produced.
670Otherwise the behavior is undefined and likely adverse.
671.It Fn lookup_for_nfsd "ndp" "startdir" "neverfollow"
672This is a private entry point into
673.Nm
674used by the NFS server code.
675It looks up a path starting from
676.Fa startdir .
677If
678.Fa neverfollow
679is set,
680.Em any
681symbolic link (not just at the end of the path) will cause an error.
682Otherwise, it follows symlinks normally.
683It should not be used by new code.
684.It Fn lookup_for_nfsd_index "ndp" "startdir"
685This is a (second) private entry point into
686.Nm
687used by the NFS server code.
688It looks up a single path component starting from
689.Fa startdir .
690It should not be used by new code.
691.El
692.Sh INTERNALS
693The
694.Em nameidata
695structure has the following layout:
696.Bd -literal
697struct nameidata {
698	/*
699	 * Arguments to namei.
700	 */
701	struct vnode *ni_atdir;		/* startup dir, cwd if null */
702	struct pathbuf *ni_pathbuf;	/* pathname container */
703	char *ni_pnbuf;			/* extra pathname buffer ref (XXX) */
704	/*
705	 * Internal starting state. (But see notes.)
706	 */
707	struct	vnode *ni_rootdir;	/* logical root directory */
708	struct	vnode *ni_erootdir;	/* emulation root directory */
709	/*
710	 * Results from namei.
711	 */
712	struct	vnode *ni_vp;		/* vnode of result */
713	struct	vnode *ni_dvp;		/* vnode of intermediate directory */
714	/*
715	 * Internal current state.
716	 */
717	size_t		ni_pathlen;	/* remaining chars in path */
718	const char	*ni_next;	/* next location in pathname */
719	unsigned int	ni_loopcnt;	/* count of symlinks encountered */
720	/*
721	 * Lookup parameters: this structure describes the subset of
722	 * information from the nameidata structure that is passed
723	 * through the VOP interface.
724	 */
725	struct componentname ni_cnd;
726};
727.Ed
728.Pp
729These fields are:
730.Bl -tag -offset indent -width ni_erootdirx -compact
731.It ni_atdir
732The directory to use for the starting point of relative paths.
733If null, the current process's current directory is used.
734This is initialized to
735.Dv NULL
736by
737.Fn NDINIT
738and set by
739.Fn NDAT .
740.It ni_pathbuf
741The abstract path buffer in use, passed as an argument to
742.Fn NDINIT .
743The name pointers that appear elsewhere, such as in the
744.Em componentname
745structure, point into this buffer.
746It is owned by the caller and must not be destroyed until all
747.Nm
748operations are complete.
749See
750.Xr pathbuf 9 .
751.It ni_pnbuf
752This is the name pointer used during
753.Nm .
754It points into
755.Fa ni_pathbuf .
756It is not initialized until entry into
757.Nm .
758.It ni_rootdir
759The root directory to use as the starting point for absolute paths.
760This is retrieved from the current process's current root directory
761when
762.Nm
763starts up.
764It is not initialized by
765.Fn NDINIT .
766.It ni_erootdir
767The root directory to use as the emulation root, for processes running
768in emulation.
769This is retrieved from the current process's emulation root directory
770when
771.Nm
772starts up and not initialized by
773.Fn NDINIT .
774As described elsewhere, it may be set by the caller if the
775.Dv EMULROOTSET
776flag is used, but this should only be done when the current process's
777emulation root directory is not yet initialized.
778(And ideally in the future things would be tidied so that this is not
779necessary.)
780.It ni_vp
781.It ni_dvp
782Returned vnodes, as described above.
783These only contain valid values if
784.Nm
785returns successfully.
786.It ni_pathlen
787The length of the full current remaining path string in
788.Fa ni_pnbuf .
789This is not initialized by
790.Fn NDINIT
791and is used only internally.
792.It ni_next
793The remaining part of the path, after the current component found in
794the
795.Em componentname
796structure.
797This is not initialized by
798.Fn NDINIT
799and is used only internally.
800.It ni_loopcnt
801The number of symbolic links encountered (and traversed) so far.
802If this exceeds a limit,
803.Nm
804fails with
805.Er ELOOP .
806This is not initialized by
807.Fn NDINIT
808and is used only internally.
809.It ni_cnd
810The
811.Em componentname
812structure holding the current directory component, and also the
813mode, flags, and credentials.
814The mode, flags, and credentials are initialized by
815.Fn NDINIT ;
816the rest is not initialized until
817.Nm
818runs.
819.El
820.Pp
821There is also a
822.Em namei_state
823structure that is hidden within
824.Pa vfs_lookup.c .
825This contains the following additional state:
826.Bl -tag -offset indent -width attempt_retry -compact
827.It docache
828A flag indicating whether to cache the last pathname component.
829.It rdonly
830The read-only state, initialized from the
831.Dv RDONLY
832flag.
833.It slashes
834The number of trailing slashes found after the current pathname
835component.
836.It attempt_retry
837Set on some error cases (and not others) to indicate that a failure in
838the emulation root should be followed by a retry in the real system
839root.
840.El
841.Pp
842The state in
843.Em namei_state
844is genuinely private to
845.Nm .
846Note that much of the state in
847.Em nameidata
848should also be private, but is currently not because it is misused in
849some fashion by outside code, usually
850.Xr nfs 4 .
851.Pp
852The control flow within the
853.Nm
854portions of
855.Pa vfs_lookup.c
856is as follows.
857.Bl -tag -width namei_tryemulrootXX
858.It Fn namei
859does a complete path lookup by calling
860.Fn namei_init ,
861.Fn namei_tryemulroot ,
862and
863.Fn namei_cleanup .
864.It Fn namei_init
865sets up the basic internal state and makes some (precondition-type)
866assertions.
867.It Fn namei_cleanup
868makes some postcondition-type assertions; it currently does nothing
869besides this.
870.It Fn namei_tryemulroot
871handles
872.Dv TRYEMULROOT
873by calling
874.Fn namei_oneroot
875once or twice as needed, and attends to making sure the original
876pathname is preserved for the second try.
877.It Fn namei_oneroot
878does a complete path search from a single root directory.
879It begins with
880.Fn namei_start ,
881then calls
882.Fn lookup_once
883(and if necessary,
884.Fn namei_follow )
885repeatedly until done.
886It also handles returning the result vnode(s) in the requested state.
887.It Fn namei_start
888sets up the initial state and locking; it calls
889.Fn namei_getstartdir .
890.It Fn namei_getstartdir
891initializes the root directory state (both
892.Fa ni_rootdir
893and
894.Fa ni_erootdir )
895and picks the starting directory, consuming the leading slashes of an
896absolute path and handling the magic
897.Dq /../
898string for bypassing the emulation root.
899A different version
900.Fn namei_getstartdir_for_nfsd
901is used for lookups coming from
902.Xr nfsd 8
903as those are required to have different semantics.
904.It Fn lookup_once
905calls
906.Fn VOP_LOOKUP
907for one path component, also handling any needed crossing of mount
908points (either up or down) and coping with locking requirements.
909.It Fn lookup_parsepath
910is called prior to each
911.Fn lookup_once
912call to examine the pathname and find where the next component
913starts.
914.It Fn namei_follow
915reads the contents of a symbolic link and updates both the path buffer
916and the search directory accordingly.
917.El
918.Pp
919As a final note be advised that the magic return value associated with
920.Dv CREATE
921mode is different for
922.Nm
923than it is for
924.Fn VOP_LOOKUP .
925The latter
926.Dq fails
927with
928.Er EJUSTRETURN .
929.Nm
930translates this into succeeding and returning a null vnode.
931.Sh CODE REFERENCES
932The name lookup subsystem is implemented within the file
933.Pa sys/kern/vfs_lookup.c .
934.Sh SEE ALSO
935.Xr intro 9 ,
936.Xr namecache 9 ,
937.Xr vfs 9 ,
938.Xr vnode 9 ,
939.Xr vnodeops 9
940.Sh BUGS
941There should be no such thing as operating modes.
942Only
943.Dv LOOKUP
944is actually needed.
945The behavior where removing an object looks it up within
946.Nm
947and then calls into the file system (which must look it up again
948internally or cache state from
949.Fn VOP_LOOKUP )
950is particularly contorted.
951.Pp
952Most of the flags are equally bogus.
953.Pp
954Most of the contents of the
955.Em nameidata
956structure should be private and hidden within
957.Nm ;
958currently it cannot be because of abuse elsewhere.
959.Pp
960The
961.Dv EMULROOTSET
962flag is messy.
963.Pp
964There is no good way to support file systems that want to use
965a more elaborate pathname schema than the customary slash-delimited
966components.
967