Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Apr 2019 17:23:34 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r346060 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Message-ID:  <201904091723.x39HNYGK086124@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Tue Apr  9 17:23:34 2019
New Revision: 346060
URL: https://svnweb.freebsd.org/changeset/base/346060

Log:
  fusefs: implement entry cache timeouts
  
  Follow-up to r346046.  These two commits implement fuse cache timeouts for
  both entries and attributes.  They also remove the vfs.fusefs.lookup_cache
  enable sysctl, which is no longer needed now that cache timeouts are
  honored.
  
  PR:		235773
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_internal.h
  projects/fuse2/sys/fs/fuse/fuse_node.c
  projects/fuse2/sys/fs/fuse/fuse_vnops.c
  projects/fuse2/tests/sys/fs/fusefs/lookup.cc

Modified: projects/fuse2/sys/fs/fuse/fuse_internal.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.h	Tue Apr  9 16:35:23 2019	(r346059)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.h	Tue Apr  9 17:23:34 2019	(r346060)
@@ -68,8 +68,6 @@
 #include "fuse_ipc.h"
 #include "fuse_node.h"
 
-extern int fuse_lookup_cache_expire;
-
 static inline bool
 vfs_isrdonly(struct mount *mp)
 {

Modified: projects/fuse2/sys/fs/fuse/fuse_node.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_node.c	Tue Apr  9 16:35:23 2019	(r346059)
+++ projects/fuse2/sys/fs/fuse/fuse_node.c	Tue Apr  9 17:23:34 2019	(r346060)
@@ -291,24 +291,21 @@ fuse_vnode_get(struct mount *mp,
 	if (dvp != NULL && cnp != NULL && (cnp->cn_flags & MAKEENTRY) != 0 &&
 	    feo != NULL &&
 	    (feo->entry_valid != 0 || feo->entry_valid_nsec != 0)) {
+		struct timespec duration, now, timeout;
+
 		ASSERT_VOP_LOCKED(*vpp, "fuse_vnode_get");
 		ASSERT_VOP_LOCKED(dvp, "fuse_vnode_get");
-		if (fuse_lookup_cache_expire) {
-			struct timespec duration, now, timeout;
 
-			getnanouptime(&now);
-			if (feo->entry_valid >= INT_MAX ||
-			    feo->entry_valid + now.tv_sec + 2 >= INT_MAX) {
-				timeout.tv_sec = INT_MAX;
-			} else {
-				duration.tv_sec = feo->entry_valid;
-				duration.tv_nsec = feo->entry_valid_nsec;
-				timespecadd(&duration, &now, &timeout);
-			}
-			cache_enter_time(dvp, *vpp, cnp, &timeout, NULL);
+		getnanouptime(&now);
+		if (feo->entry_valid >= INT_MAX ||
+		    feo->entry_valid + now.tv_sec + 2 >= INT_MAX) {
+			timeout.tv_sec = INT_MAX;
 		} else {
-			cache_enter(dvp, *vpp, cnp);
+			duration.tv_sec = feo->entry_valid;
+			duration.tv_nsec = feo->entry_valid_nsec;
+			timespecadd(&duration, &now, &timeout);
 		}
+		cache_enter_time(dvp, *vpp, cnp, &timeout, NULL);
 	}
 
 	/*

Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c	Tue Apr  9 16:35:23 2019	(r346059)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c	Tue Apr  9 17:23:34 2019	(r346060)
@@ -195,12 +195,6 @@ static u_long fuse_lookup_cache_misses = 0;
 SYSCTL_ULONG(_vfs_fusefs, OID_AUTO, lookup_cache_misses, CTLFLAG_RD,
     &fuse_lookup_cache_misses, 0, "number of cache misses in lookup");
 
-int	fuse_lookup_cache_expire = 0;
-
-SYSCTL_INT(_vfs_fusefs, OID_AUTO, lookup_cache_expire, CTLFLAG_RW,
-    &fuse_lookup_cache_expire, 0,
-    "if non-zero, expire fuse lookup cache entries at the proper time");
-
 /*
  * XXX: This feature is highly experimental and can bring to instabilities,
  * needs revisiting before to be enabled by default.
@@ -681,6 +675,8 @@ out:
 	return err;
 }
 
+SDT_PROBE_DEFINE3(fuse, , vnops, cache_lookup,
+	"int", "struct timespec*", "struct timespec*");
 /*
     struct vnop_lookup_args {
 	struct vnodeop_desc *a_desc;
@@ -750,21 +746,26 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
 		fdisp_init(&fdi, 0);
 		op = FUSE_GETATTR;
 		goto calldaemon;
-	} else if (fuse_lookup_cache_expire) {
+	} else {
 		struct timespec now, timeout;
 
 		err = cache_lookup(dvp, vpp, cnp, &timeout, NULL);
+		getnanouptime(&now);
+		SDT_PROBE3(fuse, , vnops, cache_lookup, err, &timeout, &now);
 		switch (err) {
-
 		case -1:		/* positive match */
-			getnanouptime(&now);
-			if (timespeccmp(&timeout, &now, <=)) {
+			if (timespeccmp(&timeout, &now, >)) {
 				atomic_add_acq_long(&fuse_lookup_cache_hits, 1);
 			} else {
 				/* Cache timeout */
 				atomic_add_acq_long(&fuse_lookup_cache_misses,
 					1);
-				cache_purge(*vpp);
+				fuse_internal_vnode_disappear(*vpp);
+				if (dvp != *vpp)
+					vput(*vpp);
+				else 
+					vrele(*vpp);
+				*vpp = NULL;
 				break;
 			}
 			return 0;
@@ -775,34 +776,15 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
 
 		case ENOENT:		/* negative match */
 			getnanouptime(&now);
-			if (timespeccmp(&timeout, &now, >)) {
+			if (timespeccmp(&timeout, &now, <=)) {
 				/* Cache timeout */
-				printf("Purging vnode %p name=%s\n", *vpp,
-					cnp->cn_nameptr);
-				fuse_internal_vnode_disappear(*vpp);
+				cache_purge_negative(dvp);
 				break;
 			}
 			/* fall through */
 		default:
 			return err;
 		}
-	} else {
-		err = cache_lookup(dvp, vpp, cnp, NULL, NULL);
-		switch (err) {
-
-		case -1:		/* positive match */
-			atomic_add_acq_long(&fuse_lookup_cache_hits, 1);
-			return 0;
-
-		case 0:		/* no match in cache */
-			atomic_add_acq_long(&fuse_lookup_cache_misses, 1);
-			break;
-
-		case ENOENT:		/* negative match */
-			/* fall through */
-		default:
-			return err;
-		}
 	}
 	nid = VTOI(dvp);
 	fdisp_init(&fdi, cnp->cn_namelen + 1);
@@ -817,13 +799,15 @@ calldaemon:
 	}
 	lookup_err = fdisp_wait_answ(&fdi);
 
-	if ((op == FUSE_LOOKUP) && !lookup_err) {	/* lookup call succeeded */
+	if ((op == FUSE_LOOKUP) && !lookup_err) {
+		/* lookup call succeeded */
 		nid = ((struct fuse_entry_out *)fdi.answ)->nodeid;
 		if (!nid) {
 			/*
 	                 * zero nodeid is the same as "not found",
 	                 * but it's also cacheable (which we keep
 	                 * keep on doing not as of writing this)
+			 * See PR 236226
 	                 */
 			fdi.answ_stat = ENOENT;
 			lookup_err = ENOENT;

Modified: projects/fuse2/tests/sys/fs/fusefs/lookup.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/lookup.cc	Tue Apr  9 16:35:23 2019	(r346059)
+++ projects/fuse2/tests/sys/fs/fusefs/lookup.cc	Tue Apr  9 17:23:34 2019	(r346060)
@@ -211,8 +211,7 @@ TEST_F(Lookup, entry_cache_negative_timeout)
  * If lookup returns a finite but non-zero entry cache timeout, then we should
  * discard the cached inode and requery the daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */
-TEST_F(Lookup, DISABLED_entry_cache_timeout)
+TEST_F(Lookup, entry_cache_timeout)
 {
 	const char FULLPATH[] = "mountpoint/some_file.txt";
 	const char RELPATH[] = "some_file.txt";



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