Put a timeout on -ve name cache entries in NFS
John Baldwin
jhb at freebsd.org
Mon Oct 19 20:34:39 UTC 2009
This patch allows one to put an upper time limit on how long the NFS client
should keep negative cache entries around for a given directory. This is
basically a safety belt as there are certain races with -ve entries that are
not easily fixed (e.g. dealing with the low resolution of the directory
modification timestamps). However, timing out the entries would put a limit
on how stale the client's cache entries could be. My main question is do
folks think this value should be tunable as a global sysctl or a per-mount
option. A sysctl is far easier to implement (and the acccess cache timeout
is a sysctl). However, the other namecache-related settings are all mount
options, so a mount option might be more consistent. Current rough patch is
below:
--- //depot/projects/smpng/sys/nfsclient/nfs_vnops.c 2009/10/19 14:27:26
+++ //depot/user/jhb/lock/nfsclient/nfs_vnops.c 2009/10/19 19:53:51
@@ -981,9 +981,11 @@
* We only accept a negative hit in the cache if the
* modification time of the parent directory matches
* our cached copy. Otherwise, we discard all of the
- * negative cache entries for this directory.
+ * negative cache entries for this directory. We also
+ * only trust -ve cache entries for up to 5 seconds.
*/
- if (VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 &&
+ if ((u_int)(ticks - np->n_dmtime_ticks) <= 5 &&
+ VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 &&
vattr.va_mtime.tv_sec == np->n_dmtime) {
nfsstats.lookupcache_hits++;
return (ENOENT);
@@ -1157,8 +1159,10 @@
*/
mtx_lock(&np->n_mtx);
if (np->n_dmtime <= dmtime) {
- if (np->n_dmtime == 0)
+ if (np->n_dmtime == 0) {
np->n_dmtime = dmtime;
+ np->n_dmtime_ticks = ticks;
+ }
mtx_unlock(&np->n_mtx);
cache_enter(dvp, NULL, cnp);
} else
--- //depot/projects/smpng/sys/nfsclient/nfsnode.h 2009/05/29 14:35:29
+++ //depot/user/jhb/lock/nfsclient/nfsnode.h 2009/10/19 19:53:51
@@ -119,6 +119,7 @@
struct vnode *n_vnode; /* associated vnode */
struct vnode *n_dvp; /* parent vnode */
int n_error; /* Save write error value */
+ int n_dmtime_ticks; /* When n_dmtime was last set */
union {
struct timespec nf_atim; /* Special file times */
nfsuint64 nd_cookieverf; /* Cookie verifier (dir only) */
--
John Baldwin
More information about the freebsd-arch
mailing list