VFS_CACHE(9) Kernel Developer's Manual VFS_CACHE(9)

vfs_cache, cache_enter, cache_lookup, cache_purge, cache_purgevfs, cache_revlookupname lookup cache

#include <sys/vnode.h>
#include <sys/namei.h>

cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp);

cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp);

cache_purge(struct vnode *vp);

cache_purgevfs(struct mount *mp);

cache_revlookup(struct vnode *vp, struct vnode **dvpp, char **bpp, char *bufp);

In order to speed up file name look-up operations (see VOP_LOOKUP(9)), the kernel provides an interface for maintaining a cache of the most recently looked-up file name translations. Entries in this cache have the following definition:

struct	namecache {
	TAILQ_ENTRY(namecache) nc_lru;	/* Regular Entry LRU chain */
	TAILQ_ENTRY(namecache) nc_neg;	/* Negative Entry LRU chain */
	RBT_ENTRY(namecache) n_rbcache;	/* Namecache rb tree from vnode */
	TAILQ_ENTRY(namecache) nc_me;	/* ncp's referring to me */
	struct	vnode *nc_dvp;		/* vnode of parent of name */
	u_long	nc_dvpid;		/* capability number of nc_dvp */
	struct	vnode *nc_vp;		/* vnode the name refers to */
	u_long	nc_vpid;		/* capability number of nc_vp */
	char	nc_nlen;		/* length of name */
	char	nc_name[NAMECACHE_MAXLEN];	/* segment name */

The cache is indexed by a hash value based on the file's base name and its encompassing directory's vnode generation number. Negative caching is also performed so that frequently accessed path names of files that do not exist do not result in expensive lookups.

File names with length longer than NAMECACHE_MAXLEN are not cached to simplify lookups and to save space. Such names are rare and are generally not worth caching.

The vfs_cache API contains the following routines:

(dvp, vpp, cnp)
Look up the given name in the cache. dvp points to the directory to search, vpp points to a pointer where the vnode of the name being sought will be stored, and cnp contains the last component of the path name. cnp must have the cn_nameptr, cn_namelen, and cn_hash fields filled in. If no entry is found for the given name, a new one will be created, even if the path name fails (i.e. it will be negative cached), unless the namei(9) lookup operation was DELETE or the NOCACHE flag was set for the call to namei(9).

Upon success, a pointer to a locked vnode is stored in vpp and a zero value is returned. If locking the vnode fails, the vnode will remain unlocked, *vpp will be set to NULL, and the corresponding error will be returned. If the cache entry is negative cached, meaning the name is no longer valid, ENOENT is returned. Otherwise, the cache lookup has failed and a -1 value is returned.

(dvp, vp, cnp)
Add a new entry for the translation in the directory dvp for the vnode vp with name cnp to the cache. cnp must have the cn_nameptr, cn_namelen, and cn_hash fields filled in.
Flush all cache entries corresponding with the given vnode vp. This is called after rename operations to hide entries that would no longer be valid.
Flush all cache entries for name translations associated with the file system mount described by mp. This is called when unmounting file systems, which would make all name translations pertaining to the mount invalid.
(vp, dvpp, bpp, bufp)
Scan the cache for the name of the directory entry that points to vp. dvpp points to where a pointer to the encompassing directory will be stored. If bufp is not NULL, the name will be written to the end of the space between this pointer and the value in bpp, and bpp will be updated on return to point to the start of the copied name.

On success, *dvpp will be set to point to the encompassing directory and zero will be returned. If the cache misses, dvpp will be set to NULL and -1 will be returned. Otherwise, failure has occurred, dvpp will be set to NULL, and an appropriate error code will be returned.

The vfs_cache API is implemented in the file sys/kern/vfs_cache.c.

vmstat(8), namei(9), vfs(9), vnode(9), VOP_LOOKUP(9)

The vfs_cache API first appeared in 4.2BSD.

June 4, 2018 OpenBSD 7.5