svn commit: r346137 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Alan Somers
asomers at FreeBSD.org
Tue Sep 3 14:06:44 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