diff options
Diffstat (limited to 'tests/sys/fs/fusefs/write.cc')
| -rw-r--r-- | tests/sys/fs/fusefs/write.cc | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/tests/sys/fs/fusefs/write.cc b/tests/sys/fs/fusefs/write.cc index 31b7f90a58565..407effab7db8f 100644 --- a/tests/sys/fs/fusefs/write.cc +++ b/tests/sys/fs/fusefs/write.cc @@ -29,7 +29,7 @@ */ extern "C" { -#include <sys/types.h> +#include <sys/param.h> #include <sys/mman.h> #include <sys/resource.h> #include <sys/stat.h> @@ -179,6 +179,19 @@ void expect_write(uint64_t ino, uint64_t offset, uint64_t isize, } }; +/* Tests for clustered writes with WriteBack cacheing */ +class WriteCluster: public WriteBack { +public: +virtual void SetUp() { + if (MAXPHYS < 2 * DFLTPHYS) + GTEST_SKIP() << "MAXPHYS must be at least twice DFLTPHYS" + << "for this test"; + m_async = true; + m_maxwrite = MAXPHYS; + WriteBack::SetUp(); +} +}; + void sigxfsz_handler(int __unused sig) { Write::s_sigxfsz = 1; } @@ -617,7 +630,7 @@ TEST_F(Write, write_large) int fd; ssize_t halfbufsize, bufsize; - halfbufsize = m_mock->m_max_write; + halfbufsize = m_mock->m_maxwrite; bufsize = halfbufsize * 2; contents = (int*)malloc(bufsize); ASSERT_NE(NULL, contents); @@ -711,6 +724,89 @@ TEST_F(WriteBack, close) close(fd); } +/* In writeback mode, adjacent writes will be clustered together */ +TEST_F(WriteCluster, clustering) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int i, fd; + void *wbuf, *wbuf2x; + ssize_t bufsize = 65536; + off_t filesize = 327680; + + wbuf = malloc(bufsize); + ASSERT_NE(NULL, wbuf) << strerror(errno); + memset(wbuf, 'X', bufsize); + wbuf2x = malloc(2 * bufsize); + ASSERT_NE(NULL, wbuf2x) << strerror(errno); + memset(wbuf2x, 'X', 2 * bufsize); + + expect_lookup(RELPATH, ino, filesize); + expect_open(ino, 0, 1); + /* + * Writes of bufsize-bytes each should be clustered into greater sizes. + * The amount of clustering is adaptive, so the first write actually + * issued will be 2x bufsize and subsequent writes may be larger + */ + expect_write(ino, 0, 2 * bufsize, 2 * bufsize, wbuf2x); + expect_write(ino, 2 * bufsize, 2 * bufsize, 2 * bufsize, wbuf2x); + expect_flush(ino, 1, ReturnErrno(0)); + expect_release(ino, ReturnErrno(0)); + + fd = open(FULLPATH, O_RDWR); + ASSERT_LE(0, fd) << strerror(errno); + + for (i = 0; i < 4; i++) { + ASSERT_EQ(bufsize, write(fd, wbuf, bufsize)) + << strerror(errno); + } + close(fd); +} + +/* + * When clustering writes, an I/O error to any of the cluster's children should + * not panic the system on unmount + */ +/* + * Disabled because it panics. + * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238565 + */ +TEST_F(WriteCluster, DISABLED_cluster_write_err) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int i, fd; + void *wbuf; + ssize_t bufsize = 65536; + off_t filesize = 262144; + + wbuf = malloc(bufsize); + ASSERT_NE(NULL, wbuf) << strerror(errno); + memset(wbuf, 'X', bufsize); + + expect_lookup(RELPATH, ino, filesize); + expect_open(ino, 0, 1); + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_WRITE); + }, Eq(true)), + _) + ).WillRepeatedly(Invoke(ReturnErrno(EIO))); + expect_flush(ino, 1, ReturnErrno(0)); + expect_release(ino, ReturnErrno(0)); + + fd = open(FULLPATH, O_RDWR); + ASSERT_LE(0, fd) << strerror(errno); + + for (i = 0; i < 3; i++) { + ASSERT_EQ(bufsize, write(fd, wbuf, bufsize)) + << strerror(errno); + } + close(fd); +} + /* * In writeback mode, writes to an O_WRONLY file could trigger reads from the * server. The FUSE protocol explicitly allows that. |
