From 1f9aeb4e2fe414905770bacc3dfa64c49a877562 Mon Sep 17 00:00:00 2001 From: asomers Date: Fri, 15 Mar 2019 22:47:20 +0000 Subject: [PATCH] fuse(4): add tests for the FOPEN_KEEP_CACHE option PR: 236560 Sponsored by: The FreeBSD Foundation --- tests/sys/fs/fuse/access.cc | 2 +- tests/sys/fs/fuse/create.cc | 2 +- tests/sys/fs/fuse/destroy.cc | 2 +- tests/sys/fs/fuse/flush.cc | 2 +- tests/sys/fs/fuse/fsync.cc | 2 +- tests/sys/fs/fuse/fsyncdir.cc | 2 +- tests/sys/fs/fuse/getattr.cc | 6 +- tests/sys/fs/fuse/interrupt.cc | 2 +- tests/sys/fs/fuse/link.cc | 2 +- tests/sys/fs/fuse/locks.cc | 2 +- tests/sys/fs/fuse/mkdir.cc | 2 +- tests/sys/fs/fuse/open.cc | 6 +- tests/sys/fs/fuse/opendir.cc | 2 +- tests/sys/fs/fuse/read.cc | 108 +++++++++++++++++++++++++++----- tests/sys/fs/fuse/readdir.cc | 2 +- tests/sys/fs/fuse/readlink.cc | 2 +- tests/sys/fs/fuse/release.cc | 2 +- tests/sys/fs/fuse/releasedir.cc | 2 +- tests/sys/fs/fuse/rename.cc | 16 ++--- tests/sys/fs/fuse/unlink.cc | 2 +- tests/sys/fs/fuse/utils.cc | 3 +- tests/sys/fs/fuse/utils.hh | 4 +- tests/sys/fs/fuse/write.cc | 36 +++++------ tests/sys/fs/fuse/xattr.cc | 44 ++++++------- 24 files changed, 165 insertions(+), 90 deletions(-) diff --git a/tests/sys/fs/fuse/access.cc b/tests/sys/fs/fuse/access.cc index 4f932675e336..5ceaf567a678 100644 --- a/tests/sys/fs/fuse/access.cc +++ b/tests/sys/fs/fuse/access.cc @@ -55,7 +55,7 @@ void expect_access(uint64_t ino, mode_t access_mode, int error) void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); } }; diff --git a/tests/sys/fs/fuse/create.cc b/tests/sys/fs/fuse/create.cc index 99b7d3d85fa1..088569cb2e4e 100644 --- a/tests/sys/fs/fuse/create.cc +++ b/tests/sys/fs/fuse/create.cc @@ -288,7 +288,7 @@ TEST_F(Create, DISABLED_entry_cache_negative_purge) ASSERT_LE(0, fd) << strerror(errno); /* Finally, a subsequent lookup should query the daemon */ - expect_lookup(RELPATH, ino, S_IFREG | mode, 1); + expect_lookup(RELPATH, ino, S_IFREG | mode, 0, 1); ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ diff --git a/tests/sys/fs/fuse/destroy.cc b/tests/sys/fs/fuse/destroy.cc index e63e37df600c..da3647ffff6d 100644 --- a/tests/sys/fs/fuse/destroy.cc +++ b/tests/sys/fs/fuse/destroy.cc @@ -72,7 +72,7 @@ TEST_F(Destroy, ok) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 2); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2); expect_forget(1, 1); expect_forget(ino, 2); expect_destroy(0); diff --git a/tests/sys/fs/fuse/flush.cc b/tests/sys/fs/fuse/flush.cc index 887a0462d71b..d7fd02ad420d 100644 --- a/tests/sys/fs/fuse/flush.cc +++ b/tests/sys/fs/fuse/flush.cc @@ -57,7 +57,7 @@ void expect_flush(uint64_t ino, int times, pid_t lo, ProcessMockerT r) void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); } /* diff --git a/tests/sys/fs/fuse/fsync.cc b/tests/sys/fs/fuse/fsync.cc index c2f808a51b62..9894a3d2888a 100644 --- a/tests/sys/fs/fuse/fsync.cc +++ b/tests/sys/fs/fuse/fsync.cc @@ -65,7 +65,7 @@ void expect_fsync(uint64_t ino, uint32_t flags, int error) void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); } void expect_write(uint64_t ino, uint64_t size, const void *contents) diff --git a/tests/sys/fs/fuse/fsyncdir.cc b/tests/sys/fs/fuse/fsyncdir.cc index c600185d1407..a36a53a304b2 100644 --- a/tests/sys/fs/fuse/fsyncdir.cc +++ b/tests/sys/fs/fuse/fsyncdir.cc @@ -66,7 +66,7 @@ void expect_fsyncdir(uint64_t ino, uint32_t flags, int error) void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 1); + FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 0, 1); } }; diff --git a/tests/sys/fs/fuse/getattr.cc b/tests/sys/fs/fuse/getattr.cc index fc024be692ff..9e81b3b46ab1 100644 --- a/tests/sys/fs/fuse/getattr.cc +++ b/tests/sys/fs/fuse/getattr.cc @@ -88,7 +88,7 @@ TEST_F(Getattr, attr_cache_timeout) */ long timeout_ns = 250'000'000; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 2); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { return (in->header.opcode == FUSE_GETATTR && @@ -116,7 +116,7 @@ TEST_F(Getattr, enoent) struct stat sb; const uint64_t ino = 42; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { return (in->header.opcode == FUSE_GETATTR && @@ -135,7 +135,7 @@ TEST_F(Getattr, ok) const uint64_t ino = 42; struct stat sb; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 1, 1); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { return (in->header.opcode == FUSE_GETATTR && diff --git a/tests/sys/fs/fuse/interrupt.cc b/tests/sys/fs/fuse/interrupt.cc index 3c4767845e7d..86135162587c 100644 --- a/tests/sys/fs/fuse/interrupt.cc +++ b/tests/sys/fs/fuse/interrupt.cc @@ -66,7 +66,7 @@ Interrupt(): m_child(NULL) {}; void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); } /* diff --git a/tests/sys/fs/fuse/link.cc b/tests/sys/fs/fuse/link.cc index feca5254e8bc..55a1785e342a 100644 --- a/tests/sys/fs/fuse/link.cc +++ b/tests/sys/fs/fuse/link.cc @@ -41,7 +41,7 @@ class Link: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); } }; diff --git a/tests/sys/fs/fuse/locks.cc b/tests/sys/fs/fuse/locks.cc index 90ba5e34db10..a1d37357ffb1 100644 --- a/tests/sys/fs/fuse/locks.cc +++ b/tests/sys/fs/fuse/locks.cc @@ -46,7 +46,7 @@ public: void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); } }; diff --git a/tests/sys/fs/fuse/mkdir.cc b/tests/sys/fs/fuse/mkdir.cc index bff635f12a9e..c6b0b0945a39 100644 --- a/tests/sys/fs/fuse/mkdir.cc +++ b/tests/sys/fs/fuse/mkdir.cc @@ -143,7 +143,7 @@ TEST_F(Mkdir, DISABLED_entry_cache_negative_purge) ASSERT_EQ(0, mkdir(FULLPATH, mode)) << strerror(errno); /* Finally, a subsequent lookup should query the daemon */ - expect_lookup(RELPATH, ino, S_IFDIR | mode, 1); + expect_lookup(RELPATH, ino, S_IFDIR | mode, 0, 1); ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno); } diff --git a/tests/sys/fs/fuse/open.cc b/tests/sys/fs/fuse/open.cc index 136f0441177e..220f2a79818d 100644 --- a/tests/sys/fs/fuse/open.cc +++ b/tests/sys/fs/fuse/open.cc @@ -48,7 +48,7 @@ void test_ok(int os_flags, int fuse_flags) { uint64_t ino = 42; int fd; - FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_OPEN && @@ -92,7 +92,7 @@ TEST_F(Open, enoent) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_OPEN && @@ -114,7 +114,7 @@ TEST_F(Open, eperm) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_OPEN && diff --git a/tests/sys/fs/fuse/opendir.cc b/tests/sys/fs/fuse/opendir.cc index 0b3bd162ec45..94ceb69555eb 100644 --- a/tests/sys/fs/fuse/opendir.cc +++ b/tests/sys/fs/fuse/opendir.cc @@ -42,7 +42,7 @@ class Opendir: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 1); + FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 0, 1); } }; diff --git a/tests/sys/fs/fuse/read.cc b/tests/sys/fs/fuse/read.cc index 42072f8193fe..15d73aa919ad 100644 --- a/tests/sys/fs/fuse/read.cc +++ b/tests/sys/fs/fuse/read.cc @@ -48,9 +48,9 @@ using namespace testing; class Read: public FuseTest { public: -void expect_lookup(const char *relpath, uint64_t ino) +void expect_lookup(const char *relpath, uint64_t ino, uint64_t size) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, size, 1); } }; @@ -97,7 +97,7 @@ TEST_F(AioRead, aio_read) char buf[bufsize]; struct aiocb iocb, *piocb; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); @@ -132,7 +132,7 @@ TEST_F(AioRead, async_read_disabled) off_t off1 = 4096; struct aiocb iocb0, iocb1; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( @@ -210,7 +210,7 @@ TEST_F(AsyncRead, DISABLED_async_read) off_t off1 = 4096; struct aiocb iocb0, iocb1; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( @@ -279,7 +279,7 @@ TEST_F(Read, direct_io_read_nothing) uint64_t offset = 100; char buf[80]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, offset + 1000); expect_open(ino, FOPEN_DIRECT_IO, 1); expect_getattr(ino, offset + 1000); @@ -305,7 +305,7 @@ TEST_F(Read, direct_io_pread) ssize_t bufsize = strlen(CONTENTS); char buf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, offset + bufsize); expect_open(ino, FOPEN_DIRECT_IO, 1); expect_getattr(ino, offset + bufsize); expect_read(ino, offset, bufsize, bufsize, CONTENTS); @@ -334,7 +334,7 @@ TEST_F(Read, direct_io_short_read) ssize_t halfbufsize = bufsize / 2; char buf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, offset + bufsize); expect_open(ino, FOPEN_DIRECT_IO, 1); expect_getattr(ino, offset + bufsize); expect_read(ino, offset, bufsize, halfbufsize, CONTENTS); @@ -358,7 +358,7 @@ TEST_F(Read, eio) ssize_t bufsize = strlen(CONTENTS); char buf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( @@ -376,6 +376,79 @@ TEST_F(Read, eio) /* Deliberately leak fd. close(2) will be tested in release.cc */ } +/* + * With the keep_cache option, the kernel may keep its read cache across + * multiple open(2)s. + */ +/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236560 */ +TEST_F(Read, DISABLED_keep_cache) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + const char *CONTENTS = "abcdefgh"; + uint64_t ino = 42; + int fd0, fd1; + ssize_t bufsize = strlen(CONTENTS); + char buf[bufsize]; + + FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2); + expect_open(ino, FOPEN_KEEP_CACHE, 1); + expect_getattr(ino, bufsize); + expect_read(ino, 0, bufsize, bufsize, CONTENTS); + + fd0 = open(FULLPATH, O_RDONLY); + ASSERT_LE(0, fd0) << strerror(errno); + ASSERT_EQ(bufsize, read(fd0, buf, bufsize)) << strerror(errno); + + fd1 = open(FULLPATH, O_RDONLY); + ASSERT_LE(0, fd1) << strerror(errno); + + /* + * This read should be serviced by cache, even though it's on the other + * file descriptor + */ + ASSERT_EQ(bufsize, read(fd1, buf, bufsize)) << strerror(errno); + + /* Deliberately leak fd0 and fd1. */ +} + +/* + * Without the keep_cache option, the kernel should drop its read caches on + * every open + */ +TEST_F(Read, keep_cache_disabled) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + const char *CONTENTS = "abcdefgh"; + uint64_t ino = 42; + int fd0, fd1; + ssize_t bufsize = strlen(CONTENTS); + char buf[bufsize]; + + FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2); + expect_open(ino, FOPEN_KEEP_CACHE, 1); + expect_getattr(ino, bufsize); + expect_read(ino, 0, bufsize, bufsize, CONTENTS); + + fd0 = open(FULLPATH, O_RDONLY); + ASSERT_LE(0, fd0) << strerror(errno); + ASSERT_EQ(bufsize, read(fd0, buf, bufsize)) << strerror(errno); + + fd1 = open(FULLPATH, O_RDONLY); + ASSERT_LE(0, fd1) << strerror(errno); + + /* + * This read should not be serviced by cache, even though it's on the + * original file descriptor + */ + expect_read(ino, 0, bufsize, bufsize, CONTENTS); + ASSERT_EQ(0, lseek(fd0, 0, SEEK_SET)) << strerror(errno); + ASSERT_EQ(bufsize, read(fd0, buf, bufsize)) << strerror(errno); + + /* Deliberately leak fd0 and fd1. */ +} + TEST_F(Read, mmap) { const char FULLPATH[] = "mountpoint/some_file.txt"; @@ -390,7 +463,7 @@ TEST_F(Read, mmap) len = getpagesize(); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); /* mmap may legitimately try to read more data than is available */ @@ -434,7 +507,7 @@ TEST_F(Read, o_direct) ssize_t bufsize = strlen(CONTENTS); char buf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); @@ -471,7 +544,7 @@ TEST_F(Read, pread) ssize_t bufsize = strlen(CONTENTS); char buf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, offset + bufsize); expect_open(ino, 0, 1); expect_getattr(ino, offset + bufsize); expect_read(ino, offset, bufsize, bufsize, CONTENTS); @@ -494,7 +567,7 @@ TEST_F(Read, read) ssize_t bufsize = strlen(CONTENTS); char buf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); @@ -504,6 +577,7 @@ TEST_F(Read, read) ASSERT_EQ(bufsize, read(fd, buf, bufsize)) << strerror(errno); ASSERT_EQ(0, memcmp(buf, CONTENTS, bufsize)); + /* Deliberately leak fd. close(2) will be tested in release.cc */ } @@ -527,7 +601,7 @@ TEST_F(Read, default_readahead) ASSERT_NE(NULL, contents); memmove(contents, CONTENTS0, strlen(CONTENTS0)); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, filesize); expect_open(ino, 0, 1); expect_getattr(ino, filesize); expect_read(ino, 0, default_maxreadahead, default_maxreadahead, @@ -558,7 +632,7 @@ TEST_F(Read, sendfile) int sp[2]; off_t sbytes; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); /* Like mmap, sendfile may request more data than is available */ @@ -604,7 +678,7 @@ TEST_F(Read, DISABLED_sendfile_eio) int sp[2]; off_t sbytes; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( @@ -646,7 +720,7 @@ TEST_P(ReadAhead, DISABLED_readahead) { ASSERT_NE(NULL, contents); memmove(contents, CONTENTS0, strlen(CONTENTS0)); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, filesize); expect_open(ino, 0, 1); expect_getattr(ino, filesize); /* fuse(4) should only read ahead the allowed amount */ diff --git a/tests/sys/fs/fuse/readdir.cc b/tests/sys/fs/fuse/readdir.cc index a828559d8005..13387bf8d567 100644 --- a/tests/sys/fs/fuse/readdir.cc +++ b/tests/sys/fs/fuse/readdir.cc @@ -43,7 +43,7 @@ class Readdir: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 1); + FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 0, 1); } void expect_readdir(uint64_t ino, uint64_t off, vector &ents) diff --git a/tests/sys/fs/fuse/readlink.cc b/tests/sys/fs/fuse/readlink.cc index 5ca85c2bfa53..918bd885660e 100644 --- a/tests/sys/fs/fuse/readlink.cc +++ b/tests/sys/fs/fuse/readlink.cc @@ -41,7 +41,7 @@ class Readlink: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFLNK | 0777, 1); + FuseTest::expect_lookup(relpath, ino, S_IFLNK | 0777, 0, 1); } }; diff --git a/tests/sys/fs/fuse/release.cc b/tests/sys/fs/fuse/release.cc index 71221104375c..88edb45a0806 100644 --- a/tests/sys/fs/fuse/release.cc +++ b/tests/sys/fs/fuse/release.cc @@ -43,7 +43,7 @@ class Release: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino, int times) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, times); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, times); } }; diff --git a/tests/sys/fs/fuse/releasedir.cc b/tests/sys/fs/fuse/releasedir.cc index 72eabf74fcc1..0976cdd268d1 100644 --- a/tests/sys/fs/fuse/releasedir.cc +++ b/tests/sys/fs/fuse/releasedir.cc @@ -42,7 +42,7 @@ class ReleaseDir: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino) { - FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 1); + FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 0, 1); } void expect_releasedir(uint64_t ino, ProcessMockerT r) diff --git a/tests/sys/fs/fuse/rename.cc b/tests/sys/fs/fuse/rename.cc index ed37f3f8ba14..81c039add5b4 100644 --- a/tests/sys/fs/fuse/rename.cc +++ b/tests/sys/fs/fuse/rename.cc @@ -62,7 +62,7 @@ TEST_F(Rename, einval) const char RELSRC[] = "src"; uint64_t src_ino = 42; - expect_lookup(RELSRC, src_ino, S_IFDIR | 0755, 2); + expect_lookup(RELSRC, src_ino, S_IFDIR | 0755, 0, 2); EXPECT_LOOKUP(src_ino, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); ASSERT_NE(0, rename(FULLSRC, FULLDST)); @@ -103,7 +103,7 @@ TEST_F(Rename, DISABLED_entry_cache_negative) */ struct timespec entry_valid = {.tv_sec = 0, .tv_nsec = 0}; - expect_lookup(RELSRC, ino, S_IFREG | 0644, 1); + expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1); /* LOOKUP returns a negative cache entry for dst */ EXPECT_LOOKUP(1, RELDST).WillOnce(ReturnNegativeCache(&entry_valid)); @@ -143,7 +143,7 @@ TEST_F(Rename, DISABLED_entry_cache_negative_purge) */ struct timespec entry_valid = {.tv_sec = 0, .tv_nsec = 0}; - expect_lookup(RELSRC, ino, S_IFREG | 0644, 1); + expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1); /* LOOKUP returns a negative cache entry for dst */ EXPECT_LOOKUP(1, RELDST).WillOnce(ReturnNegativeCache(&entry_valid)) .RetiresOnSaturation(); @@ -164,7 +164,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, 1); + expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1); ASSERT_EQ(0, access(FULLDST, F_OK)) << strerror(errno); } @@ -179,7 +179,7 @@ TEST_F(Rename, exdev) tmpfd = mkstemp(tmpfile); ASSERT_LE(0, tmpfd) << strerror(errno); - expect_lookup(RELB, b_ino, S_IFREG | 0644, 2); + expect_lookup(RELB, b_ino, S_IFREG | 0644, 0, 2); ASSERT_NE(0, rename(tmpfile, FULLB)); ASSERT_EQ(EXDEV, errno); @@ -198,7 +198,7 @@ TEST_F(Rename, ok) uint64_t dst_dir_ino = 1; uint64_t ino = 42; - expect_lookup(RELSRC, ino, S_IFREG | 0644, 1); + expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1); EXPECT_LOOKUP(1, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( @@ -230,8 +230,8 @@ TEST_F(Rename, overwrite) uint64_t dst_dir_ino = 1; uint64_t ino = 42; - expect_lookup(RELSRC, ino, S_IFREG | 0644, 1); - expect_lookup(RELDST, dst_ino, S_IFREG | 0644, 1); + expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1); + expect_lookup(RELDST, dst_ino, S_IFREG | 0644, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { const char *src = (const char*)in->body.bytes + diff --git a/tests/sys/fs/fuse/unlink.cc b/tests/sys/fs/fuse/unlink.cc index d2ab0cb9bfe4..bdcdf4b8e151 100644 --- a/tests/sys/fs/fuse/unlink.cc +++ b/tests/sys/fs/fuse/unlink.cc @@ -40,7 +40,7 @@ class Unlink: public FuseTest { public: void expect_lookup(const char *relpath, uint64_t ino, int times) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, times); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, times); } void expect_unlink(uint64_t parent, const char *path, int error) diff --git a/tests/sys/fs/fuse/utils.cc b/tests/sys/fs/fuse/utils.cc index f7bb4a30dfa3..abf5e378149f 100644 --- a/tests/sys/fs/fuse/utils.cc +++ b/tests/sys/fs/fuse/utils.cc @@ -103,7 +103,7 @@ void FuseTest::expect_getattr(uint64_t ino, uint64_t size) } void FuseTest::expect_lookup(const char *relpath, uint64_t ino, mode_t mode, - int times) + uint64_t size, int times) { EXPECT_LOOKUP(1, relpath) .Times(times) @@ -113,6 +113,7 @@ void FuseTest::expect_lookup(const char *relpath, uint64_t ino, mode_t mode, out->body.entry.nodeid = ino; out->body.entry.attr.nlink = 1; out->body.entry.attr_valid = UINT64_MAX; + out->body.entry.attr.size = size; }))); } diff --git a/tests/sys/fs/fuse/utils.hh b/tests/sys/fs/fuse/utils.hh index 51b43ee7ba31..adaaebb40105 100644 --- a/tests/sys/fs/fuse/utils.hh +++ b/tests/sys/fs/fuse/utils.hh @@ -73,10 +73,10 @@ class FuseTest : public ::testing::Test { /* * Create an expectation that FUSE_LOOKUP will be called for the given * path exactly times times. It will respond with inode ino, mode - * mode, and cache validity forever. + * mode, filesize size, and cache validity forever. */ void expect_lookup(const char *relpath, uint64_t ino, mode_t mode, - int times); + uint64_t size, int times); /* * Create an expectation that FUSE_GETATTR will be called for the given diff --git a/tests/sys/fs/fuse/write.cc b/tests/sys/fs/fuse/write.cc index 67af1e38bb3d..a57a7e322495 100644 --- a/tests/sys/fs/fuse/write.cc +++ b/tests/sys/fs/fuse/write.cc @@ -49,9 +49,9 @@ class Write: public FuseTest { public: -void expect_lookup(const char *relpath, uint64_t ino) +void expect_lookup(const char *relpath, uint64_t ino, uint64_t size) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, size, 1); } void expect_release(uint64_t ino, ProcessMockerT r) @@ -146,7 +146,7 @@ TEST_F(AioWrite, DISABLED_aio_write) ssize_t bufsize = strlen(CONTENTS); struct aiocb iocb, *piocb; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); @@ -190,7 +190,7 @@ TEST_F(Write, append) require_sync_resize_0(); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, initial_offset); expect_open(ino, 0, 1); expect_getattr(ino, initial_offset); expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS); @@ -213,7 +213,7 @@ TEST_F(Write, append_direct_io) uint64_t initial_offset = 4096; int fd; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, initial_offset); expect_open(ino, FOPEN_DIRECT_IO, 1); expect_getattr(ino, initial_offset); expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS); @@ -238,7 +238,7 @@ TEST_F(Write, DISABLED_direct_io_evicts_cache) ssize_t bufsize = strlen(CONTENTS0) + 1; char readbuf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS0); @@ -281,7 +281,7 @@ TEST_F(Write, DISABLED_direct_io_short_write) ssize_t halfbufsize = bufsize / 2; const char *halfcontents = CONTENTS + halfbufsize; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, FOPEN_DIRECT_IO, 1); expect_getattr(ino, 0); expect_write(ino, 0, bufsize, halfbufsize, 0, CONTENTS); @@ -316,7 +316,7 @@ TEST_F(Write, DISABLED_direct_io_short_write_iov) ssize_t totalsize = size0 + size1; struct iovec iov[2]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, FOPEN_DIRECT_IO, 1); expect_getattr(ino, 0); expect_write(ino, 0, totalsize, size0, 0, EXPECTED0); @@ -360,7 +360,7 @@ TEST_F(Write, DISABLED_mmap) ASSERT_NE(NULL, expected); memmove((uint8_t*)expected + offset, CONTENTS, bufsize); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, len); expect_open(ino, 0, 1); expect_getattr(ino, len); expect_read(ino, 0, len, len, zeros); @@ -396,7 +396,7 @@ TEST_F(Write, pwrite) int fd; ssize_t bufsize = strlen(CONTENTS); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); @@ -418,7 +418,7 @@ TEST_F(Write, write) int fd; ssize_t bufsize = strlen(CONTENTS); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); @@ -448,7 +448,7 @@ TEST_F(Write, write_large) contents[i] = i; } - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, 0, halfbufsize, halfbufsize, 0, contents); @@ -473,7 +473,7 @@ TEST_F(Write, write_nothing) int fd; ssize_t bufsize = 0; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); @@ -494,7 +494,7 @@ TEST_F(WriteBack, close) int fd; ssize_t bufsize = strlen(CONTENTS); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); @@ -529,7 +529,7 @@ TEST_F(WriteBack, writeback) ssize_t bufsize = strlen(CONTENTS); char readbuf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); @@ -562,7 +562,7 @@ TEST_F(WriteBack, o_direct) ssize_t bufsize = strlen(CONTENTS); char readbuf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); @@ -596,7 +596,7 @@ TEST_F(WriteThrough, DISABLED_writethrough) ssize_t bufsize = strlen(CONTENTS); char readbuf[bufsize]; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); @@ -625,7 +625,7 @@ TEST_F(WriteThrough, DISABLED_update_file_size) int fd; ssize_t bufsize = strlen(CONTENTS); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { diff --git a/tests/sys/fs/fuse/xattr.cc b/tests/sys/fs/fuse/xattr.cc index 3cd51e2d3e92..6cd5263d7ec0 100644 --- a/tests/sys/fs/fuse/xattr.cc +++ b/tests/sys/fs/fuse/xattr.cc @@ -121,7 +121,7 @@ TEST_F(Getxattr, enoattr) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_getxattr(ino, "user.foo", ReturnErrno(ENOATTR)); r = extattr_get_file(FULLPATH, ns, "foo", data, sizeof(data)); @@ -142,7 +142,7 @@ TEST_F(Getxattr, DISABLED_enosys) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_getxattr(ino, "user.foo", ReturnErrno(ENOSYS)); r = extattr_get_file(FULLPATH, ns, "foo", data, sizeof(data)); @@ -174,7 +174,7 @@ TEST_F(Getxattr, erange) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_getxattr(ino, "user.foo", ReturnErrno(ERANGE)); r = extattr_get_file(FULLPATH, ns, "foo", data, sizeof(data)); @@ -191,7 +191,7 @@ TEST_F(Getxattr, size_only) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_getxattr(ino, "user.foo", ReturnImmediate([](auto in __unused, auto out) { SET_OUT_HEADER_LEN(out, getxattr); @@ -215,7 +215,7 @@ TEST_F(Getxattr, system) int ns = EXTATTR_NAMESPACE_SYSTEM; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_getxattr(ino, "system.foo", ReturnImmediate([&](auto in __unused, auto out) { memcpy((void*)out->body.bytes, value, value_len); @@ -240,7 +240,7 @@ TEST_F(Getxattr, user) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_getxattr(ino, "user.foo", ReturnImmediate([&](auto in __unused, auto out) { memcpy((void*)out->body.bytes, value, value_len); @@ -264,7 +264,7 @@ TEST_F(Listxattr, DISABLED_enosys) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnErrno(ENOSYS)); ASSERT_EQ(-1, extattr_list_file(FULLPATH, ns, NULL, 0)); @@ -284,7 +284,7 @@ TEST_F(Listxattr, enotsup) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnErrno(ENOTSUP)); ASSERT_EQ(-1, extattr_list_file(FULLPATH, ns, NULL, 0)); @@ -308,7 +308,7 @@ TEST_F(Listxattr, erange) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnErrno(ERANGE)); ASSERT_EQ(-1, extattr_list_file(FULLPATH, ns, NULL, 0)); @@ -323,7 +323,7 @@ TEST_F(Listxattr, size_only_empty) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnImmediate([](auto i __unused, auto out) { out->body.listxattr.size = 0; SET_OUT_HEADER_LEN(out, listxattr); @@ -344,7 +344,7 @@ TEST_F(Listxattr, size_only_nonempty) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnImmediate([](auto i __unused, auto out) { out->body.listxattr.size = 45; SET_OUT_HEADER_LEN(out, listxattr); @@ -370,7 +370,7 @@ TEST_F(Listxattr, size_only_really_big) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnImmediate([](auto i __unused, auto out) { out->body.listxattr.size = 16000; SET_OUT_HEADER_LEN(out, listxattr); @@ -404,7 +404,7 @@ TEST_F(Listxattr, user) char expected[9] = {3, 'f', 'o', 'o', 4, 'b', 'a', 'n', 'g'}; char attrs[28] = "user.foo\0system.x\0user.bang"; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnImmediate([&](auto in __unused, auto out) { out->body.listxattr.size = sizeof(attrs); @@ -438,7 +438,7 @@ TEST_F(Listxattr, system) char expected[2] = {1, 'x'}; char attrs[28] = "user.foo\0system.x\0user.bang"; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_listxattr(ino, 0, ReturnImmediate([&](auto in __unused, auto out) { out->body.listxattr.size = sizeof(attrs); @@ -466,7 +466,7 @@ TEST_F(Removexattr, enoattr) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_removexattr(ino, "user.foo", ENOATTR); ASSERT_EQ(-1, extattr_delete_file(FULLPATH, ns, "foo")); @@ -484,7 +484,7 @@ TEST_F(Removexattr, DISABLED_enosys) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_removexattr(ino, "user.foo", ENOSYS); ASSERT_EQ(-1, extattr_delete_file(FULLPATH, ns, "foo")); @@ -501,7 +501,7 @@ TEST_F(Removexattr, user) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_removexattr(ino, "user.foo", 0); ASSERT_EQ(0, extattr_delete_file(FULLPATH, ns, "foo")) @@ -514,7 +514,7 @@ TEST_F(Removexattr, system) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_SYSTEM; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_removexattr(ino, "system.foo", 0); ASSERT_EQ(0, extattr_delete_file(FULLPATH, ns, "foo")) @@ -535,7 +535,7 @@ TEST_F(Setxattr, DISABLED_enosys) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_setxattr(ino, "user.foo", value, ReturnErrno(ENOSYS)); r = extattr_set_file(FULLPATH, ns, "foo", (void*)value, value_len); @@ -560,7 +560,7 @@ TEST_F(Setxattr, enotsup) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_setxattr(ino, "user.foo", value, ReturnErrno(ENOTSUP)); r = extattr_set_file(FULLPATH, ns, "foo", (void*)value, value_len); @@ -579,7 +579,7 @@ TEST_F(Setxattr, user) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_setxattr(ino, "user.foo", value, ReturnErrno(0)); r = extattr_set_file(FULLPATH, ns, "foo", (void*)value, value_len); @@ -597,7 +597,7 @@ TEST_F(Setxattr, system) int ns = EXTATTR_NAMESPACE_SYSTEM; ssize_t r; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_setxattr(ino, "system.foo", value, ReturnErrno(0)); r = extattr_set_file(FULLPATH, ns, "foo", (void*)value, value_len);