2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>,
7 * This code is derived from software contributed to Berkeley by
8 * Poul-Henning Kamp of the FreeBSD Project.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
39 * $FreeBSD: src/sys/kern/vfs_cache.c,v 1.42.2.6 2001/10/05 20:07:03 dillon Exp $
40 * $DragonFly: src/sys/kern/vfs_cache.c,v 1.23 2004/06/05 16:34:05 dillon Exp $
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/sysctl.h>
47 #include <sys/mount.h>
48 #include <sys/vnode.h>
49 #include <sys/malloc.h>
50 #include <sys/sysproto.h>
52 #include <sys/namei.h>
53 #include <sys/filedesc.h>
54 #include <sys/fnv_hash.h>
55 #include <sys/globaldata.h>
56 #include <sys/kern_syscall.h>
59 * Random lookups in the cache are accomplished with a hash table using
60 * a hash key of (nc_src_vp, name).
62 * Negative entries may exist and correspond to structures where nc_vp
63 * is NULL. In a negative entry, NCF_WHITEOUT will be set if the entry
64 * corresponds to a whited-out directory entry (verses simply not finding the
67 * Upon reaching the last segment of a path, if the reference is for DELETE,
68 * or NOCACHE is set (rewrite), and the name is located in the cache, it
73 * Structures associated with name cacheing.
75 #define NCHHASH(hash) (&nchashtbl[(hash) & nchash])
78 MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries");
80 static LIST_HEAD(nchashhead, namecache) *nchashtbl; /* Hash Table */
81 static struct namecache_list ncneglist; /* instead of vnode */
82 static struct namecache rootnamecache; /* Dummy node */
84 static int nczapcheck; /* panic on bad release */
85 SYSCTL_INT(_debug, OID_AUTO, nczapcheck, CTLFLAG_RW, &nczapcheck, 0, "");
87 static u_long nchash; /* size of hash table */
88 SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0, "");
90 static u_long ncnegfactor = 16; /* ratio of negative entries */
91 SYSCTL_ULONG(_debug, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0, "");
93 static u_long numneg; /* number of cache entries allocated */
94 SYSCTL_ULONG(_debug, OID_AUTO, numneg, CTLFLAG_RD, &numneg, 0, "");
96 static u_long numcache; /* number of cache entries allocated */
97 SYSCTL_ULONG(_debug, OID_AUTO, numcache, CTLFLAG_RD, &numcache, 0, "");
99 static u_long numunres; /* number of unresolved entries */
100 SYSCTL_ULONG(_debug, OID_AUTO, numunres, CTLFLAG_RD, &numunres, 0, "");
102 SYSCTL_INT(_debug, OID_AUTO, vnsize, CTLFLAG_RD, 0, sizeof(struct vnode), "");
103 SYSCTL_INT(_debug, OID_AUTO, ncsize, CTLFLAG_RD, 0, sizeof(struct namecache), "");
106 * The new name cache statistics
108 SYSCTL_NODE(_vfs, OID_AUTO, cache, CTLFLAG_RW, 0, "Name cache statistics");
109 #define STATNODE(mode, name, var) \
110 SYSCTL_ULONG(_vfs_cache, OID_AUTO, name, mode, var, 0, "");
111 STATNODE(CTLFLAG_RD, numneg, &numneg);
112 STATNODE(CTLFLAG_RD, numcache, &numcache);
113 static u_long numcalls; STATNODE(CTLFLAG_RD, numcalls, &numcalls);
114 static u_long dothits; STATNODE(CTLFLAG_RD, dothits, &dothits);
115 static u_long dotdothits; STATNODE(CTLFLAG_RD, dotdothits, &dotdothits);
116 static u_long numchecks; STATNODE(CTLFLAG_RD, numchecks, &numchecks);
117 static u_long nummiss; STATNODE(CTLFLAG_RD, nummiss, &nummiss);
118 static u_long nummisszap; STATNODE(CTLFLAG_RD, nummisszap, &nummisszap);
119 static u_long numposzaps; STATNODE(CTLFLAG_RD, numposzaps, &numposzaps);
120 static u_long numposhits; STATNODE(CTLFLAG_RD, numposhits, &numposhits);
121 static u_long numnegzaps; STATNODE(CTLFLAG_RD, numnegzaps, &numnegzaps);
122 static u_long numneghits; STATNODE(CTLFLAG_RD, numneghits, &numneghits);
124 struct nchstats nchstats[SMP_MAXCPU];
126 * Export VFS cache effectiveness statistics to user-land.
128 * The statistics are left for aggregation to user-land so
129 * neat things can be achieved, like observing per-CPU cache
133 sysctl_nchstats(SYSCTL_HANDLER_ARGS)
135 struct globaldata *gd;
139 for (i = 0; i < ncpus; ++i) {
140 gd = globaldata_find(i);
141 if ((error = SYSCTL_OUT(req, (void *)&(*gd->gd_nchstats),
142 sizeof(struct nchstats))))
148 SYSCTL_PROC(_vfs_cache, OID_AUTO, nchstats, CTLTYPE_OPAQUE|CTLFLAG_RD,
149 0, 0, sysctl_nchstats, "S,nchstats", "VFS cache effectiveness statistics");
151 static void cache_zap(struct namecache *ncp);
154 * cache_hold() and cache_drop() prevent the premature deletion of a
155 * namecache entry but do not prevent operations (such as zapping) on
156 * that namecache entry.
160 _cache_hold(struct namecache *ncp)
168 _cache_drop(struct namecache *ncp)
170 KKASSERT(ncp->nc_refs > 0);
171 if (ncp->nc_refs == 1 &&
172 (ncp->nc_flag & NCF_UNRESOLVED) &&
173 TAILQ_EMPTY(&ncp->nc_list)
182 cache_hold(struct namecache *ncp)
184 return(_cache_hold(ncp));
188 cache_drop(struct namecache *ncp)
194 cache_link_parent(struct namecache *ncp, struct namecache *par)
196 KKASSERT(ncp->nc_parent == NULL);
197 ncp->nc_parent = par;
198 if (TAILQ_EMPTY(&par->nc_list)) {
202 TAILQ_INSERT_HEAD(&par->nc_list, ncp, nc_entry);
206 cache_unlink_parent(struct namecache *ncp)
208 struct namecache *par;
210 if ((par = ncp->nc_parent) != NULL) {
211 ncp->nc_parent = NULL;
212 par = cache_hold(par);
213 TAILQ_REMOVE(&par->nc_list, ncp, nc_entry);
214 if (par->nc_vp && TAILQ_EMPTY(&par->nc_list))
220 static struct namecache *
221 cache_alloc(struct vnode *vp)
223 struct namecache *ncp;
225 ncp = malloc(sizeof(*ncp), M_VFSCACHE, M_WAITOK|M_ZERO);
226 TAILQ_INIT(&ncp->nc_list);
229 TAILQ_INSERT_HEAD(&vp->v_namecache, ncp, nc_vnode);
232 TAILQ_INSERT_TAIL(&ncneglist, ncp, nc_vnode);
239 * Try to destroy a namecache entry. The entry is disassociated from its
240 * vnode or ncneglist and reverted to an UNRESOLVED state.
242 * Then, if there are no additional references to the ncp and we can
243 * successfully delete the children, the entry is also removed from the
244 * namecache hashlist / topology.
246 * References or undeletable children will prevent the entry from being
247 * removed from the topology. The entry may be revalidated (typically
248 * by cache_enter()) at a later time. Children remain because:
250 * + we have tried to delete a node rather then a leaf in the topology.
251 * + the presence of negative entries (we try to scrap these).
252 * + an entry or child has a non-zero ref count and cannot be scrapped.
254 * This function must be called with the ncp held and will drop the ref
255 * count during zapping.
258 cache_zap(struct namecache *ncp)
260 struct namecache *par;
264 * Disassociate the vnode or negative cache ref and set NCF_UNRESOLVED.
266 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
267 ncp->nc_flag |= NCF_UNRESOLVED;
269 if ((vp = ncp->nc_vp) != NULL) {
271 ncp->nc_vp = NULL; /* safety */
272 TAILQ_REMOVE(&vp->v_namecache, ncp, nc_vnode);
273 if (!TAILQ_EMPTY(&ncp->nc_list))
276 TAILQ_REMOVE(&ncneglist, ncp, nc_vnode);
282 * Try to scrap the entry and possibly tail-recurse on its parent.
283 * We only scrap unref'd (other then our ref) unresolved entries,
284 * we do not scrap 'live' entries.
286 while (ncp->nc_flag & NCF_UNRESOLVED) {
288 * Someone other then us has a ref, stop.
290 if (ncp->nc_refs > 1)
294 * We have children, stop.
296 if (!TAILQ_EMPTY(&ncp->nc_list))
300 * Ok, we can completely destroy and free this entry. Sanity
301 * check it against our static rootnamecache structure,
302 * then remove it from the hash.
304 KKASSERT(ncp != &rootnamecache);
306 if (ncp->nc_flag & NCF_HASHED) {
307 ncp->nc_flag &= ~NCF_HASHED;
308 LIST_REMOVE(ncp, nc_hash);
312 * Unlink from its parent and free, then loop on the
313 * parent. XXX temp hack, in stage-3 parent is never NULL
315 if ((par = ncp->nc_parent) != NULL) {
316 par = cache_hold(par);
317 TAILQ_REMOVE(&par->nc_list, ncp, nc_entry);
318 if (par->nc_vp && TAILQ_EMPTY(&par->nc_list))
322 ncp->nc_refs = -1; /* safety */
323 ncp->nc_parent = NULL; /* safety */
325 free(ncp->nc_name, M_VFSCACHE);
326 free(ncp, M_VFSCACHE);
328 if (par == NULL) /* temp hack */
329 return; /* temp hack */
336 * Lookup an entry in the cache
338 * Lookup is called with dvp pointing to the directory to search,
339 * cnp pointing to the name of the entry being sought.
341 * If the lookup succeeds, the vnode is returned in *vpp, and a
342 * status of -1 is returned.
344 * If the lookup determines that the name does not exist (negative cacheing),
345 * a status of ENOENT is returned.
347 * If the lookup fails, a status of zero is returned.
349 * Note that UNRESOLVED entries are ignored. They are not negative cache
353 cache_lookup(struct vnode *dvp, struct namecache *par, struct vnode **vpp,
354 struct namecache **ncpp, struct componentname *cnp)
356 struct namecache *ncp;
358 globaldata_t gd = mycpu;
363 * Obtain the namecache entry associated with dvp, creating one if
364 * necessary. If we have to create one we have insufficient
365 * information to hash it or even supply the name, but we still
366 * need one so we can link it in.
368 * NOTE: in this stage of development, the passed 'par' is
369 * almost always NULL.
372 if ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL)
373 par = cache_alloc(dvp);
377 * Deal with "." and "..". In this stage of code development we leave
378 * the returned ncpp NULL. Note that if the namecache is disjoint,
379 * we won't find a vnode for "..".
381 if (cnp->cn_nameptr[0] == '.') {
382 if (cnp->cn_namelen == 1) {
385 numposhits++; /* include in total statistics */
388 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') {
390 numposhits++; /* include in total statistics */
391 if ((cnp->cn_flags & CNP_MAKEENTRY) == 0)
393 if (par->nc_parent == NULL ||
394 par->nc_parent->nc_vp == NULL) {
397 *vpp = par->nc_parent->nc_vp;
403 * Try to locate an existing entry
405 hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT);
406 hash = fnv_32_buf(&par, sizeof(par), hash);
408 printf("DVP %p/%p %08x %*.*s\n", dvp, par, hash, (int)cnp->cn_namelen, (int)cnp->cn_namelen, cnp->cn_nameptr);
410 LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
412 if (nczapcheck > 1) {
413 printf("TEST ncp par=%p %*.*s\n",
414 ncp->nc_parent, ncp->nc_nlen, ncp->nc_nlen,
419 * Zap entries that have timed out.
421 if (ncp->nc_timeout &&
422 (int)(ncp->nc_timeout - ticks) < 0
426 cache_zap(cache_hold(ncp));
431 * Break out if we find a matching entry. UNRESOLVED entries
432 * never match (they are in the middle of being destroyed).
434 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0 &&
435 ncp->nc_parent == par &&
436 ncp->nc_nlen == cnp->cn_namelen &&
437 bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen) == 0
447 * If we failed to locate an entry, return 0 (indicates failure).
450 if ((cnp->cn_flags & CNP_MAKEENTRY) == 0) {
455 gd->gd_nchstats->ncs_miss++;
457 printf("MISS %p/%p %*.*s/%*.*s\n", dvp, par,
458 par->nc_nlen, par->nc_nlen, (par->nc_name ? par->nc_name : ""),
459 (int)cnp->cn_namelen, (int)cnp->cn_namelen, cnp->cn_nameptr);
465 * If we found an entry, but we don't want to have one, we zap it.
467 if ((cnp->cn_flags & CNP_MAKEENTRY) == 0) {
469 gd->gd_nchstats->ncs_badhits++;
475 * If the vnode is not NULL then return the positive match.
479 gd->gd_nchstats->ncs_goodhits++;
486 * If the vnode is NULL we found a negative match. If we want to
487 * create it, purge the negative match and return failure (as if
488 * we hadn't found a match in the first place).
490 if (cnp->cn_nameiop == NAMEI_CREATE) {
492 gd->gd_nchstats->ncs_badhits++;
500 * We found a "negative" match, ENOENT notifies client of this match.
501 * The nc_flag field records whether this is a whiteout. Since there
502 * is no vnode we can use the vnode tailq link field with ncneglist.
504 TAILQ_REMOVE(&ncneglist, ncp, nc_vnode);
505 TAILQ_INSERT_TAIL(&ncneglist, ncp, nc_vnode);
506 gd->gd_nchstats->ncs_neghits++;
507 if (ncp->nc_flag & NCF_WHITEOUT)
508 cnp->cn_flags |= CNP_ISWHITEOUT;
514 * Generate a special linkage between the mount point and the root of the
515 * mounted filesystem in order to maintain the namecache topology across
516 * a mount point. The special linkage has a 0-length name component
517 * and sets NCF_MOUNTPT.
520 cache_mount(struct vnode *dvp, struct vnode *tvp)
522 struct namecache *ncp;
523 struct namecache *par;
524 struct nchashhead *nchpp;
528 * If a linkage already exists we do not have to do anything.
530 hash = fnv_32_buf("", 0, FNV1_32_INIT);
531 hash = fnv_32_buf(&dvp->v_id, sizeof(dvp->v_id), hash);
532 LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
534 if (ncp->nc_vp == tvp &&
537 ncp->nc_parent->nc_vp == dvp
543 if ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL)
544 par = cache_alloc(dvp);
547 * Otherwise create a new linkage.
549 ncp = cache_alloc(tvp);
550 ncp->nc_flag = NCF_MOUNTPT;
551 cache_link_parent(ncp, par);
556 hash = fnv_32_buf("", 0, FNV1_32_INIT);
557 hash = fnv_32_buf(&dvp->v_id, sizeof(dvp->v_id), hash);
558 nchpp = NCHHASH(hash);
559 LIST_INSERT_HEAD(nchpp, ncp, nc_hash);
561 ncp->nc_flag |= NCF_HASHED;
565 * Add an entry to the cache.
568 cache_enter(struct vnode *dvp, struct namecache *par, struct vnode *vp, struct componentname *cnp)
570 struct namecache *ncp;
571 struct namecache *bpar;
572 struct nchashhead *nchpp;
577 * If the directory has no namecache entry we must associate one with
578 * it. The name of the entry is not known so it isn't hashed.
581 if ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL)
582 par = cache_alloc(dvp);
586 * This may be a bit confusing. "." and ".." are 'virtual' entries.
587 * We do not actually create a namecache entry representing either.
588 * However, the ".." case is used to linkup a potentially disjoint
589 * directory with its parent, to disconnect a directory from its
590 * parent, or to change an existing linkage that may no longer be
591 * correct (as might occur when a subdirectory is renamed).
594 if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')
596 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[0] == '.' &&
597 cnp->cn_nameptr[1] == '.'
601 cache_unlink_parent(par);
603 if ((ncp = TAILQ_FIRST(&vp->v_namecache)) == NULL)
604 ncp = cache_alloc(vp);
607 cache_unlink_parent(par);
608 cache_link_parent(par, ncp); /* ncp is parent of par */
615 * Locate other entries associated with this vnode and zap them,
616 * because the purge code may not be able to find them due to
617 * the topology not yet being consistent. This is a temporary
622 TAILQ_FOREACH(ncp, &vp->v_namecache, nc_vnode) {
623 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
624 cache_zap(cache_hold(ncp));
630 hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT);
632 hash = fnv_32_buf(&bpar, sizeof(bpar), hash);
635 printf("ENTER %p/%p %08x '%*.*s' %p ", dvp, par, hash, (int)cnp->cn_namelen, (int)cnp->cn_namelen, cnp->cn_nameptr, vp);
638 name = malloc(cnp->cn_namelen, M_VFSCACHE, M_WAITOK);
639 ncp = cache_alloc(vp);
646 if (cnp->cn_flags & CNP_CACHETIMEOUT) {
647 if ((ncp->nc_timeout = ticks + cnp->cn_timeout) == 0)
652 * Linkup the parent pointer, bump the parent vnode's hold
653 * count when we go from 0->1 children.
655 cache_link_parent(ncp, par);
658 * Add to the hash table
661 ncp->nc_nlen = cnp->cn_namelen;
662 bcopy(cnp->cn_nameptr, ncp->nc_name, cnp->cn_namelen);
663 nchpp = NCHHASH(hash);
664 LIST_INSERT_HEAD(nchpp, ncp, nc_hash);
665 ncp->nc_flag |= NCF_HASHED;
668 * If the target vnode is NULL if this is to be a negative cache
672 ncp->nc_flag &= ~NCF_WHITEOUT;
673 if (cnp->cn_flags & CNP_ISWHITEOUT)
674 ncp->nc_flag |= NCF_WHITEOUT;
678 * Don't cache too many negative hits
680 if (numneg > MINNEG && numneg * ncnegfactor > numcache) {
681 ncp = TAILQ_FIRST(&ncneglist);
682 KKASSERT(ncp != NULL);
683 cache_zap(cache_hold(ncp));
688 * Name cache initialization, from vfsinit() when we are booting
690 * rootnamecache is initialized such that it cannot be recursively deleted.
698 /* initialise per-cpu namecache effectiveness statistics. */
699 for (i = 0; i < ncpus; ++i) {
700 gd = globaldata_find(i);
701 gd->gd_nchstats = &nchstats[i];
704 TAILQ_INIT(&ncneglist);
705 nchashtbl = hashinit(desiredvnodes*2, M_VFSCACHE, &nchash);
706 TAILQ_INIT(&rootnamecache.nc_list);
707 rootnamecache.nc_flag |= NCF_HASHED | NCF_ROOT | NCF_UNRESOLVED;
708 rootnamecache.nc_refs = 1;
712 * vfs_cache_setroot()
714 * Create an association between the root of our namecache and
715 * the root vnode. This routine may be called several times during
719 vfs_cache_setroot(struct vnode *nvp)
721 KKASSERT(rootnamecache.nc_refs > 0); /* don't accidently free */
722 cache_zap(cache_hold(&rootnamecache));
724 rootnamecache.nc_vp = nvp;
725 rootnamecache.nc_flag &= ~NCF_UNRESOLVED;
728 if (!TAILQ_EMPTY(&rootnamecache.nc_list))
730 TAILQ_INSERT_HEAD(&nvp->v_namecache, &rootnamecache, nc_vnode);
733 TAILQ_INSERT_TAIL(&ncneglist, &rootnamecache, nc_vnode);
734 rootnamecache.nc_flag &= ~NCF_WHITEOUT;
739 * Invalidate all namecache entries to a particular vnode as well as
740 * any direct children of that vnode in the namecache. This is a
741 * 'catch all' purge used by filesystems that do not know any better.
743 * A new vnode v_id is generated. Note that no vnode will ever have a
746 * Note that the linkage between the vnode and its namecache entries will
747 * be removed, but the namecache entries themselves might stay put due to
748 * active references from elsewhere in the system or due to the existance of
749 * the children. The namecache topology is left intact even if we do not
750 * know what the vnode association is. Such entries will be marked
753 * XXX: Only time and the size of v_id prevents this from failing:
754 * XXX: In theory we should hunt down all (struct vnode*, v_id)
755 * XXX: soft references and nuke them, at least on the global
756 * XXX: v_id wraparound. The period of resistance can be extended
757 * XXX: by incrementing each vnodes v_id individually instead of
758 * XXX: using the global v_id.
761 cache_purge(struct vnode *vp)
763 static u_long nextid;
764 struct namecache *ncp;
765 struct namecache *scan;
768 * Disassociate the vnode from its namecache entries along with
769 * (for historical reasons) any direct children.
771 while ((ncp = TAILQ_FIRST(&vp->v_namecache)) != NULL) {
774 restart: /* YYY hack, fix me */
775 TAILQ_FOREACH(scan, &ncp->nc_list, nc_entry) {
776 if ((scan->nc_flag & NCF_UNRESOLVED) == 0) {
777 cache_zap(cache_hold(scan));
785 * Calculate a new unique id for ".." handling
789 } while (nextid == vp->v_id || nextid == 0);
794 * Flush all entries referencing a particular filesystem.
796 * Since we need to check it anyway, we will flush all the invalid
797 * entries at the same time.
800 cache_purgevfs(struct mount *mp)
802 struct nchashhead *nchpp;
803 struct namecache *ncp, *nnp;
806 * Scan hash tables for applicable entries.
808 for (nchpp = &nchashtbl[nchash]; nchpp >= nchashtbl; nchpp--) {
809 ncp = LIST_FIRST(nchpp);
813 nnp = LIST_NEXT(ncp, nc_hash);
816 if (ncp->nc_vp && ncp->nc_vp->v_mount == mp)
828 * Test whether the vnode is at a leaf in the nameicache tree.
830 * Returns 0 if it is a leaf, -1 if it isn't.
833 cache_leaf_test(struct vnode *vp)
835 struct namecache *scan;
836 struct namecache *ncp;
838 TAILQ_FOREACH(scan, &vp->v_namecache, nc_vnode) {
839 TAILQ_FOREACH(ncp, &scan->nc_list, nc_entry) {
840 /* YYY && ncp->nc_vp->v_type == VDIR ? */
841 if (ncp->nc_vp != NULL)
849 * Perform canonical checks and cache lookup and pass on to filesystem
850 * through the vop_cachedlookup only if needed.
853 * struct vnode a_dvp;
854 * struct namecache *a_ncp;
855 * struct vnode **a_vpp;
856 * struct namecache **a_ncpp;
857 * struct componentname *a_cnp;
861 vfs_cache_lookup(struct vop_lookup_args *ap)
863 struct vnode *dvp, *vp;
866 struct namecache *par = ap->a_par;
867 struct vnode **vpp = ap->a_vpp;
868 struct namecache **ncpp = ap->a_ncpp;
869 struct componentname *cnp = ap->a_cnp;
870 struct ucred *cred = cnp->cn_cred;
871 int flags = cnp->cn_flags;
872 struct thread *td = cnp->cn_td;
873 u_long vpid; /* capability number of vnode */
879 lockparent = flags & CNP_LOCKPARENT;
881 if (dvp->v_type != VDIR)
884 if ((flags & CNP_ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
885 (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME)) {
889 error = VOP_ACCESS(dvp, VEXEC, cred, td);
894 error = cache_lookup(dvp, par, vpp, ncpp, cnp);
897 return (VOP_CACHEDLOOKUP(dvp, par, vpp, ncpp, cnp));
904 cnp->cn_flags &= ~CNP_PDIRUNLOCK;
905 if (dvp == vp) { /* lookup on "." */
908 } else if (flags & CNP_ISDOTDOT) {
909 VOP_UNLOCK(dvp, NULL, 0, td);
910 cnp->cn_flags |= CNP_PDIRUNLOCK;
911 error = vget(vp, NULL, LK_EXCLUSIVE, td);
912 if (!error && lockparent && (flags & CNP_ISLASTCN)) {
913 if ((error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td)) == 0)
914 cnp->cn_flags &= ~CNP_PDIRUNLOCK;
917 error = vget(vp, NULL, LK_EXCLUSIVE, td);
918 if (!lockparent || error || !(flags & CNP_ISLASTCN)) {
919 VOP_UNLOCK(dvp, NULL, 0, td);
920 cnp->cn_flags |= CNP_PDIRUNLOCK;
924 * Check that the capability number did not change
925 * while we were waiting for the lock.
928 if (vpid == vp->v_id)
931 if (lockparent && dvp != vp && (flags & CNP_ISLASTCN)) {
932 VOP_UNLOCK(dvp, NULL, 0, td);
933 cnp->cn_flags |= CNP_PDIRUNLOCK;
936 if (cnp->cn_flags & CNP_PDIRUNLOCK) {
937 error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td);
940 cnp->cn_flags &= ~CNP_PDIRUNLOCK;
942 return (VOP_CACHEDLOOKUP(dvp, par, vpp, ncpp, cnp));
945 static int disablecwd;
946 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, "");
948 static u_long numcwdcalls; STATNODE(CTLFLAG_RD, numcwdcalls, &numcwdcalls);
949 static u_long numcwdfail1; STATNODE(CTLFLAG_RD, numcwdfail1, &numcwdfail1);
950 static u_long numcwdfail2; STATNODE(CTLFLAG_RD, numcwdfail2, &numcwdfail2);
951 static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3);
952 static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4);
953 static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound);
956 __getcwd(struct __getcwd_args *uap)
966 buflen = uap->buflen;
969 if (buflen > MAXPATHLEN)
972 buf = malloc(buflen, M_TEMP, M_WAITOK);
973 bp = kern_getcwd(buf, buflen, &error);
975 error = copyout(bp, uap->buf, strlen(bp) + 1);
981 kern_getcwd(char *buf, size_t buflen, int *error)
983 struct proc *p = curproc;
985 int i, slash_prefixed;
986 struct filedesc *fdp;
987 struct namecache *ncp;
996 for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) {
997 if (vp->v_flag & VROOT) {
998 if (vp->v_mount == NULL) { /* forced unmount */
1002 vp = vp->v_mount->mnt_vnodecovered;
1005 TAILQ_FOREACH(ncp, &vp->v_namecache, nc_vnode) {
1006 if (ncp->nc_parent && ncp->nc_parent->nc_vp &&
1016 for (i = ncp->nc_nlen - 1; i >= 0; i--) {
1022 *--bp = ncp->nc_name[i];
1031 vp = ncp->nc_parent->nc_vp;
1033 if (!slash_prefixed) {
1047 * Thus begins the fullpath magic.
1051 #define STATNODE(name) \
1052 static u_int name; \
1053 SYSCTL_UINT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, "")
1055 static int disablefullpath;
1056 SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW,
1057 &disablefullpath, 0, "");
1059 STATNODE(numfullpathcalls);
1060 STATNODE(numfullpathfail1);
1061 STATNODE(numfullpathfail2);
1062 STATNODE(numfullpathfail3);
1063 STATNODE(numfullpathfail4);
1064 STATNODE(numfullpathfound);
1067 vn_fullpath(struct proc *p, struct vnode *vn, char **retbuf, char **freebuf)
1070 int i, slash_prefixed;
1071 struct filedesc *fdp;
1072 struct namecache *ncp;
1076 if (disablefullpath)
1082 /* vn is NULL, client wants us to use p->p_textvp */
1084 if ((vn = p->p_textvp) == NULL)
1088 buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1089 bp = buf + MAXPATHLEN - 1;
1093 for (vp = vn; vp != fdp->fd_rdir && vp != rootvnode;) {
1094 if (vp->v_flag & VROOT) {
1095 if (vp->v_mount == NULL) { /* forced unmount */
1099 vp = vp->v_mount->mnt_vnodecovered;
1102 TAILQ_FOREACH(ncp, &vp->v_namecache, nc_vnode) {
1105 if (ncp->nc_parent && ncp->nc_parent->nc_vp &&
1115 for (i = ncp->nc_nlen - 1; i >= 0; i--) {
1121 *--bp = ncp->nc_name[i];
1130 vp = ncp->nc_parent->nc_vp;
1132 if (!slash_prefixed) {