Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Oct 2009 16:34:29 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        arch@FreeBSD.org
Subject:   Put a timeout on -ve name cache entries in NFS
Message-ID:  <200910191634.30040.jhb@freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910191634.30040.jhb>