diff options
| author | Alan Somers <asomers@FreeBSD.org> | 2025-01-10 21:36:02 +0000 |
|---|---|---|
| committer | Alan Somers <asomers@FreeBSD.org> | 2025-04-17 20:14:58 +0000 |
| commit | 1c316af141497cedb82971abddbbc53ea5264cef (patch) | |
| tree | 9629d39456c0e0a0745bea70dc111df8957eaba7 /tests | |
| parent | d03aa29b82b803b440886a2f864dcdafa184c4fb (diff) | |
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/sys/fs/fusefs/mockfs.cc | 10 | ||||
| -rw-r--r-- | tests/sys/fs/fusefs/mockfs.hh | 8 | ||||
| -rw-r--r-- | tests/sys/fs/fusefs/read.cc | 53 | ||||
| -rw-r--r-- | tests/sys/fs/fusefs/utils.cc | 2 | ||||
| -rw-r--r-- | tests/sys/fs/fusefs/utils.hh | 2 |
5 files changed, 72 insertions, 3 deletions
diff --git a/tests/sys/fs/fusefs/mockfs.cc b/tests/sys/fs/fusefs/mockfs.cc index 502f22a1e980..1fd2d5e358b1 100644 --- a/tests/sys/fs/fusefs/mockfs.cc +++ b/tests/sys/fs/fusefs/mockfs.cc @@ -416,7 +416,8 @@ void MockFS::debug_response(const mockfs_buf_out &out) { } } -MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions, +MockFS::MockFS(int max_read, int max_readahead, bool allow_other, + bool default_permissions, bool push_symlinks_in, bool ro, enum poll_method pm, uint32_t flags, uint32_t kernel_minor_version, uint32_t max_write, bool async, bool noclusterr, unsigned time_gran, bool nointr, bool noatime, @@ -424,6 +425,7 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions, : m_daemon_id(NULL), m_kernel_minor_version(kernel_minor_version), m_kq(pm == KQ ? kqueue() : -1), + m_maxread(max_read), m_maxreadahead(max_readahead), m_pid(getpid()), m_uniques(new std::unordered_set<uint64_t>), @@ -470,6 +472,12 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions, build_iovec(&iov, &iovlen, "from", __DECONST(void *, "/dev/fuse"), -1); sprintf(fdstr, "%d", m_fuse_fd); build_iovec(&iov, &iovlen, "fd", fdstr, -1); + if (m_maxread > 0) { + char val[10]; + + snprintf(val, sizeof(val), "%d", m_maxread); + build_iovec(&iov, &iovlen, "max_read=", &val, -1); + } if (allow_other) { build_iovec(&iov, &iovlen, "allow_other", __DECONST(void*, &trueval), sizeof(bool)); diff --git a/tests/sys/fs/fusefs/mockfs.hh b/tests/sys/fs/fusefs/mockfs.hh index 38efcd049a61..1de77767d0c9 100644 --- a/tests/sys/fs/fusefs/mockfs.hh +++ b/tests/sys/fs/fusefs/mockfs.hh @@ -294,6 +294,12 @@ class MockFS { int m_kq; + /* + * If nonzero, the maximum size in bytes of a read that the kernel will + * send to the server. + */ + int m_maxread; + /* The max_readahead file system option */ uint32_t m_maxreadahead; @@ -355,7 +361,7 @@ class MockFS { bool m_quit; /* Create a new mockfs and mount it to a tempdir */ - MockFS(int max_readahead, bool allow_other, + MockFS(int max_read, int max_readahead, bool allow_other, bool default_permissions, bool push_symlinks_in, bool ro, enum poll_method pm, uint32_t flags, uint32_t kernel_minor_version, uint32_t max_write, bool async, diff --git a/tests/sys/fs/fusefs/read.cc b/tests/sys/fs/fusefs/read.cc index 9693428914e6..e9c79ba2ffda 100644 --- a/tests/sys/fs/fusefs/read.cc +++ b/tests/sys/fs/fusefs/read.cc @@ -111,6 +111,13 @@ class ReadAhead: public Read, } }; +class ReadMaxRead: public Read { + virtual void SetUp() { + m_maxread = 16384; + Read::SetUp(); + } +}; + class ReadNoatime: public Read { virtual void SetUp() { m_noatime = true; @@ -840,6 +847,52 @@ TEST_F(Read, mmap) leak(fd); } + +/* When max_read is set, large reads will be split up as necessary */ +TEST_F(ReadMaxRead, split) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int fd; + ssize_t bufsize = 65536; + ssize_t fragsize = bufsize / 4; + char *rbuf, *frag0, *frag1, *frag2, *frag3; + + rbuf = new char[bufsize](); + frag0 = new char[fragsize](); + frag1 = new char[fragsize](); + frag2 = new char[fragsize](); + frag3 = new char[fragsize](); + memset(frag0, '0', fragsize); + memset(frag1, '1', fragsize); + memset(frag2, '2', fragsize); + memset(frag3, '3', fragsize); + + expect_lookup(RELPATH, ino, bufsize); + expect_open(ino, 0, 1); + expect_read(ino, 0, fragsize, fragsize, frag0); + expect_read(ino, fragsize, fragsize, fragsize, frag1); + expect_read(ino, 2 * fragsize, fragsize, fragsize, frag2); + expect_read(ino, 3 * fragsize, fragsize, fragsize, frag3); + + fd = open(FULLPATH, O_RDONLY); + ASSERT_LE(0, fd) << strerror(errno); + + ASSERT_EQ(bufsize, read(fd, rbuf, bufsize)) << strerror(errno); + ASSERT_EQ(0, memcmp(rbuf, frag0, fragsize)); + ASSERT_EQ(0, memcmp(rbuf + fragsize, frag1, fragsize)); + ASSERT_EQ(0, memcmp(rbuf + 2 * fragsize, frag2, fragsize)); + ASSERT_EQ(0, memcmp(rbuf + 3 * fragsize, frag3, fragsize)); + + delete[] frag3; + delete[] frag2; + delete[] frag1; + delete[] frag0; + delete[] rbuf; + leak(fd); +} + /* * The kernel should not update the cached atime attribute during a read, if * MNT_NOATIME is used. diff --git a/tests/sys/fs/fusefs/utils.cc b/tests/sys/fs/fusefs/utils.cc index 831ded0c0815..d059221b2e55 100644 --- a/tests/sys/fs/fusefs/utils.cc +++ b/tests/sys/fs/fusefs/utils.cc @@ -154,7 +154,7 @@ void FuseTest::SetUp() { m_maxwrite = MIN(libfuse_max_write, (uint32_t)m_maxphys / 2); try { - m_mock = new MockFS(m_maxreadahead, m_allow_other, + m_mock = new MockFS(m_maxread, m_maxreadahead, m_allow_other, m_default_permissions, m_push_symlinks_in, m_ro, m_pm, m_init_flags, m_kernel_minor_version, m_maxwrite, m_async, m_noclusterr, m_time_gran, diff --git a/tests/sys/fs/fusefs/utils.hh b/tests/sys/fs/fusefs/utils.hh index 506e8a985212..9dd8dad6b5cc 100644 --- a/tests/sys/fs/fusefs/utils.hh +++ b/tests/sys/fs/fusefs/utils.hh @@ -55,6 +55,7 @@ bool is_unsafe_aio_enabled(void); extern const uint32_t libfuse_max_write; class FuseTest : public ::testing::Test { protected: + uint32_t m_maxread; uint32_t m_maxreadahead; uint32_t m_maxwrite; uint32_t m_init_flags; @@ -80,6 +81,7 @@ class FuseTest : public ::testing::Test { unsigned long m_maxphys; FuseTest(): + m_maxread(0), m_maxreadahead(0), m_maxwrite(0), m_init_flags(0), |
