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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user