diff options
Diffstat (limited to 'tests/sys/fs/fusefs/bmap.cc')
| -rw-r--r-- | tests/sys/fs/fusefs/bmap.cc | 87 | 
1 files changed, 87 insertions, 0 deletions
| diff --git a/tests/sys/fs/fusefs/bmap.cc b/tests/sys/fs/fusefs/bmap.cc index 30612079657d..e61dadb6d79e 100644 --- a/tests/sys/fs/fusefs/bmap.cc +++ b/tests/sys/fs/fusefs/bmap.cc @@ -178,6 +178,93 @@ TEST_F(Bmap, default_)  }  /* + * The server returns an error for some reason for FUSE_BMAP.  fusefs should + * faithfully report that error up to the caller. + */ +TEST_F(Bmap, einval) +{ +	struct fiobmap2_arg arg; +	const off_t filesize = 1 << 30; +	int64_t lbn = 100; +	const ino_t ino = 42; +	int fd; + +	expect_lookup(RELPATH, 42, filesize); +	expect_open(ino, 0, 1); +	EXPECT_CALL(*m_mock, process( +		ResultOf([=](auto in) { +			return (in.header.opcode == FUSE_BMAP && +				in.header.nodeid == ino); +		}, Eq(true)), +		_) +	).WillOnce(Invoke(ReturnErrno(EINVAL))); + +	fd = open(FULLPATH, O_RDWR); +	ASSERT_LE(0, fd) << strerror(errno); + +	arg.bn = lbn; +	arg.runp = -1; +	arg.runb = -1; +	ASSERT_EQ(-1, ioctl(fd, FIOBMAP2, &arg)); +	EXPECT_EQ(EINVAL, errno); + +	leak(fd); +} + +/* + * Even if the server returns EINVAL during VOP_BMAP, we should still be able + * to successfully read a block.  This is a regression test for + * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=264196 .  The bug did not + * lie in fusefs, but this is a convenient place for a regression test. + */ +TEST_F(Bmap, spurious_einval) +{ +	const off_t filesize = 4ull << 30; +	const ino_t ino = 42; +	int fd, r; +	char buf[1]; + +	expect_lookup(RELPATH, 42, filesize); +	expect_open(ino, 0, 1); +	EXPECT_CALL(*m_mock, process( +		ResultOf([=](auto in) { +			return (in.header.opcode == FUSE_BMAP && +				in.header.nodeid == ino); +		}, Eq(true)), +		_) +	).WillRepeatedly(Invoke(ReturnErrno(EINVAL))); +	EXPECT_CALL(*m_mock, process( +	ResultOf([=](auto in) { +		return (in.header.opcode == FUSE_READ && +			in.header.nodeid == ino && +			in.body.read.offset == 0 && +			in.body.read.size == (uint64_t)m_maxbcachebuf); +		}, Eq(true)), +		_) +	).WillOnce(Invoke(ReturnImmediate([=](auto in, auto& out) { +		size_t osize = in.body.read.size; + +		assert(osize < sizeof(out.body.bytes)); +		out.header.len = sizeof(struct fuse_out_header) + osize; +		bzero(out.body.bytes, osize); +	}))); + +	fd = open(FULLPATH, O_RDWR); +	ASSERT_LE(0, fd) << strerror(errno); + +	/* +	 * Read the same block multiple times.  On a system affected by PR +	 * 264196 , the second read will fail. +	 */ +	r = read(fd, buf, sizeof(buf)); +	EXPECT_EQ(r, 1) << strerror(errno); +	r = read(fd, buf, sizeof(buf)); +	EXPECT_EQ(r, 1) << strerror(errno); +	r = read(fd, buf, sizeof(buf)); +	EXPECT_EQ(r, 1) << strerror(errno); +} + +/*   * VOP_BMAP should not query the server for the file's size, even if its cached   * attributes have expired.   * Regression test for https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=256937 | 
