1 .\" Copyright (c) 1996 Doug Rabson
3 .\" All rights reserved.
5 .\" This program is free software.
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
10 .\" 1. Redistributions of source code must retain the above copyright
11 .\" notice, this list of conditions and the following disclaimer.
12 .\" 2. Redistributions in binary form must reproduce the above copyright
13 .\" notice, this list of conditions and the following disclaimer in the
14 .\" documentation and/or other materials provided with the distribution.
16 .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
17 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 .\" $FreeBSD: src/share/man/man9/VOP_LOOKUP.9,v 1.8.2.5 2001/12/17 11:30:18 ru Exp $
28 .\" $DragonFly: src/share/man/man9/VOP_LOOKUP.9,v 1.4 2004/06/01 11:36:53 hmp Exp $
35 .Nd lookup a component of a pathname
41 .Fn VOP_LOOKUP "struct vnode *dvp" "struct vnode **vpp" "struct componentname *cnp"
43 This entry point looks up a single pathname component in a given directory.
48 the locked vnode of the directory to search
50 the address of a variable where the resulting locked vnode should be stored
52 the pathname component to be searched for
56 is a pointer to a componentname structure defined as follows:
58 struct componentname {
60 * Arguments to lookup.
62 u_long cn_nameiop; /* namei operation */
63 u_long cn_flags; /* flags to namei */
64 struct proc *cn_proc; /* process requesting lookup */
65 struct ucred *cn_cred; /* credentials */
67 * Shared between lookup and commit routines.
69 char *cn_pnbuf; /* pathname buffer */
70 char *cn_nameptr; /* pointer to looked up name */
71 long cn_namelen; /* length of looked up component */
72 u_long cn_hash; /* hash value of looked up name */
73 long cn_consume; /* chars to consume in lookup() */
77 Convert a component of a pathname into a pointer to a locked vnode.
78 This is a very central and rather complicated routine.
79 If the file system is not maintained in a strict tree hierarchy,
80 this can result in a deadlock situation.
90 depending on the intended use of the object.
96 is specified, information usable in
97 creating, renaming, or deleting a directory entry may be calculated.
99 Overall outline of VOP_LOOKUP:
100 .Bd -ragged -offset indent
101 Check accessibility of directory.
102 Look for name in cache, if found, then return name.
103 Search for name in directory, goto to found or notfound as appropriate.
107 .Bd -ragged -offset indent
108 If creating or renaming and at end of pathname,
111 leaving info on available slots else return
116 .Bd -ragged -offset indent
117 If at end of path and deleting, return information to allow delete.
118 If at end of path and renaming, lock target
119 inode and return info to allow rename.
120 If not at end, add name to cache; if at end and neither creating
121 nor deleting, add name to cache.
126 should be locked on entry.
127 If an error (note: the return value
129 is not considered an error)
130 is detected, it will be returned locked.
131 Otherwise, it will be unlocked unless both
137 If an entry is found in the directory, it will be returned locked.
139 Zero is returned with
141 set to the locked vnode of the file if the component is found.
142 If the component being searched for is ".", then the vnode just has
143 an extra reference added to it with
145 The caller must take care to release the locks appropriately in this
148 If the component is not found and the operation is
154 is specified and the operation would succeed, the special return value
157 Otherwise, an appropriate error code is returned.
161 vop_lookup(struct vnode *dvp,
163 struct componentname *cnp)
166 int nameiop = cnp->cn_nameiop;
167 int flags = cnp->cn_flags;
168 int lockparent = flags & LOCKPARENT;
169 int islastcn = flags & ISLASTCN;
170 struct vnode *vp = NULL;
173 * Check accessibility of directory.
175 if (dvp->v_type != VDIR)
178 error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_proc);
182 if (islastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
183 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
187 * Check name cache for directory/name pair. This returns ENOENT
188 * if the name is known not to exist, -1 if the name was found, or
191 error = cache_lookup(dvp, vpp, cnp);
199 if (dvp == vp) { /* lookup on "." */
202 } else if (flags & ISDOTDOT) {
204 * We need to unlock the directory before getting
205 * the locked vnode for ".." to avoid deadlocks.
210 if (lockparent && islastcn)
211 error = VOP_LOCK(dvp);
215 if (error || !(lockparent && islastcn)) {
221 * Check that the capability number did not change
222 * while we were waiting for the lock.
225 if (vpid == vp->v_id) {
227 * dvp is locked if lockparent && islastcn.
234 if (dvp != vp && lockparent && islastcn)
239 * Re-lock dvp for the directory search below.
241 error = VOP_LOCK(dvp);
250 * Search dvp for the component cnp->cn_nameptr.
255 if ((nameiop == CREATE || nameiop == RENAME)
257 && directory dvp has not been removed) {
259 * Check for write access on directory.
263 * Possibly record the position of a slot in the directory
264 * large enough for the new component name. This can be
265 * recorded in the vnode private data for dvp.
266 * Set the SAVENAME flag to hold onto the pathname for use
267 * later in VOP_CREATE or VOP_RENAME.
269 cnp->cn_flags |= SAVENAME;
272 * Note that the extra data recorded above is only
273 * useful if lockparent is specified.
281 * Consider inserting name into cache.
283 if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
284 cache_enter(dvp, NULL, cnp);
289 * If deleting, and at end of pathname, return parameters
290 * which can be used to remove file. If the wantparent flag
291 * isn't set, we return only the directory, otherwise we go on
292 * and lock the inode, being careful with ".".
294 if (nameiop == DELETE && islastcn) {
296 * Check for write access on directory.
298 error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_proc);
302 if (found entry is same as dvp) {
308 error = VFS_VGET(dvp->v_mount, ..., &vp);
312 if (directory is sticky
314 && cred->cr_uid != owner of dvp
315 && owner of vp != cred->cr_uid) {
327 * If rewriting (RENAME), return the inode and the
328 * information required to rewrite the present directory
329 * Must get inode of directory entry to verify it's a
330 * regular file, or empty directory.
332 if (nameiop == RENAME && wantparent && islastcn) {
333 error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_proc);
340 if (found entry is same as dvp)
343 error = VFS_VGET(dvp->v_mount, ..., &vp);
348 * Save the name for use in VOP_RENAME later.
350 cnp->cn_flags |= SAVENAME;
358 * Step through the translation in the name. We do not `vput' the
359 * directory because we may need it again if a symbolic link
360 * is relative to the current directory. Instead we save it
361 * unlocked as "pdp". We must get the target inode before unlocking
362 * the directory to insure that the inode will not be removed
363 * before we get it. We prevent deadlock by always fetching
364 * inodes from the root, moving down the directory tree. Thus
365 * when following backward pointers ".." we must unlock the
366 * parent directory before getting the requested directory.
367 * There is a potential race condition here if both the current
368 * and parent directories are removed before the VFS_VGET for the
369 * inode associated with ".." returns. We hope that this occurs
370 * infrequently since we cannot avoid this race condition without
371 * implementing a sophisticated deadlock detection algorithm.
372 * Note also that this simple deadlock detection scheme will not
373 * work if the file system has any hard links other than ".."
374 * that point backwards in the directory structure.
376 if (flags & ISDOTDOT) {
377 VOP_UNLOCK(dvp); /* race to get the inode */
378 error = VFS_VGET(dvp->v_mount, ..., &vp);
383 if (lockparent && islastcn) {
384 error = VOP_LOCK(dvp);
391 } else if (found entry is same as dvp) {
392 VREF(dvp); /* we want ourself, ie "." */
395 error = VFS_VGET(dvp->v_mount, ..., &vp);
398 if (!lockparent || !islastcn)
404 * Insert name into cache if appropriate.
406 if (cnp->cn_flags & MAKEENTRY)
407 cache_enter(dvp, *vpp, cnp);
417 does not represent a directory.
421 was not found in this directory.
423 access for the specified operation is denied.
424 .It Bq Er EJUSTRETURN
429 operation would be successful
447 This man page was written by
449 with some text from comments in