1fab63cc4SDoug Rabson.\" -*- nroff -*- 2fab63cc4SDoug Rabson.\" 3fab63cc4SDoug Rabson.\" Copyright (c) 1996 Doug Rabson 4fab63cc4SDoug Rabson.\" 5fab63cc4SDoug Rabson.\" All rights reserved. 6fab63cc4SDoug Rabson.\" 7fab63cc4SDoug Rabson.\" This program is free software. 8fab63cc4SDoug Rabson.\" 9fab63cc4SDoug Rabson.\" Redistribution and use in source and binary forms, with or without 10fab63cc4SDoug Rabson.\" modification, are permitted provided that the following conditions 11fab63cc4SDoug Rabson.\" are met: 12fab63cc4SDoug Rabson.\" 1. Redistributions of source code must retain the above copyright 13fab63cc4SDoug Rabson.\" notice, this list of conditions and the following disclaimer. 14fab63cc4SDoug Rabson.\" 2. Redistributions in binary form must reproduce the above copyright 15fab63cc4SDoug Rabson.\" notice, this list of conditions and the following disclaimer in the 16fab63cc4SDoug Rabson.\" documentation and/or other materials provided with the distribution. 17fab63cc4SDoug Rabson.\" 18fab63cc4SDoug Rabson.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 19fab63cc4SDoug Rabson.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20fab63cc4SDoug Rabson.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21fab63cc4SDoug Rabson.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 22fab63cc4SDoug Rabson.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23fab63cc4SDoug Rabson.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24fab63cc4SDoug Rabson.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25fab63cc4SDoug Rabson.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26fab63cc4SDoug Rabson.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27fab63cc4SDoug Rabson.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28fab63cc4SDoug Rabson.\" 293a9c9c6eSMike Pritchard.\" $Id: VOP_LOOKUP.9,v 1.1 1997/03/03 18:00:26 dfr Exp $ 30fab63cc4SDoug Rabson.\" 31fab63cc4SDoug Rabson.Dd July 24, 1996 32fab63cc4SDoug Rabson.Os FreeBSD 33fab63cc4SDoug Rabson.Dt VOP_LOOKUP 9 34fab63cc4SDoug Rabson.Sh NAME 35fab63cc4SDoug Rabson.Nm VOP_LOOKUP 36fab63cc4SDoug Rabson.Nd lookup a component of a pathname 37fab63cc4SDoug Rabson.Sh SYNOPSIS 38fab63cc4SDoug Rabson.Fd #include <sys/vnode.h> 39fab63cc4SDoug Rabson.Fd #include <sys/namei.h> 40fab63cc4SDoug Rabson.Ft int 41fab63cc4SDoug Rabson.Fn VOP_LOOKUP "struct vnode *dvp" "struct vnode **vpp" "struct componentname *cnp" 42fab63cc4SDoug Rabson.Sh DESCRIPTION 43fab63cc4SDoug RabsonThis VFS entry point looks up a single pathname component in a given directory. 44fab63cc4SDoug Rabson.Pp 45fab63cc4SDoug RabsonIts arguments are: 46fab63cc4SDoug Rabson.Bl -tag -width vpp 47fab63cc4SDoug Rabson.It Ar dvp 48fab63cc4SDoug Rabsonthe locked vnode of the directory to search 49fab63cc4SDoug Rabson.It Ar vpp 50fab63cc4SDoug Rabsonthe address of a variable where the resulting locked vnode should be stored 51fab63cc4SDoug Rabson.It Ar cnp 52fab63cc4SDoug Rabsonthe pathname component to be searched for 53fab63cc4SDoug Rabson.El 54fab63cc4SDoug Rabson.Pp 55fab63cc4SDoug Rabson.Fa Cnp 56fab63cc4SDoug Rabsonis a pointer to a componentname structure defined as follows: 57fab63cc4SDoug Rabson.Bd -literal 58fab63cc4SDoug Rabsonstruct componentname { 59fab63cc4SDoug Rabson /* 60fab63cc4SDoug Rabson * Arguments to lookup. 61fab63cc4SDoug Rabson */ 62fab63cc4SDoug Rabson u_long cn_nameiop; /* namei operation */ 63fab63cc4SDoug Rabson u_long cn_flags; /* flags to namei */ 64fab63cc4SDoug Rabson struct proc *cn_proc; /* process requesting lookup */ 65fab63cc4SDoug Rabson struct ucred *cn_cred; /* credentials */ 66fab63cc4SDoug Rabson /* 67fab63cc4SDoug Rabson * Shared between lookup and commit routines. 68fab63cc4SDoug Rabson */ 69fab63cc4SDoug Rabson char *cn_pnbuf; /* pathname buffer */ 70fab63cc4SDoug Rabson char *cn_nameptr; /* pointer to looked up name */ 71fab63cc4SDoug Rabson long cn_namelen; /* length of looked up component */ 72fab63cc4SDoug Rabson u_long cn_hash; /* hash value of looked up name */ 73fab63cc4SDoug Rabson long cn_consume; /* chars to consume in lookup() */ 74fab63cc4SDoug Rabson}; 75fab63cc4SDoug Rabson.Ed 76fab63cc4SDoug Rabson.Pp 77fab63cc4SDoug RabsonConvert a component of a pathname into a pointer to a locked vnode. 78fab63cc4SDoug RabsonThis is a very central and rather complicated routine. 79fab63cc4SDoug RabsonIf the file system is not maintained in a strict tree hierarchy, 80fab63cc4SDoug Rabsonthis can result in a deadlock situation. 81fab63cc4SDoug Rabson.Pp 82fab63cc4SDoug RabsonThe 83fab63cc4SDoug Rabson.Fa cnp->cn_nameiop 84fab63cc4SDoug Rabsonargument is 85fab63cc4SDoug Rabson.Dv LOOKUP , 86fab63cc4SDoug Rabson.Dv CREATE , 87fab63cc4SDoug Rabson.Dv RENAME , 88fab63cc4SDoug Rabsonor 89fab63cc4SDoug Rabson.Dv DELETE 90fab63cc4SDoug Rabsondepending on the intended use of the object. 91fab63cc4SDoug RabsonWhen 92fab63cc4SDoug Rabson.Dv CREATE , 93fab63cc4SDoug Rabson.Dv RENAME , 94fab63cc4SDoug Rabsonor 95fab63cc4SDoug Rabson.Dv DELETE 96fab63cc4SDoug Rabsonis specified, information usable in 97fab63cc4SDoug Rabsoncreating, renaming, or deleting a directory entry may be calculated. 98fab63cc4SDoug Rabson.Pp 99fab63cc4SDoug RabsonOverall outline of VOP_LOOKUP: 100fab63cc4SDoug Rabson.Bd -filled -offset indent 101fab63cc4SDoug RabsonCheck accessibility of directory. 102fab63cc4SDoug RabsonLook for name in cache, if found, then return name. 103fab63cc4SDoug RabsonSearch for name in directory, goto to found or notfound as appropriate. 104fab63cc4SDoug Rabson.Ed 105fab63cc4SDoug Rabson.Pp 106fab63cc4SDoug Rabsonnotfound: 107fab63cc4SDoug Rabson.Bd -filled -offset indent 108fab63cc4SDoug RabsonIf creating or renaming and at end of pathname, 109fab63cc4SDoug Rabsonreturn 110fab63cc4SDoug Rabson.Dv EJUSTRETURN , 111fab63cc4SDoug Rabsonleaving info on available slots else return 112fab63cc4SDoug Rabson.Dv ENOENT . 113fab63cc4SDoug Rabson.Ed 114fab63cc4SDoug Rabson.Pp 115fab63cc4SDoug Rabsonfound: 116fab63cc4SDoug Rabson.Bd -filled -offset indent 117fab63cc4SDoug RabsonIf at end of path and deleting, return information to allow delete. 118fab63cc4SDoug RabsonIf at end of path and renaming, lock target 119fab63cc4SDoug Rabsoninode and return info to allow rename. 120fab63cc4SDoug RabsonIf not at end, add name to cache; if at end and neither creating 121fab63cc4SDoug Rabsonnor deleting, add name to cache. 122fab63cc4SDoug Rabson.Ed 123fab63cc4SDoug Rabson.Sh LOCKS 124fab63cc4SDoug RabsonThe directory, 125fab63cc4SDoug Rabson.Fa dvp 126fab63cc4SDoug Rabsonshould be locked on entry. 127fab63cc4SDoug RabsonIf an error (note: the return value 128fab63cc4SDoug Rabson.Dv EJUSTRETURN 129fab63cc4SDoug Rabsonis not considered an error) 130fab63cc4SDoug Rabsonis detected, it will be returned locked. 131fab63cc4SDoug RabsonOtherwise, it will be unlocked unless both 132fab63cc4SDoug Rabson.Dv LOCKPARENT 133fab63cc4SDoug Rabsonand 134fab63cc4SDoug Rabson.Dv ISLASTCN 135fab63cc4SDoug Rabsonare specified in 136fab63cc4SDoug Rabson.Fa cnp->cn_flags . 137fab63cc4SDoug RabsonIf an entry is found in the directory, it will be returned locked. 138fab63cc4SDoug Rabson.Sh RETURN VALUES 139fab63cc4SDoug RabsonZero is returned with 140fab63cc4SDoug Rabson.Fa *vpp 141fab63cc4SDoug Rabsonset to the locked vnode of the file if the component is found. 142fab63cc4SDoug RabsonIf the component being searched for is ".", then the vnode just has 143fab63cc4SDoug Rabsonan extra reference added to it with 144fab63cc4SDoug Rabson.Xr vref 9 . 145fab63cc4SDoug RabsonThe caller must take care to release the locks appropriately in this 146fab63cc4SDoug Rabsoncase. 147fab63cc4SDoug Rabson.Pp 148fab63cc4SDoug RabsonIf the component is not found and the operation is 149fab63cc4SDoug Rabson.Dv CREATE 150fab63cc4SDoug Rabsonor 151fab63cc4SDoug Rabson.Dv RENAME , 152fab63cc4SDoug Rabsonthe flag 153fab63cc4SDoug Rabson.Dv ISLASTCN 154fab63cc4SDoug Rabsonis specified and the operation would succeed, the special return value 155fab63cc4SDoug Rabson.Dv EJUSTRETURN 156fab63cc4SDoug Rabsonis returned. 157fab63cc4SDoug RabsonOtherwise, an appropriate error code is returned. 158fab63cc4SDoug Rabson.Sh PSEUDOCODE 159fab63cc4SDoug Rabson.Bd -literal 160fab63cc4SDoug Rabsonint 161fab63cc4SDoug Rabsonvop_lookup(struct vnode *dvp, 162fab63cc4SDoug Rabson struct vnode **vpp, 163fab63cc4SDoug Rabson struct componentname *cnp) 164fab63cc4SDoug Rabson{ 165fab63cc4SDoug Rabson int error; 166fab63cc4SDoug Rabson int nameiop = cnp->cn_nameiop; 167fab63cc4SDoug Rabson int flags = cnp->cn_flags; 168fab63cc4SDoug Rabson int lockparent = flags & LOCKPARENT; 169fab63cc4SDoug Rabson int islastcn = flags & ISLASTCN; 170fab63cc4SDoug Rabson struct vnode *vp = NULL; 171fab63cc4SDoug Rabson 172fab63cc4SDoug Rabson /* 1733a9c9c6eSMike Pritchard * Check accessibility of directory. 174fab63cc4SDoug Rabson */ 175fab63cc4SDoug Rabson if (dvp->v_type != VDIR) 176fab63cc4SDoug Rabson return ENOTDIR; 177fab63cc4SDoug Rabson 178fab63cc4SDoug Rabson error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_proc); 179fab63cc4SDoug Rabson if (error) 180fab63cc4SDoug Rabson return (error); 181fab63cc4SDoug Rabson 182fab63cc4SDoug Rabson if (islastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) && 183fab63cc4SDoug Rabson (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 184fab63cc4SDoug Rabson return (EROFS); 185fab63cc4SDoug Rabson 186fab63cc4SDoug Rabson /* 1873a9c9c6eSMike Pritchard * Check name cache for directory/name pair. This returns ENOENT 188fab63cc4SDoug Rabson * if the name is known not to exist, -1 if the name was found, or 189fab63cc4SDoug Rabson * zero if not. 190fab63cc4SDoug Rabson */ 191fab63cc4SDoug Rabson error = cache_lookup(dvp, vpp, cnp); 192fab63cc4SDoug Rabson if (error) { 193fab63cc4SDoug Rabson int vpid; 194fab63cc4SDoug Rabson 195fab63cc4SDoug Rabson if (error = ENOENT) 196fab63cc4SDoug Rabson return error; 197fab63cc4SDoug Rabson 198fab63cc4SDoug Rabson vp = *vpp; 199fab63cc4SDoug Rabson if (dvp == vp) { /* lookup on "." */ 200fab63cc4SDoug Rabson VREF(vp); 201fab63cc4SDoug Rabson error = 0; 202fab63cc4SDoug Rabson } else if (flags & ISDOTDOT) { 203fab63cc4SDoug Rabson /* 204fab63cc4SDoug Rabson * We need to unlock the directory before getting 205fab63cc4SDoug Rabson * the locked vnode for ".." to avoid deadlocks. 206fab63cc4SDoug Rabson */ 207fab63cc4SDoug Rabson VOP_UNLOCK(dvp); 208fab63cc4SDoug Rabson error = vget(vp, 1); 209fab63cc4SDoug Rabson if (!error) { 210fab63cc4SDoug Rabson if (lockparent && islastcn) 211fab63cc4SDoug Rabson error = VOP_LOCK(dvp); 212fab63cc4SDoug Rabson } 213fab63cc4SDoug Rabson } else { 214fab63cc4SDoug Rabson error = vget(vp, 1); 215fab63cc4SDoug Rabson if (error || !(lockparent && islastcn)) { 216fab63cc4SDoug Rabson VOP_UNLOCK(dvp); 217fab63cc4SDoug Rabson } 218fab63cc4SDoug Rabson } 219fab63cc4SDoug Rabson 220fab63cc4SDoug Rabson /* 221fab63cc4SDoug Rabson * Check that the capability number did not change 222fab63cc4SDoug Rabson * while we were waiting for the lock. 223fab63cc4SDoug Rabson */ 224fab63cc4SDoug Rabson if (!error) { 225fab63cc4SDoug Rabson if (vpid == vp->v_id) { 226fab63cc4SDoug Rabson /* 227fab63cc4SDoug Rabson * dvp is locked if lockparent && islastcn. 228fab63cc4SDoug Rabson * vp is locked. 229fab63cc4SDoug Rabson */ 230fab63cc4SDoug Rabson return (0); 231fab63cc4SDoug Rabson } 232fab63cc4SDoug Rabson vput(vp); 233fab63cc4SDoug Rabson 234fab63cc4SDoug Rabson if (dvp != vp && lockparent && islastcn) 235fab63cc4SDoug Rabson VOP_UNLOCK(pdp); 236fab63cc4SDoug Rabson } 237fab63cc4SDoug Rabson 238fab63cc4SDoug Rabson /* 239fab63cc4SDoug Rabson * Re-lock dvp for the directory search below. 240fab63cc4SDoug Rabson */ 241fab63cc4SDoug Rabson error = VOP_LOCK(dvp); 242fab63cc4SDoug Rabson if (error) { 243fab63cc4SDoug Rabson return (error); 244fab63cc4SDoug Rabson } 245fab63cc4SDoug Rabson 246fab63cc4SDoug Rabson *vpp = NULL; 247fab63cc4SDoug Rabson } 248fab63cc4SDoug Rabson 249fab63cc4SDoug Rabson /* 250fab63cc4SDoug Rabson * Search dvp for the component cnp->cn_nameptr. 251fab63cc4SDoug Rabson */ 252fab63cc4SDoug Rabson ...; 253fab63cc4SDoug Rabson 254fab63cc4SDoug Rabson if (!found) { 255fab63cc4SDoug Rabson if ((nameiop == CREATE || nameiop == RENAME) 256fab63cc4SDoug Rabson && islastcn 257fab63cc4SDoug Rabson && directory dvp has not been removed) { 258fab63cc4SDoug Rabson /* 259fab63cc4SDoug Rabson * Check for write access on directory. 260fab63cc4SDoug Rabson */ 261fab63cc4SDoug Rabson 262fab63cc4SDoug Rabson /* 263fab63cc4SDoug Rabson * Possibly record the position of a slot in the directory 264fab63cc4SDoug Rabson * large enough for the new component name. This can be 265fab63cc4SDoug Rabson * recorded in the vnode private data for dvp. 266fab63cc4SDoug Rabson * Set the SAVENAME flag to hold onto the pathname for use 267fab63cc4SDoug Rabson * later in VOP_CREATE or VOP_RENAME. 268fab63cc4SDoug Rabson */ 269fab63cc4SDoug Rabson cnp->cn_flags |= SAVENAME; 270fab63cc4SDoug Rabson if (!lockparent) 271fab63cc4SDoug Rabson /* 272fab63cc4SDoug Rabson * Note that the extra data recorded above is only 273fab63cc4SDoug Rabson * useful if lockparent is specified. 274fab63cc4SDoug Rabson */ 275fab63cc4SDoug Rabson VOP_UNLOCK(dvp); 276fab63cc4SDoug Rabson 277fab63cc4SDoug Rabson return EJUSTRETURN; 278fab63cc4SDoug Rabson } 279fab63cc4SDoug Rabson 280fab63cc4SDoug Rabson /* 281fab63cc4SDoug Rabson * Consider inserting name into cache. 282fab63cc4SDoug Rabson */ 283fab63cc4SDoug Rabson if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) 284fab63cc4SDoug Rabson cache_enter(dvp, NULL, cnp); 285fab63cc4SDoug Rabson 286fab63cc4SDoug Rabson return ENOENT; 287fab63cc4SDoug Rabson } else { 288fab63cc4SDoug Rabson /* 289fab63cc4SDoug Rabson * If deleting, and at end of pathname, return parameters 290fab63cc4SDoug Rabson * which can be used to remove file. If the wantparent flag 291fab63cc4SDoug Rabson * isn't set, we return only the directory, otherwise we go on 292fab63cc4SDoug Rabson * and lock the inode, being careful with ".". 293fab63cc4SDoug Rabson */ 294fab63cc4SDoug Rabson if (nameiop == DELETE && islastcn) { 295fab63cc4SDoug Rabson /* 296fab63cc4SDoug Rabson * Check for write access on directory. 297fab63cc4SDoug Rabson */ 298fab63cc4SDoug Rabson error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_proc); 299fab63cc4SDoug Rabson if (error) 300fab63cc4SDoug Rabson return (error); 301fab63cc4SDoug Rabson 302fab63cc4SDoug Rabson if (found entry is same as dvp) { 303fab63cc4SDoug Rabson VREF(dvp); 304fab63cc4SDoug Rabson *vpp = dvp; 305fab63cc4SDoug Rabson return 0; 306fab63cc4SDoug Rabson } 307fab63cc4SDoug Rabson 308fab63cc4SDoug Rabson error = VFS_VGET(dvp->v_mount, ..., &vp); 309fab63cc4SDoug Rabson if (error) 310fab63cc4SDoug Rabson return error; 311fab63cc4SDoug Rabson 312fab63cc4SDoug Rabson if (directory is sticky 313fab63cc4SDoug Rabson && cred->cr_uid != 0 314fab63cc4SDoug Rabson && cred->cr_uid != owner of dvp 315fab63cc4SDoug Rabson && owner of vp != cred->cr_uid) { 316fab63cc4SDoug Rabson vput(vp); 317fab63cc4SDoug Rabson return EPERM; 318fab63cc4SDoug Rabson } 319fab63cc4SDoug Rabson *vpp = vp; 320fab63cc4SDoug Rabson if (!lockparent) 321fab63cc4SDoug Rabson VOP_UNLOCK(dvp); 322fab63cc4SDoug Rabson 323fab63cc4SDoug Rabson return 0; 324fab63cc4SDoug Rabson } 325fab63cc4SDoug Rabson 326fab63cc4SDoug Rabson /* 327fab63cc4SDoug Rabson * If rewriting (RENAME), return the inode and the 328fab63cc4SDoug Rabson * information required to rewrite the present directory 329fab63cc4SDoug Rabson * Must get inode of directory entry to verify it's a 330fab63cc4SDoug Rabson * regular file, or empty directory. 331fab63cc4SDoug Rabson */ 332fab63cc4SDoug Rabson if (nameiop == RENAME && wantparent && islastcn) { 333fab63cc4SDoug Rabson error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_proc); 334fab63cc4SDoug Rabson if (error) 335fab63cc4SDoug Rabson return (error); 336fab63cc4SDoug Rabson 337fab63cc4SDoug Rabson /* 338fab63cc4SDoug Rabson * Check for "." 339fab63cc4SDoug Rabson */ 340fab63cc4SDoug Rabson if (found entry is same as dvp) 341fab63cc4SDoug Rabson return EISDIR; 342fab63cc4SDoug Rabson 343fab63cc4SDoug Rabson error = VFS_VGET(dvp->v_mount, ..., &vp); 344fab63cc4SDoug Rabson if (error) 345fab63cc4SDoug Rabson return error; 346fab63cc4SDoug Rabson *vpp = vp; 347fab63cc4SDoug Rabson /* 348fab63cc4SDoug Rabson * Save the name for use in VOP_RENAME later. 349fab63cc4SDoug Rabson */ 350fab63cc4SDoug Rabson cnp->cn_flags |= SAVENAME; 351fab63cc4SDoug Rabson if (!lockparent) 352fab63cc4SDoug Rabson VOP_UNLOCK(dvp); 353fab63cc4SDoug Rabson 354fab63cc4SDoug Rabson return 0; 355fab63cc4SDoug Rabson } 356fab63cc4SDoug Rabson 357fab63cc4SDoug Rabson /* 358fab63cc4SDoug Rabson * Step through the translation in the name. We do not `vput' the 359fab63cc4SDoug Rabson * directory because we may need it again if a symbolic link 360fab63cc4SDoug Rabson * is relative to the current directory. Instead we save it 361fab63cc4SDoug Rabson * unlocked as "pdp". We must get the target inode before unlocking 362fab63cc4SDoug Rabson * the directory to insure that the inode will not be removed 363fab63cc4SDoug Rabson * before we get it. We prevent deadlock by always fetching 364fab63cc4SDoug Rabson * inodes from the root, moving down the directory tree. Thus 365fab63cc4SDoug Rabson * when following backward pointers ".." we must unlock the 366fab63cc4SDoug Rabson * parent directory before getting the requested directory. 367fab63cc4SDoug Rabson * There is a potential race condition here if both the current 368fab63cc4SDoug Rabson * and parent directories are removed before the VFS_VGET for the 369fab63cc4SDoug Rabson * inode associated with ".." returns. We hope that this occurs 370fab63cc4SDoug Rabson * infrequently since we cannot avoid this race condition without 371fab63cc4SDoug Rabson * implementing a sophisticated deadlock detection algorithm. 372fab63cc4SDoug Rabson * Note also that this simple deadlock detection scheme will not 373fab63cc4SDoug Rabson * work if the file system has any hard links other than ".." 374fab63cc4SDoug Rabson * that point backwards in the directory structure. 375fab63cc4SDoug Rabson */ 376fab63cc4SDoug Rabson if (flags & ISDOTDOT) { 377fab63cc4SDoug Rabson VOP_UNLOCK(dvp); /* race to get the inode */ 378fab63cc4SDoug Rabson error = VFS_VGET(dvp->v_mount, ..., &vp); 379fab63cc4SDoug Rabson if (error) { 380fab63cc4SDoug Rabson VOP_LOCK(dvp); 381fab63cc4SDoug Rabson return (error); 382fab63cc4SDoug Rabson } 383fab63cc4SDoug Rabson if (lockparent && islastcn) { 384fab63cc4SDoug Rabson error = VOP_LOCK(dvp); 385fab63cc4SDoug Rabson if (error) { 386fab63cc4SDoug Rabson vput(vp); 387fab63cc4SDoug Rabson return error; 388fab63cc4SDoug Rabson } 389fab63cc4SDoug Rabson } 390fab63cc4SDoug Rabson *vpp = vp; 391fab63cc4SDoug Rabson } else if (found entry is same as dvp) { 392fab63cc4SDoug Rabson VREF(dvp); /* we want ourself, ie "." */ 393fab63cc4SDoug Rabson *vpp = dvp; 394fab63cc4SDoug Rabson } else { 395fab63cc4SDoug Rabson error = VFS_VGET(dvp->v_mount, ..., &vp); 396fab63cc4SDoug Rabson if (error) 397fab63cc4SDoug Rabson return (error); 398fab63cc4SDoug Rabson if (!lockparent || !islastcn) 399fab63cc4SDoug Rabson VOP_UNLOCK(dvp); 400fab63cc4SDoug Rabson *vpp = vp; 401fab63cc4SDoug Rabson } 402fab63cc4SDoug Rabson 403fab63cc4SDoug Rabson /* 404fab63cc4SDoug Rabson * Insert name into cache if appropriate. 405fab63cc4SDoug Rabson */ 406fab63cc4SDoug Rabson if (cnp->cn_flags & MAKEENTRY) 407fab63cc4SDoug Rabson cache_enter(dvp, *vpp, cnp); 408fab63cc4SDoug Rabson return (0); 409fab63cc4SDoug Rabson } 410fab63cc4SDoug Rabson} 411fab63cc4SDoug Rabson.Ed 412fab63cc4SDoug Rabson.Sh ERRORS 413fab63cc4SDoug Rabson.Bl -tag -width EJUSTRETURN 414fab63cc4SDoug Rabson.It Bq Er ENOTDIR 415fab63cc4SDoug RabsonThe vnode 416fab63cc4SDoug Rabson.Fa dvp 417fab63cc4SDoug Rabsondoes not represent a directory. 418fab63cc4SDoug Rabson.It Bq Er ENOENT 419fab63cc4SDoug RabsonThe component 420fab63cc4SDoug Rabson.Fa dvp 421fab63cc4SDoug Rabsonwas not found in this directory. 422fab63cc4SDoug Rabson.It Bq Er EACCESS 423fab63cc4SDoug Rabsonaccess for the specified operation is denied. 424fab63cc4SDoug Rabson.It Bq Er EJUSTRETURN 425fab63cc4SDoug Rabsona 426fab63cc4SDoug Rabson.Dv CREATE 427fab63cc4SDoug Rabsonor 428fab63cc4SDoug Rabson.Dv RENAME 429fab63cc4SDoug Rabsonoperation would be successful 430fab63cc4SDoug Rabson.El 431fab63cc4SDoug Rabson.Sh SEE ALSO 432fab63cc4SDoug Rabson.Xr VOP_ACCESS 9 , 433fab63cc4SDoug Rabson.Xr VOP_CREATE 9 , 434fab63cc4SDoug Rabson.Xr VOP_MKNOD 9 , 435fab63cc4SDoug Rabson.Xr VOP_MKDIR 9 , 436fab63cc4SDoug Rabson.Xr VOP_SYMLINK 9 , 437fab63cc4SDoug Rabson.Xr VOP_RENAME 9 , 438fab63cc4SDoug Rabson.Xr VOP_ABORTOP 9 439fab63cc4SDoug Rabson.Sh HISTORY 440fab63cc4SDoug RabsonThe function 441fab63cc4SDoug Rabson.Nm 442fab63cc4SDoug Rabsonappeared in 4.3BSD. 443fab63cc4SDoug Rabson.Sh SEE ALSO 444fab63cc4SDoug Rabson.Xr vnode 9 445fab63cc4SDoug Rabson.Sh AUTHORS 446fab63cc4SDoug RabsonThis man page was written by Doug Rabson, with some text from 447fab63cc4SDoug Rabsoncomments in ufs_lookup.c. 448