summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/namei.9
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/namei.9')
-rw-r--r--static/netbsd/man9/namei.9966
1 files changed, 966 insertions, 0 deletions
diff --git a/static/netbsd/man9/namei.9 b/static/netbsd/man9/namei.9
new file mode 100644
index 00000000..c1a86853
--- /dev/null
+++ b/static/netbsd/man9/namei.9
@@ -0,0 +1,966 @@
+.\" $NetBSD: namei.9,v 1.52 2021/12/26 16:41:09 andvar Exp $
+.\"
+.\" Copyright (c) 2001, 2005, 2006, 2017 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Gregory McGarry.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 5, 2019
+.Dt NAMEI 9
+.Os
+.Sh NAME
+.Nm namei ,
+.Nm NDINIT ,
+.Nm NDAT ,
+.Nm namei_simple_kernel ,
+.Nm namei_simple_user ,
+.Nm relookup ,
+.Nm lookup_for_nfsd ,
+.Nm lookup_for_nfsd_index
+.Nd pathname lookup
+.Sh SYNOPSIS
+.In sys/namei.h
+.In sys/uio.h
+.In sys/vnode.h
+.Fn NDINIT "struct nameidata *ndp" "u_long op" "u_long flags" \
+"struct pathbuf *pathbuf"
+.Fn NDAT "struct nameidata *ndp" "struct vnode *dvp"
+.Ft int
+.Fn namei "struct nameidata *ndp"
+.Ft int
+.Fn namei_simple_kernel "const char *path" "namei_simple_flags_t sflags" \
+"struct vnode **ret"
+.Ft int
+.Fn namei_simple_user "const char *path" "namei_simple_flags_t sflags" \
+"struct vnode **ret"
+.Ft int
+.Fn relookup "struct vnode *dvp" "struct vnode **vpp" \
+"struct componentname *cnp" "int dummy"
+.Ft int
+.Fn lookup_for_nfsd "struct nameidata *ndp" "struct vnode *startdir" \
+"int neverfollow"
+.Ft int
+.Fn lookup_for_nfsd_index "struct nameidata *ndp" "struct vnode *startdir"
+.Sh DESCRIPTION
+The
+.Nm
+interface is used to convert pathnames to file system vnodes.
+The
+name of the interface is actually a contraction of the words
+.Em name
+and
+.Em inode
+for name-to-inode conversion, in the days before the
+.Xr vfs 9
+interface was implemented.
+.Pp
+All access to the
+.Nm
+interface must be in process context.
+Pathname lookups cannot be done in interrupt context.
+.Pp
+In the general form of
+.Nm ,
+a caller must:
+.Bl -enum -compact
+.It
+Allocate storage for a
+.Ft struct nameidata
+object
+.Fa nd .
+.It
+Initialize
+.Fa nd
+with
+.Fn NDINIT
+and optionally
+.Fn NDAT
+to specify the arguments to a lookup.
+.It
+Call
+.Fn namei
+and handle failure if it returns a nonzero error code.
+.It
+Read the resulting vnode out of
+.Fa nd Ns Li .ni_vp .
+If requested with
+.Dv LOCKPARENT ,
+read the directory vnode out of
+.Fa nd Ns Li .ni_dvp .
+.It
+For directory operations, use the
+.Ft struct componentname
+object stored at
+.Fa nd Ns Li .ni_cnd .
+.El
+.Pp
+The other fields of
+.Ft struct nameidata
+should not be examined or altered directly.
+.Pp
+Note that the
+.Xr nfs 4
+code misuses
+.Ft struct nameidata
+and currently has an incestuous relationship with the
+.Nm
+code.
+This is gradually being cleaned up.
+.Pp
+The
+.Ft struct componentname
+type has the following layout:
+.Bd -literal
+struct componentname {
+ /*
+ * Arguments to VOP_LOOKUP and directory VOP routines.
+ */
+ uint32_t cn_nameiop; /* namei operation */
+ uint32_t cn_flags; /* flags to namei */
+ kauth_cred_t cn_cred; /* credentials */
+ const char *cn_nameptr; /* pointer to looked up name */
+ size_t cn_namelen; /* length of looked up comp */
+ /*
+ * Side result from VOP_LOOKUP.
+ */
+ size_t cn_consume; /* chars to consume in lookup */
+};
+.Ed
+.Pp
+This structure contains the information about a single directory
+component name, along with certain other information required by vnode
+operations.
+See
+.Xr vnodeops 9
+for more information about these vnode operations.
+.Pp
+The members:
+.Bl -tag -offset indent -width cn_consumexx -compact
+.It cn_nameiop
+The type of operation in progress; indicates the basic operating mode
+of namei.
+May be one of
+.Dv LOOKUP ,
+.Dv CREATE ,
+.Dv DELETE ,
+or
+.Dv RENAME .
+These modes are described below.
+.It cn_flags
+Additional flags affecting the operation of namei.
+These are described below as well.
+.It cn_cred
+The credentials to use for the lookup or other operation the
+.Em componentname
+is passed to.
+This may match the credentials of the current process or it may not,
+depending on where the original operation request came from and how it
+has been routed.
+.It cn_nameptr
+The name of this directory component, followed by the rest of the path
+being looked up.
+.It cn_namelen
+The length of the name of this directory component.
+The name is not in general null terminated, although the complete
+string (the full remaining path) always is.
+.It cn_consume
+This field starts at zero; it may be set to a larger value by
+implementations of
+.Xr VOP_LOOKUP 9
+to indicate how many more characters beyond
+.Em cn_namelen
+are being consumed.
+New uses of this feature are discouraged and should be discussed.
+.El
+.Ss Operating modes
+Each lookup happens in one of the following modes, specified by
+callers of
+.Nm
+with
+.Fn NDINIT
+and specified internally by
+.Nm
+to
+.Xr VOP_LOOKUP 9 :
+.Bl -bullet -compact
+.It
+Callers of
+.Nm
+specify the mode for the last component of a lookup.
+.It
+Internally,
+.Nm
+recursively calls
+.Xr VOP_LOOKUP 9
+in
+.Dv LOOKUP
+mode for each directory component, and then finally calls
+.Xr VOP_LOOKUP 9
+in the caller-specified mode for the last component.
+.El
+Each mode can fail in different ways \(em for example,
+.Dv LOOKUP
+mode fails with
+.Er ENOENT
+if no entry exists, but
+.Dv CREATE
+mode succeeds with a
+.Dv NULL
+vnode.
+.Bl -tag -width LOOKUP
+.It Dv LOOKUP
+Yield the vnode for an existing entry.
+Callers specify
+.Dv LOOKUP
+for operations on existing vnodes:
+.Xr stat 2 ,
+.Xr open 2
+without
+.Dv O_CREATE ,
+etc.
+.Pp
+File systems:
+.Bl -dash -compact
+.It
+MUST refuse if user lacks lookup permission for directory.
+.It
+SHOULD use
+.Xr namecache 9
+to cache lookup results.
+.El
+.Pp
+.Bl -tag -compact -width ENAMETOOLONG
+.It Bq Er ENOENT
+No entry exists.
+.El
+.It Dv CREATE
+Yield the vnode for an existing entry; or, if there is none, yield
+.Dv NULL
+and hint that it will soon be created.
+Callers specify
+.Dv CREATE
+for operations that may create directory entries:
+.Xr mkdir 2 ,
+.Xr open 2
+with
+.Dv O_CREATE ,
+etc.
+.Pp
+File systems:
+.Bl -dash -compact
+.It
+MUST refuse if user lacks lookup permission for directory.
+.It
+MUST refuse if no entry exists and user lacks write permission for
+directory.
+.It
+MUST refuse if no entry exists and file system is read-only.
+.It
+SHOULD NOT use
+.Xr namecache 9
+to cache negative lookup results.
+.It
+SHOULD save lookup hints internally in the directory for a subsequent
+operation to create a directory entry.
+.El
+.Pp
+.Bl -tag -compact -width ENAMETOOLONG
+.It Bq Er EPERM
+The user lacks lookup permission for the directory.
+.It Bq Er EPERM
+No entry exists and the user lacks write permission for the directory.
+.It Bq Er EROFS
+No entry exists and the file system is read-only.
+.El
+.It Dv DELETE
+Yield the vnode of an existing entry, and hint that it will soon be
+deleted.
+Callers specify
+.Dv DELETE
+for operations that delete directory entries:
+.Xr unlink 2 ,
+.Xr rmdir 2 ,
+etc.
+.Pp
+File systems:
+.Bl -dash -compact
+.It
+MUST refuse if user lacks lookup permission for directory.
+.It
+MUST refuse if entry exists and user lacks write permission for
+directory.
+.It
+MUST refuse if entry exists and file system is read-only.
+.It
+SHOULD NOT use
+.Xr namecache 9
+to cache lookup results.
+.It
+SHOULD save lookup hints internally in the directory for a subsequent
+operation to delete a directory entry.
+.El
+.Pp
+.Bl -tag -compact -width ENAMETOOLONG
+.It Bq Er ENOENT
+No entry exists.
+.It Bq Er EPERM
+The user lacks lookup permission for the directory.
+.It Bq Er EPERM
+An entry exists and the user lacks write permission for the directory.
+.It Bq Er EROFS
+An entry exists and the file system is read-only.
+.El
+.It Dv RENAME
+Yield the vnode of an existing entry, and hint that it will soon be
+overwritten; or, if there is none, yield
+.Dv NULL ,
+and hint that it will soon be created.
+.Pp
+Callers specify
+.Dv RENAME
+for an entry that is about to be created or overwritten, namely for the
+target of
+.Xr rename 2 .
+.Pp
+File systems:
+.Bl -dash -compact
+.It
+MUST refuse if user lacks lookup permission for directory.
+.It
+MUST refuse if user lacks write permission for directory.
+.It
+MUST refuse if file system is read-only.
+.It
+SHOULD NOT use
+.Xr namecache 9
+to cache lookup results.
+.It
+SHOULD save lookup hints internally in the directory for a subsequent
+operation to create or overwrite a directory entry.
+.El
+.Pp
+.Bl -tag -compact -width ENAMETOOLONG
+.It Bq Er EPERM
+The user lacks lookup permission for the directory.
+.It Bq Er EPERM
+The user lacks write permission for the directory.
+.It Bq Er EROFS
+The file system is read-only.
+.El
+.El
+.Pp
+If a caller decides not to perform an operation it hinted at by a
+destructive operating mode
+.Pq Dv CREATE , Dv DELETE , No or Dv RENAME ,
+it SHOULD call
+.Xr VOP_ABORTOP 9
+to release the hints.
+If a file system fails to perform such an operation, it SHOULD call
+.Xr VOP_ABORTOP 9
+to release the hints.
+However, the current code is inconsistent about this, and every
+implementation of
+.Xr VOP_ABORTOP 9
+does nothing.
+.Ss Flags
+The following flags may be specified by
+.Em callers
+of
+.Nm ,
+and MUST NOT be used by file systems:
+.Bl -tag -width NOCROSSMOUNT
+.It Dv FOLLOW
+Follow symbolic links in the last path component.
+Used by operations that do not address symbolic links directly, such as
+.Xr stat 2 .
+(Does not affect symbolic links found in the middle of a path.)
+.It Dv NOFOLLOW
+Do not follow symbolic links in the last path component.
+Used by operations that address symbolic links directly, such as
+.Xr lstat 2 .
+.Pp
+Note: The value of
+.Dv NOFOLLOW
+is 0.
+We define the constant to let callers say either
+.Dv FOLLOW
+or
+.Dv NOFOLLOW
+explicitly.
+.It Dv LOCKLEAF
+On successful lookup, lock the vnode, if any, in
+.Fa ndp Ns Li ->ni_vp .
+Without this flag, it would be unlocked.
+.It Dv LOCKPARENT
+On successful lookup, lock and return the directory vnode in
+.Fa ndp Ns Li ->ni_dvp .
+Without this flag, it is not returned at all.
+.It Dv TRYEMULROOT
+If set, the path is looked up in the emulation root of the current
+process first.
+If that fails, the system root is used.
+.It Dv EMULROOTSET
+Indicates that the caller has set
+.Fa ndp Ns Li ->ni_erootdir
+prior to calling
+.Nm .
+This is only useful or permitted when the emulation in the current
+process is partway through being set up.
+.It Dv NOCHROOT
+Bypass normal
+.Xr chroot 8
+handling for absolute paths.
+.It Dv NOCROSSMOUNT
+Do not cross mount points.
+.It Dv RDONLY
+Enforce read-only behavior.
+.It Dv CREATEDIR
+Accept slashes after a component name that does not exist.
+This only makes sense in
+.Dv CREATE
+mode and when creating a directory.
+.It Dv NOCACHE
+Do not cache the lookup result for the last component name.
+This is used only with the
+.Dv RENAME
+mode for the target; the cache entry would be invalidated immediately.
+.El
+.Pp
+The following flag may be set by a caller of
+.Nm
+and tested by a file system in
+.Xr VOP_LOOKUP 9
+or other subsequent directory operations:
+.Bl -tag -width NOCROSSMOUNT
+.It Dv DOWHITEOUT
+Allow whiteouts to be seen as objects instead of functioning as
+.Dq nothing there .
+.El
+.Pp
+The following flags are set by namei for calling
+.Xr VOP_LOOKUP 9 :
+.Bl -tag -width NOCROSSMOUNT
+.It Dv ISDOTDOT
+The current pathname component is
+.Dq Li .. .
+May be tested by subsequent directory operations too.
+.It Dv ISLASTCN
+The current pathname component is the last component found in the
+pathname.
+Guaranteed to remain set in subsequent directory operations.
+.It Dv REQUIREDIR
+The current object to be looked up must be a directory.
+May not be used by subsequent directory operations.
+.It Dv MAKEENTRY
+The lookup result for the current pathname component should be added to
+the
+.Xr namecache 9 .
+May be used to make additional caching decisions, e.g. to store an
+mtime for determining whether our cache for a remote vnode is stale.
+May not be used by subsequent directory operations.
+.El
+.Pp
+A file system may set the following flag on return from
+.Xr VOP_LOOKUP 9
+for use by
+.Nm ,
+.Xr namecache 9 ,
+and subsequent directory operations:
+.Bl -tag -width NOCROSSMOUNT
+.It Dv ISWHITEOUT
+The object at the current pathname component is a whiteout.
+.El
+.Pp
+The following additional historic flags have been removed from
+.Nx
+and should be handled as follows if porting code from elsewhere:
+.Bl -tag -width NOCROSSMOUNT
+.It Dv INRENAME
+Part of a misbegotten and incorrect locking scheme.
+Any file-system-level code using this is presumptively incorrect.
+File systems should use the
+.Xr genfs_rename 9
+interface to handle locking in
+.Fn VOP_RENAME .
+.It Dv INRELOOKUP
+Used at one point for signaling to
+.Xr puffs 3
+to work around a protocol deficiency that was later rectified.
+.It Dv ISSYMLINK
+Useless internal state.
+.It Dv SAVESTART
+Unclean setting affect vnode reference counting.
+Now effectively never in effect.
+Any code referring to this is suspect.
+.It Dv SAVENAME
+Unclean setting relating to responsibility for freeing pathname buffers
+in the days before the
+.Em pathbuf
+structure.
+Now effectively always in effect; the caller of
+.Nm
+owns the
+.Em pathbuf
+structure and is always responsible for destroying it.
+.It Dv HASBUF
+Related to SAVENAME.
+Any uses can be replaced with
+.Dq true .
+.El
+.Sh FUNCTIONS
+.Bl -tag -width abcd
+.It Fn NDINIT "ndp" "op" "flags" "pathbuf"
+Initialise a nameidata structure pointed to by
+.Fa ndp
+for use by the
+.Nm
+interface.
+The operating mode and flags (as documented above) are specified by
+.Fa op
+and
+.Fa flags
+respectively.
+The pathname is passed as a pathbuf structure, which should be
+initialized using one of the
+.Xr pathbuf 9
+operations.
+Destroying the pathbuf is the responsibility of the caller; this must
+not be done until the caller is finished with all of the
+.Nm
+results and all of the nameidata contents except for the result vnode.
+.Pp
+This routine stores the credentials of the calling thread
+.Va ( curlwp )
+in
+.Fa ndp .
+.Fn NDINIT
+sets the credentials using
+.Xr kauth_cred_get 9 .
+In the rare case that another set of credentials is required for the
+namei operation,
+.Em ndp->ni_cnd.cn_cred
+must be set manually after
+.Fn NDINIT .
+.It Fn NDAT "ndp" "dvp"
+This macro is used after
+.Fn NDINIT
+to set the starting directory.
+This supersedes the current process's current working directory as the
+initial point of departure for looking up relative paths.
+This mechanism is used by
+.Xr openat 2
+and related calls.
+.It Fn namei "ndp"
+Convert a pathname into a pointer to a vnode.
+The nameidata structure pointed to by
+.Fa ndp
+should be initialized with the
+.Fn NDINIT
+macro, and perhaps also the
+.Fn NDAT
+macro.
+Direct initialization of members of struct nameidata is
+.Em not
+supported and may (will) break silently in the future.
+.Pp
+The vnode for the pathname is returned in
+.Em ndp->ni_vp .
+The parent directory is returned locked in
+.Em ndp->ni_dvp
+iff
+.Dv LOCKPARENT
+is specified.
+.Pp
+Any or all of the flags documented above as set by the caller can be
+enabled by passing them (OR'd together) as the
+.Fa flags
+argument of
+.Fn NDINIT .
+As discussed above every such call should explicitly contain either
+.Dv FOLLOW
+or
+.Dv NOFOLLOW
+to control the behavior regarding final symbolic links.
+.It Fn namei_simple_kernel "path" "sflags" "ret"
+Look up the path
+.Fa path
+and translate it to a vnode, returned in
+.Fa ret .
+The
+.Fa path
+argument must be a kernel
+.Pq Dv UIO_SYSSPACE
+pointer.
+The
+.Fa sflags
+argument chooses the precise behavior.
+It may be set to one of the following symbols:
+.Bl -tag -offset indent -width NSM_NOFOLLOW_TRYEMULROOT -compact
+.It Dv NSM_NOFOLLOW_NOEMULROOT
+.It Dv NSM_NOFOLLOW_TRYEMULROOT
+.It Dv NSM_FOLLOW_NOEMULROOT
+.It Dv NSM_FOLLOW_TRYEMULROOT
+.El
+These select (or not) the
+.Dv FOLLOW/NOFOLLOW
+and
+.Dv TRYEMULROOT
+flags.
+Other flags are not available through this interface, which is
+nonetheless sufficient for more than half the
+.Fn namei
+usage in the kernel.
+Note that the encoding of
+.Fa sflags
+has deliberately been arranged to be type-incompatible with anything
+else.
+This prevents various possible accidents while the
+.Fn namei
+interface is being rototilled.
+.It Fn namei_simple_user "path" "sflags" "ret"
+This function is the same as
+.Fn namei_simple_kernel
+except that the
+.Fa path
+argument shall be a user pointer
+.Pq Dv UIO_USERSPACE
+rather than a kernel pointer.
+.It Fn relookup "dvp" "vpp" "cnp" "dummy"
+Reacquire a path name component is a directory.
+This is a quicker way to lookup a pathname component when the parent
+directory is known.
+The locked parent directory vnode is specified by
+.Fa dvp
+and the pathname component by
+.Fa cnp .
+The vnode of the pathname is returned in the address specified by
+.Fa vpp .
+The
+.Fa dummy
+argument is unused.
+Note that one may only use
+.Fn relookup
+to repeat a lookup of a final path component previously done by
+.Nm ,
+and one must use the same
+.Em componentname
+structure that call produced.
+Otherwise the behavior is undefined and likely adverse.
+.It Fn lookup_for_nfsd "ndp" "startdir" "neverfollow"
+This is a private entry point into
+.Nm
+used by the NFS server code.
+It looks up a path starting from
+.Fa startdir .
+If
+.Fa neverfollow
+is set,
+.Em any
+symbolic link (not just at the end of the path) will cause an error.
+Otherwise, it follows symlinks normally.
+It should not be used by new code.
+.It Fn lookup_for_nfsd_index "ndp" "startdir"
+This is a (second) private entry point into
+.Nm
+used by the NFS server code.
+It looks up a single path component starting from
+.Fa startdir .
+It should not be used by new code.
+.El
+.Sh INTERNALS
+The
+.Em nameidata
+structure has the following layout:
+.Bd -literal
+struct nameidata {
+ /*
+ * Arguments to namei.
+ */
+ struct vnode *ni_atdir; /* startup dir, cwd if null */
+ struct pathbuf *ni_pathbuf; /* pathname container */
+ char *ni_pnbuf; /* extra pathname buffer ref (XXX) */
+ /*
+ * Internal starting state. (But see notes.)
+ */
+ struct vnode *ni_rootdir; /* logical root directory */
+ struct vnode *ni_erootdir; /* emulation root directory */
+ /*
+ * Results from namei.
+ */
+ struct vnode *ni_vp; /* vnode of result */
+ struct vnode *ni_dvp; /* vnode of intermediate directory */
+ /*
+ * Internal current state.
+ */
+ size_t ni_pathlen; /* remaining chars in path */
+ const char *ni_next; /* next location in pathname */
+ unsigned int ni_loopcnt; /* count of symlinks encountered */
+ /*
+ * Lookup parameters: this structure describes the subset of
+ * information from the nameidata structure that is passed
+ * through the VOP interface.
+ */
+ struct componentname ni_cnd;
+};
+.Ed
+.Pp
+These fields are:
+.Bl -tag -offset indent -width ni_erootdirx -compact
+.It ni_atdir
+The directory to use for the starting point of relative paths.
+If null, the current process's current directory is used.
+This is initialized to
+.Dv NULL
+by
+.Fn NDINIT
+and set by
+.Fn NDAT .
+.It ni_pathbuf
+The abstract path buffer in use, passed as an argument to
+.Fn NDINIT .
+The name pointers that appear elsewhere, such as in the
+.Em componentname
+structure, point into this buffer.
+It is owned by the caller and must not be destroyed until all
+.Nm
+operations are complete.
+See
+.Xr pathbuf 9 .
+.It ni_pnbuf
+This is the name pointer used during
+.Nm .
+It points into
+.Fa ni_pathbuf .
+It is not initialized until entry into
+.Nm .
+.It ni_rootdir
+The root directory to use as the starting point for absolute paths.
+This is retrieved from the current process's current root directory
+when
+.Nm
+starts up.
+It is not initialized by
+.Fn NDINIT .
+.It ni_erootdir
+The root directory to use as the emulation root, for processes running
+in emulation.
+This is retrieved from the current process's emulation root directory
+when
+.Nm
+starts up and not initialized by
+.Fn NDINIT .
+As described elsewhere, it may be set by the caller if the
+.Dv EMULROOTSET
+flag is used, but this should only be done when the current process's
+emulation root directory is not yet initialized.
+(And ideally in the future things would be tidied so that this is not
+necessary.)
+.It ni_vp
+.It ni_dvp
+Returned vnodes, as described above.
+These only contain valid values if
+.Nm
+returns successfully.
+.It ni_pathlen
+The length of the full current remaining path string in
+.Fa ni_pnbuf .
+This is not initialized by
+.Fn NDINIT
+and is used only internally.
+.It ni_next
+The remaining part of the path, after the current component found in
+the
+.Em componentname
+structure.
+This is not initialized by
+.Fn NDINIT
+and is used only internally.
+.It ni_loopcnt
+The number of symbolic links encountered (and traversed) so far.
+If this exceeds a limit,
+.Nm
+fails with
+.Er ELOOP .
+This is not initialized by
+.Fn NDINIT
+and is used only internally.
+.It ni_cnd
+The
+.Em componentname
+structure holding the current directory component, and also the
+mode, flags, and credentials.
+The mode, flags, and credentials are initialized by
+.Fn NDINIT ;
+the rest is not initialized until
+.Nm
+runs.
+.El
+.Pp
+There is also a
+.Em namei_state
+structure that is hidden within
+.Pa vfs_lookup.c .
+This contains the following additional state:
+.Bl -tag -offset indent -width attempt_retry -compact
+.It docache
+A flag indicating whether to cache the last pathname component.
+.It rdonly
+The read-only state, initialized from the
+.Dv RDONLY
+flag.
+.It slashes
+The number of trailing slashes found after the current pathname
+component.
+.It attempt_retry
+Set on some error cases (and not others) to indicate that a failure in
+the emulation root should be followed by a retry in the real system
+root.
+.El
+.Pp
+The state in
+.Em namei_state
+is genuinely private to
+.Nm .
+Note that much of the state in
+.Em nameidata
+should also be private, but is currently not because it is misused in
+some fashion by outside code, usually
+.Xr nfs 4 .
+.Pp
+The control flow within the
+.Nm
+portions of
+.Pa vfs_lookup.c
+is as follows.
+.Bl -tag -width namei_tryemulrootXX
+.It Fn namei
+does a complete path lookup by calling
+.Fn namei_init ,
+.Fn namei_tryemulroot ,
+and
+.Fn namei_cleanup .
+.It Fn namei_init
+sets up the basic internal state and makes some (precondition-type)
+assertions.
+.It Fn namei_cleanup
+makes some postcondition-type assertions; it currently does nothing
+besides this.
+.It Fn namei_tryemulroot
+handles
+.Dv TRYEMULROOT
+by calling
+.Fn namei_oneroot
+once or twice as needed, and attends to making sure the original
+pathname is preserved for the second try.
+.It Fn namei_oneroot
+does a complete path search from a single root directory.
+It begins with
+.Fn namei_start ,
+then calls
+.Fn lookup_once
+(and if necessary,
+.Fn namei_follow )
+repeatedly until done.
+It also handles returning the result vnode(s) in the requested state.
+.It Fn namei_start
+sets up the initial state and locking; it calls
+.Fn namei_getstartdir .
+.It Fn namei_getstartdir
+initializes the root directory state (both
+.Fa ni_rootdir
+and
+.Fa ni_erootdir )
+and picks the starting directory, consuming the leading slashes of an
+absolute path and handling the magic
+.Dq /../
+string for bypassing the emulation root.
+A different version
+.Fn namei_getstartdir_for_nfsd
+is used for lookups coming from
+.Xr nfsd 8
+as those are required to have different semantics.
+.It Fn lookup_once
+calls
+.Fn VOP_LOOKUP
+for one path component, also handling any needed crossing of mount
+points (either up or down) and coping with locking requirements.
+.It Fn lookup_parsepath
+is called prior to each
+.Fn lookup_once
+call to examine the pathname and find where the next component
+starts.
+.It Fn namei_follow
+reads the contents of a symbolic link and updates both the path buffer
+and the search directory accordingly.
+.El
+.Pp
+As a final note be advised that the magic return value associated with
+.Dv CREATE
+mode is different for
+.Nm
+than it is for
+.Fn VOP_LOOKUP .
+The latter
+.Dq fails
+with
+.Er EJUSTRETURN .
+.Nm
+translates this into succeeding and returning a null vnode.
+.Sh CODE REFERENCES
+The name lookup subsystem is implemented within the file
+.Pa sys/kern/vfs_lookup.c .
+.Sh SEE ALSO
+.Xr intro 9 ,
+.Xr namecache 9 ,
+.Xr vfs 9 ,
+.Xr vnode 9 ,
+.Xr vnodeops 9
+.Sh BUGS
+There should be no such thing as operating modes.
+Only
+.Dv LOOKUP
+is actually needed.
+The behavior where removing an object looks it up within
+.Nm
+and then calls into the file system (which must look it up again
+internally or cache state from
+.Fn VOP_LOOKUP )
+is particularly contorted.
+.Pp
+Most of the flags are equally bogus.
+.Pp
+Most of the contents of the
+.Em nameidata
+structure should be private and hidden within
+.Nm ;
+currently it cannot be because of abuse elsewhere.
+.Pp
+The
+.Dv EMULROOTSET
+flag is messy.
+.Pp
+There is no good way to support file systems that want to use
+a more elaborate pathname schema than the customary slash-delimited
+components.