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