137487Smckusick /*
268534Smckusick * Copyright (c) 1989, 1993, 1995
363180Sbostic * The Regents of the University of California. All rights reserved.
437487Smckusick *
568534Smckusick * This code is derived from software contributed to Berkeley by
668534Smckusick * Poul-Henning Kamp of the FreeBSD Project.
768534Smckusick *
844455Sbostic * %sccs.include.redist.c%
937487Smckusick *
1068534Smckusick * from: vfs_cache.c,v 1.11 1995/03/12 02:01:20 phk Exp $
1168534Smckusick *
12*68581Smckusick * @(#)vfs_cache.c 8.5 (Berkeley) 03/22/95
1337487Smckusick */
1437487Smckusick
1556517Sbostic #include <sys/param.h>
1656517Sbostic #include <sys/systm.h>
1756517Sbostic #include <sys/time.h>
1856517Sbostic #include <sys/mount.h>
1956517Sbostic #include <sys/vnode.h>
2056517Sbostic #include <sys/namei.h>
2156517Sbostic #include <sys/errno.h>
2256517Sbostic #include <sys/malloc.h>
2337487Smckusick
2437487Smckusick /*
2537487Smckusick * Name caching works as follows:
2637487Smckusick *
2737487Smckusick * Names found by directory scans are retained in a cache
2837487Smckusick * for future reference. It is managed LRU, so frequently
2937487Smckusick * used names will hang around. Cache is indexed by hash value
3038768Smckusick * obtained from (vp, name) where vp refers to the directory
3138768Smckusick * containing name.
3237487Smckusick *
3368534Smckusick * If it is a "negative" entry, (i.e. for a name that is known NOT to
3468534Smckusick * exist) the vnode pointer will be NULL.
3568534Smckusick *
3637487Smckusick * For simplicity (and economy of storage), names longer than
3737487Smckusick * a maximum length of NCHNAMLEN are not cached; they occur
3837487Smckusick * infrequently in any case, and are almost never of interest.
3937487Smckusick *
4037487Smckusick * Upon reaching the last segment of a path, if the reference
4137487Smckusick * is for DELETE, or NOCACHE is set (rewrite), and the
4237487Smckusick * name is located in the cache, it will be dropped.
4337487Smckusick */
4437487Smckusick
4537487Smckusick /*
4637487Smckusick * Structures associated with name cacheing.
4737487Smckusick */
4868534Smckusick #define NCHHASH(dvp, cnp) \
4968534Smckusick (&nchashtbl[((dvp)->v_id + (cnp)->cn_hash) & nchash])
5068534Smckusick LIST_HEAD(nchashhead, namecache) *nchashtbl; /* Hash Table */
5140881Smckusick u_long nchash; /* size of hash table - 1 */
5240881Smckusick long numcache; /* number of cache entries allocated */
5368534Smckusick TAILQ_HEAD(, namecache) nclruhead; /* LRU chain */
5437487Smckusick struct nchstats nchstats; /* cache effectiveness statistics */
5537487Smckusick
5638768Smckusick int doingcache = 1; /* 1 => enable the cache */
5738768Smckusick
5837487Smckusick /*
5968534Smckusick * Delete an entry from its hash list and move it to the front
6068534Smckusick * of the LRU list for immediate reuse.
6168534Smckusick */
6268534Smckusick #define PURGE(ncp) { \
6368534Smckusick LIST_REMOVE(ncp, nc_hash); \
6468534Smckusick ncp->nc_hash.le_prev = 0; \
6568534Smckusick TAILQ_REMOVE(&nclruhead, ncp, nc_lru); \
6668534Smckusick TAILQ_INSERT_HEAD(&nclruhead, ncp, nc_lru); \
6768534Smckusick }
6868534Smckusick
6968534Smckusick /*
7068534Smckusick * Move an entry that has been used to the tail of the LRU list
7168534Smckusick * so that it will be preserved for future use.
7268534Smckusick */
7368534Smckusick #define TOUCH(ncp) { \
7468534Smckusick if (ncp->nc_lru.tqe_next != 0) { \
7568534Smckusick TAILQ_REMOVE(&nclruhead, ncp, nc_lru); \
7668534Smckusick TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); \
7768534Smckusick } \
7868534Smckusick }
7968534Smckusick
8068534Smckusick /*
8168534Smckusick * Lookup an entry in the cache
8268534Smckusick *
8368534Smckusick * We don't do this if the segment name is long, simply so the cache
8468534Smckusick * can avoid holding long names (which would either waste space, or
8537487Smckusick * add greatly to the complexity).
8638768Smckusick *
8768534Smckusick * Lookup is called with dvp pointing to the directory to search,
8868534Smckusick * cnp pointing to the name of the entry being sought. If the lookup
8968534Smckusick * succeeds, the vnode is returned in *vpp, and a status of -1 is
9068534Smckusick * returned. If the lookup determines that the name does not exist
9168534Smckusick * (negative cacheing), a status of ENOENT is returned. If the lookup
9268534Smckusick * fails, a status of zero is returned.
9337487Smckusick */
9468534Smckusick
9552231Sheideman int
cache_lookup(dvp,vpp,cnp)9652306Sheideman cache_lookup(dvp, vpp, cnp)
9752231Sheideman struct vnode *dvp;
9852231Sheideman struct vnode **vpp;
9952231Sheideman struct componentname *cnp;
10037487Smckusick {
10168534Smckusick register struct namecache *ncp, *nnp;
10267732Smckusick register struct nchashhead *ncpp;
10337487Smckusick
10467490Smckusick if (!doingcache) {
10567490Smckusick cnp->cn_flags &= ~MAKEENTRY;
10638768Smckusick return (0);
10767490Smckusick }
10852231Sheideman if (cnp->cn_namelen > NCHNAMLEN) {
10937487Smckusick nchstats.ncs_long++;
11052231Sheideman cnp->cn_flags &= ~MAKEENTRY;
11137487Smckusick return (0);
11237487Smckusick }
11368534Smckusick
11468534Smckusick ncpp = NCHHASH(dvp, cnp);
11568534Smckusick for (ncp = ncpp->lh_first; ncp != 0; ncp = nnp) {
11668534Smckusick nnp = ncp->nc_hash.le_next;
11768534Smckusick /* If one of the vp's went stale, don't bother anymore. */
11868534Smckusick if ((ncp->nc_dvpid != ncp->nc_dvp->v_id) ||
11968534Smckusick (ncp->nc_vp && ncp->nc_vpid != ncp->nc_vp->v_id)) {
12068534Smckusick nchstats.ncs_falsehits++;
12168534Smckusick PURGE(ncp);
12268534Smckusick continue;
12368534Smckusick }
12468534Smckusick /* Now that we know the vp's to be valid, is it ours ? */
12538768Smckusick if (ncp->nc_dvp == dvp &&
12652231Sheideman ncp->nc_nlen == cnp->cn_namelen &&
12755544Smckusick !bcmp(ncp->nc_name, cnp->cn_nameptr, (u_int)ncp->nc_nlen))
12837487Smckusick break;
12937487Smckusick }
13068534Smckusick
13168534Smckusick /* We failed to find an entry */
13267732Smckusick if (ncp == 0) {
13337487Smckusick nchstats.ncs_miss++;
13437487Smckusick return (0);
13537487Smckusick }
13668534Smckusick
13768534Smckusick /* We don't want to have an entry, so dump it */
13867732Smckusick if ((cnp->cn_flags & MAKEENTRY) == 0) {
13938768Smckusick nchstats.ncs_badhits++;
14068534Smckusick PURGE(ncp);
14168534Smckusick return (0);
14268534Smckusick }
14368534Smckusick
14468534Smckusick /* We found a "positive" match, return the vnode */
14568534Smckusick if (ncp->nc_vp) {
14637487Smckusick nchstats.ncs_goodhits++;
14768534Smckusick TOUCH(ncp);
14852231Sheideman *vpp = ncp->nc_vp;
14938768Smckusick return (-1);
15037487Smckusick }
15137487Smckusick
15268534Smckusick /* We found a negative match, and want to create it, so purge */
15368534Smckusick if (cnp->cn_nameiop == CREATE) {
15468534Smckusick nchstats.ncs_badhits++;
15568534Smckusick PURGE(ncp);
15668534Smckusick return (0);
15768534Smckusick }
15868534Smckusick
159*68581Smckusick /*
160*68581Smckusick * We found a "negative" match, ENOENT notifies client of this match.
161*68581Smckusick * The nc_vpid field records whether this is a whiteout.
162*68581Smckusick */
16368534Smckusick nchstats.ncs_neghits++;
16468534Smckusick TOUCH(ncp);
165*68581Smckusick cnp->cn_flags |= ncp->nc_vpid;
16668534Smckusick return (ENOENT);
16737487Smckusick }
16837487Smckusick
16937487Smckusick /*
17068534Smckusick * Add an entry to the cache.
17137487Smckusick */
17268534Smckusick void
cache_enter(dvp,vp,cnp)17352306Sheideman cache_enter(dvp, vp, cnp)
17452231Sheideman struct vnode *dvp;
17552231Sheideman struct vnode *vp;
17652231Sheideman struct componentname *cnp;
17737487Smckusick {
17867732Smckusick register struct namecache *ncp;
17967732Smckusick register struct nchashhead *ncpp;
18037487Smckusick
18168534Smckusick if (!doingcache)
18268534Smckusick return;
18368534Smckusick
18455185Smckusick #ifdef DIAGNOSTIC
18555185Smckusick if (cnp->cn_namelen > NCHNAMLEN)
18655185Smckusick panic("cache_enter: name too long");
18755185Smckusick #endif
18868534Smckusick
18937487Smckusick /*
19068534Smckusick * We allocate a new entry if we are less than the maximum
19168534Smckusick * allowed and the one at the front of the LRU list is in use.
19268534Smckusick * Otherwise we use the one at the front of the LRU list.
19337487Smckusick */
19468534Smckusick if (numcache < desiredvnodes &&
19568534Smckusick ((ncp = nclruhead.tqh_first) == NULL ||
19668534Smckusick ncp->nc_hash.le_prev != 0)) {
19768534Smckusick /* Add one more entry */
19840881Smckusick ncp = (struct namecache *)
19945117Smckusick malloc((u_long)sizeof *ncp, M_CACHE, M_WAITOK);
20040881Smckusick bzero((char *)ncp, sizeof *ncp);
20140881Smckusick numcache++;
20267732Smckusick } else if (ncp = nclruhead.tqh_first) {
20368534Smckusick /* reuse an old entry */
20467732Smckusick TAILQ_REMOVE(&nclruhead, ncp, nc_lru);
20567732Smckusick if (ncp->nc_hash.le_prev != 0) {
20667732Smckusick LIST_REMOVE(ncp, nc_hash);
20767732Smckusick ncp->nc_hash.le_prev = 0;
20855699Smckusick }
20968534Smckusick } else {
21068534Smckusick /* give up */
21140881Smckusick return;
21268534Smckusick }
21368534Smckusick
214*68581Smckusick /*
215*68581Smckusick * Fill in cache info, if vp is NULL this is a "negative" cache entry.
216*68581Smckusick * For negative entries, we have to record whether it is a whiteout.
217*68581Smckusick * the whiteout flag is stored in the nc_vpid field which is
218*68581Smckusick * otherwise unused.
219*68581Smckusick */
22052231Sheideman ncp->nc_vp = vp;
22152231Sheideman if (vp)
22252231Sheideman ncp->nc_vpid = vp->v_id;
22340881Smckusick else
224*68581Smckusick ncp->nc_vpid = cnp->cn_flags & ISWHITEOUT;
22552231Sheideman ncp->nc_dvp = dvp;
22652231Sheideman ncp->nc_dvpid = dvp->v_id;
22752231Sheideman ncp->nc_nlen = cnp->cn_namelen;
22852231Sheideman bcopy(cnp->cn_nameptr, ncp->nc_name, (unsigned)ncp->nc_nlen);
22967732Smckusick TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru);
23068534Smckusick ncpp = NCHHASH(dvp, cnp);
23167732Smckusick LIST_INSERT_HEAD(ncpp, ncp, nc_hash);
23237487Smckusick }
23337487Smckusick
23437487Smckusick /*
23540881Smckusick * Name cache initialization, from vfs_init() when we are booting
23637487Smckusick */
23768534Smckusick void
nchinit()23837487Smckusick nchinit()
23937487Smckusick {
24037487Smckusick
24167732Smckusick TAILQ_INIT(&nclruhead);
24255544Smckusick nchashtbl = hashinit(desiredvnodes, M_CACHE, &nchash);
24337487Smckusick }
24437487Smckusick
24537487Smckusick /*
24668534Smckusick * Invalidate a all entries to particular vnode.
24768534Smckusick *
24868534Smckusick * We actually just increment the v_id, that will do it. The entries will
24968534Smckusick * be purged by lookup as they get found. If the v_id wraps around, we
25068534Smckusick * need to ditch the entire cache, to avoid confusion. No valid vnode will
25168534Smckusick * ever have (v_id == 0).
25237487Smckusick */
25368534Smckusick void
cache_purge(vp)25437487Smckusick cache_purge(vp)
25538768Smckusick struct vnode *vp;
25637487Smckusick {
25767732Smckusick struct namecache *ncp;
25867732Smckusick struct nchashhead *ncpp;
25937487Smckusick
26038768Smckusick vp->v_id = ++nextvnodeid;
26138768Smckusick if (nextvnodeid != 0)
26238768Smckusick return;
26355544Smckusick for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
26468534Smckusick while (ncp = ncpp->lh_first)
26568534Smckusick PURGE(ncp);
26637487Smckusick }
26738768Smckusick vp->v_id = ++nextvnodeid;
26837487Smckusick }
26937487Smckusick
27037487Smckusick /*
27168534Smckusick * Flush all entries referencing a particular filesystem.
27237487Smckusick *
27368534Smckusick * Since we need to check it anyway, we will flush all the invalid
27468534Smckusick * entriess at the same time.
27537487Smckusick */
27668534Smckusick void
cache_purgevfs(mp)27737487Smckusick cache_purgevfs(mp)
27845117Smckusick struct mount *mp;
27937487Smckusick {
28068534Smckusick struct nchashhead *ncpp;
28168534Smckusick struct namecache *ncp, *nnp;
28237487Smckusick
28368534Smckusick /* Scan hash tables for applicable entries */
28468534Smckusick for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
28568534Smckusick for (ncp = ncpp->lh_first; ncp != 0; ncp = nnp) {
28668534Smckusick nnp = ncp->nc_hash.le_next;
28768534Smckusick if (ncp->nc_dvpid != ncp->nc_dvp->v_id ||
28868534Smckusick (ncp->nc_vp && ncp->nc_vpid != ncp->nc_vp->v_id) ||
28968534Smckusick ncp->nc_dvp->v_mount == mp) {
29068534Smckusick PURGE(ncp);
29168534Smckusick }
29255544Smckusick }
29337487Smckusick }
29437487Smckusick }
295