137487Smckusick /* 2*68534Smckusick * Copyright (c) 1989, 1993, 1995 363180Sbostic * The Regents of the University of California. All rights reserved. 437487Smckusick * 5*68534Smckusick * This code is derived from software contributed to Berkeley by 6*68534Smckusick * Poul-Henning Kamp of the FreeBSD Project. 7*68534Smckusick * 844455Sbostic * %sccs.include.redist.c% 937487Smckusick * 10*68534Smckusick * from: vfs_cache.c,v 1.11 1995/03/12 02:01:20 phk Exp $ 11*68534Smckusick * 12*68534Smckusick * @(#)vfs_cache.c 8.4 (Berkeley) 03/18/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 * 33*68534Smckusick * If it is a "negative" entry, (i.e. for a name that is known NOT to 34*68534Smckusick * exist) the vnode pointer will be NULL. 35*68534Smckusick * 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 */ 48*68534Smckusick #define NCHHASH(dvp, cnp) \ 49*68534Smckusick (&nchashtbl[((dvp)->v_id + (cnp)->cn_hash) & nchash]) 50*68534Smckusick LIST_HEAD(nchashhead, namecache) *nchashtbl; /* Hash Table */ 5140881Smckusick u_long nchash; /* size of hash table - 1 */ 5240881Smckusick long numcache; /* number of cache entries allocated */ 53*68534Smckusick TAILQ_HEAD(, namecache) nclruhead; /* LRU chain */ 5437487Smckusick struct nchstats nchstats; /* cache effectiveness statistics */ 5537487Smckusick 5638768Smckusick int doingcache = 1; /* 1 => enable the cache */ 5738768Smckusick 5837487Smckusick /* 59*68534Smckusick * Delete an entry from its hash list and move it to the front 60*68534Smckusick * of the LRU list for immediate reuse. 61*68534Smckusick */ 62*68534Smckusick #define PURGE(ncp) { \ 63*68534Smckusick LIST_REMOVE(ncp, nc_hash); \ 64*68534Smckusick ncp->nc_hash.le_prev = 0; \ 65*68534Smckusick TAILQ_REMOVE(&nclruhead, ncp, nc_lru); \ 66*68534Smckusick TAILQ_INSERT_HEAD(&nclruhead, ncp, nc_lru); \ 67*68534Smckusick } 68*68534Smckusick 69*68534Smckusick /* 70*68534Smckusick * Move an entry that has been used to the tail of the LRU list 71*68534Smckusick * so that it will be preserved for future use. 72*68534Smckusick */ 73*68534Smckusick #define TOUCH(ncp) { \ 74*68534Smckusick if (ncp->nc_lru.tqe_next != 0) { \ 75*68534Smckusick TAILQ_REMOVE(&nclruhead, ncp, nc_lru); \ 76*68534Smckusick TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); \ 77*68534Smckusick } \ 78*68534Smckusick } 79*68534Smckusick 80*68534Smckusick /* 81*68534Smckusick * Lookup an entry in the cache 82*68534Smckusick * 83*68534Smckusick * We don't do this if the segment name is long, simply so the cache 84*68534Smckusick * can avoid holding long names (which would either waste space, or 8537487Smckusick * add greatly to the complexity). 8638768Smckusick * 87*68534Smckusick * Lookup is called with dvp pointing to the directory to search, 88*68534Smckusick * cnp pointing to the name of the entry being sought. If the lookup 89*68534Smckusick * succeeds, the vnode is returned in *vpp, and a status of -1 is 90*68534Smckusick * returned. If the lookup determines that the name does not exist 91*68534Smckusick * (negative cacheing), a status of ENOENT is returned. If the lookup 92*68534Smckusick * fails, a status of zero is returned. 9337487Smckusick */ 94*68534Smckusick 9552231Sheideman int 9652306Sheideman cache_lookup(dvp, vpp, cnp) 9752231Sheideman struct vnode *dvp; 9852231Sheideman struct vnode **vpp; 9952231Sheideman struct componentname *cnp; 10037487Smckusick { 101*68534Smckusick 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 } 113*68534Smckusick 114*68534Smckusick ncpp = NCHHASH(dvp, cnp); 115*68534Smckusick for (ncp = ncpp->lh_first; ncp != 0; ncp = nnp) { 116*68534Smckusick nnp = ncp->nc_hash.le_next; 117*68534Smckusick /* If one of the vp's went stale, don't bother anymore. */ 118*68534Smckusick if ((ncp->nc_dvpid != ncp->nc_dvp->v_id) || 119*68534Smckusick (ncp->nc_vp && ncp->nc_vpid != ncp->nc_vp->v_id)) { 120*68534Smckusick nchstats.ncs_falsehits++; 121*68534Smckusick PURGE(ncp); 122*68534Smckusick continue; 123*68534Smckusick } 124*68534Smckusick /* 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 } 130*68534Smckusick 131*68534Smckusick /* We failed to find an entry */ 13267732Smckusick if (ncp == 0) { 13337487Smckusick nchstats.ncs_miss++; 13437487Smckusick return (0); 13537487Smckusick } 136*68534Smckusick 137*68534Smckusick /* We don't want to have an entry, so dump it */ 13867732Smckusick if ((cnp->cn_flags & MAKEENTRY) == 0) { 13938768Smckusick nchstats.ncs_badhits++; 140*68534Smckusick PURGE(ncp); 141*68534Smckusick return (0); 142*68534Smckusick } 143*68534Smckusick 144*68534Smckusick /* We found a "positive" match, return the vnode */ 145*68534Smckusick if (ncp->nc_vp) { 14637487Smckusick nchstats.ncs_goodhits++; 147*68534Smckusick TOUCH(ncp); 14852231Sheideman *vpp = ncp->nc_vp; 14938768Smckusick return (-1); 15037487Smckusick } 15137487Smckusick 152*68534Smckusick /* We found a negative match, and want to create it, so purge */ 153*68534Smckusick if (cnp->cn_nameiop == CREATE) { 154*68534Smckusick nchstats.ncs_badhits++; 155*68534Smckusick PURGE(ncp); 156*68534Smckusick return (0); 157*68534Smckusick } 158*68534Smckusick 159*68534Smckusick /* We found a "negative" match, ENOENT notifies client of this match */ 160*68534Smckusick nchstats.ncs_neghits++; 161*68534Smckusick TOUCH(ncp); 162*68534Smckusick return (ENOENT); 16337487Smckusick } 16437487Smckusick 16537487Smckusick /* 166*68534Smckusick * Add an entry to the cache. 16737487Smckusick */ 168*68534Smckusick void 16952306Sheideman cache_enter(dvp, vp, cnp) 17052231Sheideman struct vnode *dvp; 17152231Sheideman struct vnode *vp; 17252231Sheideman struct componentname *cnp; 17337487Smckusick { 17467732Smckusick register struct namecache *ncp; 17567732Smckusick register struct nchashhead *ncpp; 17637487Smckusick 177*68534Smckusick if (!doingcache) 178*68534Smckusick return; 179*68534Smckusick 18055185Smckusick #ifdef DIAGNOSTIC 18155185Smckusick if (cnp->cn_namelen > NCHNAMLEN) 18255185Smckusick panic("cache_enter: name too long"); 18355185Smckusick #endif 184*68534Smckusick 18537487Smckusick /* 186*68534Smckusick * We allocate a new entry if we are less than the maximum 187*68534Smckusick * allowed and the one at the front of the LRU list is in use. 188*68534Smckusick * Otherwise we use the one at the front of the LRU list. 18937487Smckusick */ 190*68534Smckusick if (numcache < desiredvnodes && 191*68534Smckusick ((ncp = nclruhead.tqh_first) == NULL || 192*68534Smckusick ncp->nc_hash.le_prev != 0)) { 193*68534Smckusick /* Add one more entry */ 19440881Smckusick ncp = (struct namecache *) 19545117Smckusick malloc((u_long)sizeof *ncp, M_CACHE, M_WAITOK); 19640881Smckusick bzero((char *)ncp, sizeof *ncp); 19740881Smckusick numcache++; 19867732Smckusick } else if (ncp = nclruhead.tqh_first) { 199*68534Smckusick /* reuse an old entry */ 20067732Smckusick TAILQ_REMOVE(&nclruhead, ncp, nc_lru); 20167732Smckusick if (ncp->nc_hash.le_prev != 0) { 20267732Smckusick LIST_REMOVE(ncp, nc_hash); 20367732Smckusick ncp->nc_hash.le_prev = 0; 20455699Smckusick } 205*68534Smckusick } else { 206*68534Smckusick /* give up */ 20740881Smckusick return; 208*68534Smckusick } 209*68534Smckusick 210*68534Smckusick /* fill in cache info, if vp is NULL this is a "negative" cache entry */ 21152231Sheideman ncp->nc_vp = vp; 21252231Sheideman if (vp) 21352231Sheideman ncp->nc_vpid = vp->v_id; 21440881Smckusick else 21540881Smckusick ncp->nc_vpid = 0; 21652231Sheideman ncp->nc_dvp = dvp; 21752231Sheideman ncp->nc_dvpid = dvp->v_id; 21852231Sheideman ncp->nc_nlen = cnp->cn_namelen; 21952231Sheideman bcopy(cnp->cn_nameptr, ncp->nc_name, (unsigned)ncp->nc_nlen); 22067732Smckusick TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); 221*68534Smckusick ncpp = NCHHASH(dvp, cnp); 22267732Smckusick LIST_INSERT_HEAD(ncpp, ncp, nc_hash); 22337487Smckusick } 22437487Smckusick 22537487Smckusick /* 22640881Smckusick * Name cache initialization, from vfs_init() when we are booting 22737487Smckusick */ 228*68534Smckusick void 22937487Smckusick nchinit() 23037487Smckusick { 23137487Smckusick 23267732Smckusick TAILQ_INIT(&nclruhead); 23355544Smckusick nchashtbl = hashinit(desiredvnodes, M_CACHE, &nchash); 23437487Smckusick } 23537487Smckusick 23637487Smckusick /* 237*68534Smckusick * Invalidate a all entries to particular vnode. 238*68534Smckusick * 239*68534Smckusick * We actually just increment the v_id, that will do it. The entries will 240*68534Smckusick * be purged by lookup as they get found. If the v_id wraps around, we 241*68534Smckusick * need to ditch the entire cache, to avoid confusion. No valid vnode will 242*68534Smckusick * ever have (v_id == 0). 24337487Smckusick */ 244*68534Smckusick void 24537487Smckusick cache_purge(vp) 24638768Smckusick struct vnode *vp; 24737487Smckusick { 24867732Smckusick struct namecache *ncp; 24967732Smckusick struct nchashhead *ncpp; 25037487Smckusick 25138768Smckusick vp->v_id = ++nextvnodeid; 25238768Smckusick if (nextvnodeid != 0) 25338768Smckusick return; 25455544Smckusick for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) { 255*68534Smckusick while (ncp = ncpp->lh_first) 256*68534Smckusick PURGE(ncp); 25737487Smckusick } 25838768Smckusick vp->v_id = ++nextvnodeid; 25937487Smckusick } 26037487Smckusick 26137487Smckusick /* 262*68534Smckusick * Flush all entries referencing a particular filesystem. 26337487Smckusick * 264*68534Smckusick * Since we need to check it anyway, we will flush all the invalid 265*68534Smckusick * entriess at the same time. 26637487Smckusick */ 267*68534Smckusick void 26837487Smckusick cache_purgevfs(mp) 26945117Smckusick struct mount *mp; 27037487Smckusick { 271*68534Smckusick struct nchashhead *ncpp; 272*68534Smckusick struct namecache *ncp, *nnp; 27337487Smckusick 274*68534Smckusick /* Scan hash tables for applicable entries */ 275*68534Smckusick for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) { 276*68534Smckusick for (ncp = ncpp->lh_first; ncp != 0; ncp = nnp) { 277*68534Smckusick nnp = ncp->nc_hash.le_next; 278*68534Smckusick if (ncp->nc_dvpid != ncp->nc_dvp->v_id || 279*68534Smckusick (ncp->nc_vp && ncp->nc_vpid != ncp->nc_vp->v_id) || 280*68534Smckusick ncp->nc_dvp->v_mount == mp) { 281*68534Smckusick PURGE(ncp); 282*68534Smckusick } 28355544Smckusick } 28437487Smckusick } 28537487Smckusick } 286