fusefs: correctly handle cacheable negative LOOKUP responses
The FUSE protocol allows for LOOKUP to return a cacheable negative response, which means that the file doesn't exist and the kernel can cache its nonexistence. As of this commit fusefs doesn't cache the nonexistence, but it does correctly handle such responses. Prior to this commit attempting to create a file, even with O_CREAT would fail with ENOENT if the daemon returned a cacheable negative response. PR: 236231 Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
915012e0d0
commit
6248288e97
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=345399
@ -747,6 +747,7 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
|
||||
* but it's also cacheable (which we keep
|
||||
* keep on doing not as of writing this)
|
||||
*/
|
||||
fdi.answ_stat = ENOENT;
|
||||
lookup_err = ENOENT;
|
||||
} else if (nid == FUSE_ROOT_ID) {
|
||||
lookup_err = EINVAL;
|
||||
|
@ -185,8 +185,7 @@ TEST_F(Create, DISABLED_Enosys)
|
||||
/*
|
||||
* Creating a new file after FUSE_LOOKUP returned a negative cache entry
|
||||
*/
|
||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236231 */
|
||||
TEST_F(Create, DISABLED_entry_cache_negative)
|
||||
TEST_F(Create, entry_cache_negative)
|
||||
{
|
||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||
const char RELPATH[] = "some_file.txt";
|
||||
@ -240,8 +239,7 @@ TEST_F(Create, DISABLED_entry_cache_negative)
|
||||
/*
|
||||
* Creating a new file should purge any negative namecache entries
|
||||
*/
|
||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236231 */
|
||||
TEST_F(Create, DISABLED_entry_cache_negative_purge)
|
||||
TEST_F(Create, entry_cache_negative_purge)
|
||||
{
|
||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||
const char RELPATH[] = "some_file.txt";
|
||||
|
@ -69,8 +69,7 @@ TEST_F(Mkdir, emlink)
|
||||
/*
|
||||
* Creating a new directory after FUSE_LOOKUP returned a negative cache entry
|
||||
*/
|
||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236231 */
|
||||
TEST_F(Mkdir, DISABLED_entry_cache_negative)
|
||||
TEST_F(Mkdir, entry_cache_negative)
|
||||
{
|
||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||
const char RELPATH[] = "some_file.txt";
|
||||
@ -109,8 +108,7 @@ TEST_F(Mkdir, DISABLED_entry_cache_negative)
|
||||
/*
|
||||
* Creating a new directory should purge any negative namecache entries
|
||||
*/
|
||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236231 */
|
||||
TEST_F(Mkdir, DISABLED_entry_cache_negative_purge)
|
||||
TEST_F(Mkdir, entry_cache_negative_purge)
|
||||
{
|
||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||
const char RELPATH[] = "some_file.txt";
|
||||
|
@ -86,8 +86,7 @@ TEST_F(Rename, enoent)
|
||||
/*
|
||||
* Renaming a file after FUSE_LOOKUP returned a negative cache entry for dst
|
||||
*/
|
||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236231 */
|
||||
TEST_F(Rename, DISABLED_entry_cache_negative)
|
||||
TEST_F(Rename, entry_cache_negative)
|
||||
{
|
||||
const char FULLDST[] = "mountpoint/dst";
|
||||
const char RELDST[] = "dst";
|
||||
@ -126,8 +125,7 @@ TEST_F(Rename, DISABLED_entry_cache_negative)
|
||||
/*
|
||||
* Renaming a file should purge any negative namecache entries for the dst
|
||||
*/
|
||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236231 */
|
||||
TEST_F(Rename, DISABLED_entry_cache_negative_purge)
|
||||
TEST_F(Rename, entry_cache_negative_purge)
|
||||
{
|
||||
const char FULLDST[] = "mountpoint/dst";
|
||||
const char RELDST[] = "dst";
|
||||
@ -136,12 +134,7 @@ TEST_F(Rename, DISABLED_entry_cache_negative_purge)
|
||||
// FUSE hardcodes the mountpoint to inode 1
|
||||
uint64_t dst_dir_ino = 1;
|
||||
uint64_t ino = 42;
|
||||
/*
|
||||
* Set entry_valid = 0 because this test isn't concerned with whether
|
||||
* or not we actually cache negative entries, only with whether we
|
||||
* interpret negative cache responses correctly.
|
||||
*/
|
||||
struct timespec entry_valid = {.tv_sec = 0, .tv_nsec = 0};
|
||||
struct timespec entry_valid = {.tv_sec = TIME_T_MAX, .tv_nsec = 0};
|
||||
|
||||
expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1);
|
||||
/* LOOKUP returns a negative cache entry for dst */
|
||||
@ -164,7 +157,7 @@ TEST_F(Rename, DISABLED_entry_cache_negative_purge)
|
||||
ASSERT_EQ(0, rename(FULLSRC, FULLDST)) << strerror(errno);
|
||||
|
||||
/* Finally, a subsequent lookup should query the daemon */
|
||||
expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1);
|
||||
expect_lookup(RELDST, ino, S_IFREG | 0644, 0, 1);
|
||||
|
||||
ASSERT_EQ(0, access(FULLDST, F_OK)) << strerror(errno);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user