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
This commit is contained in:
parent
4683b90591
commit
64f31d4f3b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=346137
@ -233,7 +233,17 @@ fuse_vnode_alloc(struct mount *mp,
|
|||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
if (*vpp) {
|
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");
|
SDT_PROBE2(fuse, , node, trace, 1, "vnode taken from hash");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -349,3 +349,23 @@ TEST_F(Lookup, subdir)
|
|||||||
*/
|
*/
|
||||||
ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno);
|
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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user