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