Date: Thu, 11 Apr 2019 22:32:35 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r346137 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs Message-ID: <201904112232.x3BMWZic075577@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904112232.x3BMWZic075577>