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