--- b/tests/sys/fs/fusefs/io.cc +++ b/tests/sys/fs/fusefs/io.cc @@ -194,6 +194,26 @@ void SetUp() }, Eq(true)), _) ).WillRepeatedly(Invoke(ReturnErrno(0))); + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_FALLOCATE && + in.header.nodeid == ino && + in.body.fallocate.mode == + (FUSE_FALLOC_FL_KEEP_SIZE | + FUSE_FALLOC_FL_PUNCH_HOLE)); + + }, Eq(true)), + _) + ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in, auto& out) { + spacectl_range rqsr = { + .r_offset = (off_t)in.body.fallocate.offset, + .r_len = (off_t)in.body.fallocate.length + }; + ASSERT_EQ(0, fspacectl(m_backing_fd, SPACECTL_DEALLOC, &rqsr, + 0, &rqsr)) + << strerror(errno); + out.header.len = sizeof(out.header); + }))); m_test_fd = open(FULLPATH, O_RDWR ); EXPECT_LE(0, m_test_fd) << strerror(errno); @@ -222,6 +242,24 @@ void do_closeopen() ASSERT_LE(0, m_control_fd) << strerror(errno); } +void do_fspacectl(ssize_t size, off_t offs) +{ + struct spacectl_range rqsr = { + .r_offset = offs, + .r_len = size, + }; + struct spacectl_range rmsr; + + ASSERT_EQ(0, fspacectl(m_test_fd, SPACECTL_DEALLOC, &rqsr, 0, &rmsr)) + << strerror(errno); + EXPECT_EQ(0, rmsr.r_len); + EXPECT_EQ(offs + size, rmsr.r_offset); + ASSERT_EQ(0, fspacectl(m_control_fd, SPACECTL_DEALLOC, &rqsr, 0, &rmsr)) + << strerror(errno); + EXPECT_EQ(0, rmsr.r_len); + EXPECT_EQ(offs + size, rmsr.r_offset); +} + void do_ftruncate(off_t offs) { ASSERT_EQ(0, ftruncate(m_test_fd, offs)) << strerror(errno); @@ -506,6 +544,27 @@ TEST_P(Io, resize_a_valid_buffer_while_extending) close(m_test_fd); } +/* Revealed with bfffs 4a0eef6c6011fa3c0ab898dbd647c1ea27986004 using fsx c3e726d6de39d4b2641cd8b49bbd19beef456604 + * + * fsx -f fsx.toml -N 1000 -P /tmp -S 2153242284826767701 /testpool/tmp/fsx.bin + * + * fsx.toml: + * nomsyncafterwrite = true + * [weights] + * close_open = 0.1 + * invalidate = 0.2 + * truncate = 1 + * fsync = 1 + * fdatasync = 1 + * punch_hole = 100 + */ +TEST_P(IoCacheable, fsx_bfffs_fspacectl) +{ + do_mapwrite(0x80f1, 0x1ffb4); + do_fspacectl(0x1f7, 0x27eae); + do_mapread(0xb982, 0x16252); +} + INSTANTIATE_TEST_CASE_P(Io, Io, Combine(Bool(), /* async read */ Values(0x1000, 0x10000, 0x20000), /* m_maxwrite */