1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
.\" $OpenBSD: vfs_cache.9,v 1.2 2005/06/20 15:48:52 jaredy Exp $
.\" Written by Jared Yanovich <jaredy@openbsd.org>
.\" Public domain, 2005/6/17
.Dd June 17, 2005
.Dt VFS_CACHE 9
.Os
.Sh NAME
.Nm vfs_cache ,
.Nm cache_enter ,
.Nm cache_lookup ,
.Nm cache_purge ,
.Nm cache_purgevfs ,
.Nm cache_revlookup
.Nd name lookup cache
.Sh SYNOPSIS
.In sys/vnode.h
.In sys/namei.h
.Pp
.Ft int
.Fn cache_lookup "struct vnode *dvp" "struct vnode **vpp" \
"struct componentname *cnp"
.Ft void
.Fn cache_enter "struct vnode *dvp" "struct vnode *vp" \
"struct componentname *cnp"
.Ft void
.Fn cache_purge "struct vnode *vp"
.Ft void
.Fn cache_purgevfs "struct mount *mp"
.Ft int
.Fn cache_revlookup "struct vnode *vp" "struct vnode **dvpp" \
"char **bpp" "char *bufp"
.Sh DESCRIPTION
In order to speed up file name look-up operations (see
.Xr 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:
.Bd -literal
struct namecache {
LIST_ENTRY(namecache) nc_hash; /* hash chain */
LIST_ENTRY(namecache) nc_vhash; /* (reverse) dir hash chain */
TAILQ_ENTRY(namecache) nc_lru; /* LRU chain */
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[NCHNAMLEN]; /* segment name */
};
.Ed
.Pp
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.
.Pp
File names with length longer than
.Dv NCHNAMLEN
are not cached to simplify lookups and to save space.
Such names are rare and are generally not worth caching.
.Pp
The
.Nm vfs_cache
API contains the following routines:
.Bl -tag -width Ds
.It Fn cache_lookup dvp vpp cnp
Look up the given name in the cache.
.Fa dvp
points to the directory to search,
.Fa vpp
points to a pointer where the vnode of the name being sought will be
stored, and
.Fa cnp
contains the last component of the path name.
.Fa cnp
must have the
.Va cn_nameptr ,
.Va cn_namelen ,
and
.Va 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
.Xr namei 9
lookup operation was
.Dv DELETE
or the
.Dv NOCACHE
flag was set for the call to
.Xr namei 9 .
.Pp
Upon success, a pointer to a locked vnode is stored in
.Fa vpp
and a zero value is returned.
If locking the vnode fails, the vnode will remain unlocked,
.Fa *vpp
will be set to
.Dv NULL ,
and the corresponding error will be returned.
If the cache entry is negative cached, meaning the name is no longer
valid,
.Er ENOENT
is returned.
Otherwise, the cache lookup has failed and a \-1 value is returned.
.It Fn cache_enter dvp vp cnp
Add a new entry for the translation in the directory
.Fa dvp
for the vnode
.Fa vp
with name
.Fa cnp
to the cache.
.Fa cnp
must have the
.Va cn_nameptr ,
.Va cn_namelen ,
and
.Va cn_hash
fields filled in.
.It Fn cache_purge vp
Flush all cache entries corresponding with the given vnode
.Fa vp .
This is called after rename operations to hide entries that would no
longer be valid.
.It Fn cache_purgevfs mp
Flush all cache entries for name translations associated with the file
system mount described by
.Fa mp .
This is called when unmounting file systems, which would make all name
translations pertaining to the mount invalid.
.It Fn cache_revlookup vp dvpp bpp bufp
Scan the cache for the name of the directory entry that points to
.Fa vp .
.Fa dvpp
points to where a pointer to the encompassing directory will be stored.
If
.Fa bufp
is not
.Dv NULL ,
the name will be written to the end of the space between this pointer
and the value in
.Fa bpp ,
and
.Fa bpp
will be updated on return to point to the start of the copied name.
.Pp
On success,
.Fa *dvpp
will be set to point to the encompassing directory and zero will be
returned.
If the cache misses,
.Fa dvpp
will be set to
.Dv NULL
and \-1 will be returned.
Otherwise, failure has occurred,
.Fa dvpp
will be set to
.Dv NULL ,
and an appropriate error code will be returned.
.El
.Sh CODE REFERENCES
The
.Nm
API is implemented in the file
.Pa sys/kern/vfs_cache.c .
.Sh SEE ALSO
.Xr vmstat 8 ,
.Xr namei 9 ,
.Xr vfs 9 ,
.Xr vnode 9
.Sh HISTORY
The
.Nm
API first appeared in
.Bx 4.2 .
|