svn commit: r346137 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs

Alan Somers asomers at FreeBSD.org
Thu Apr 11 22:32:36 UTC 2019


Author: asomers
Date: Thu Apr 11 22:32:34 2019
New Revision: 346137
URL: https://svnweb.freebsd.org/changeset/base/346137

Log:
  fusefs: fix a panic in a stale vnode situation
  
  Don't panic if the server changes the file type of a file without us first
  deleting it.  That could indicate a buggy server, but it could also be the
  result of one of several race conditions.  Return EAGAIN as we do elsewhere.
  
  Sponsored by:	The FreeBSD Foundation

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

Modified: projects/fuse2/sys/fs/fuse/fuse_node.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_node.c	Thu Apr 11 21:13:54 2019	(r346136)
+++ projects/fuse2/sys/fs/fuse/fuse_node.c	Thu Apr 11 22:32:34 2019	(r346137)
@@ -233,7 +233,17 @@ fuse_vnode_alloc(struct mount *mp,
 		return (err);
 
 	if (*vpp) {
-		MPASS((*vpp)->v_type == vtyp && (*vpp)->v_data != NULL);
+		if ((*vpp)->v_type != vtyp) {
+			/*
+			 * STALE vnode!  This probably indicates a buggy
+			 * server, but it could also be the result of a race
+			 * between FUSE_LOOKUP and another client's
+			 * FUSE_UNLINK/FUSE_CREATE
+			 */
+			fuse_internal_vnode_disappear(*vpp);
+			return (EAGAIN);
+		}
+		MPASS((*vpp)->v_data != NULL);
 		SDT_PROBE2(fuse, , node, trace, 1, "vnode taken from hash");
 		return (0);
 	}

Modified: projects/fuse2/tests/sys/fs/fusefs/lookup.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/lookup.cc	Thu Apr 11 21:13:54 2019	(r346136)
+++ projects/fuse2/tests/sys/fs/fusefs/lookup.cc	Thu Apr 11 22:32:34 2019	(r346137)
@@ -349,3 +349,23 @@ TEST_F(Lookup, subdir)
 	 */
 	ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno);
 }
+
+/* 
+ * The server returns two different vtypes for the same nodeid.  This is a bad
+ * server!  But we shouldn't crash.
+ */
+TEST_F(Lookup, vtype_conflict)
+{
+	const char FIRSTFULLPATH[] = "mountpoint/foo";
+	const char SECONDFULLPATH[] = "mountpoint/bar";
+	const char FIRSTRELPATH[] = "foo";
+	const char SECONDRELPATH[] = "bar";
+	uint64_t ino = 42;
+
+	expect_lookup(FIRSTRELPATH, ino, S_IFREG | 0644, 0, 1, UINT64_MAX);
+	expect_lookup(SECONDRELPATH, ino, S_IFDIR | 0755, 0, 1, UINT64_MAX);
+
+	ASSERT_EQ(0, access(FIRSTFULLPATH, F_OK)) << strerror(errno);
+	ASSERT_EQ(-1, access(SECONDFULLPATH, F_OK));
+	ASSERT_EQ(EAGAIN, errno);
+}


More information about the svn-src-projects mailing list