Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/fs/fusefs/copy_file_range.cc
Show First 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | TEST_F(CopyFileRange, eio) | ||||
fd1 = open(FULLPATH1, O_RDONLY); | fd1 = open(FULLPATH1, O_RDONLY); | ||||
fd2 = open(FULLPATH2, O_WRONLY); | fd2 = open(FULLPATH2, O_WRONLY); | ||||
ASSERT_EQ(-1, copy_file_range(fd1, &start1, fd2, &start2, len, 0)); | ASSERT_EQ(-1, copy_file_range(fd1, &start1, fd2, &start2, len, 0)); | ||||
EXPECT_EQ(EIO, errno); | EXPECT_EQ(EIO, errno); | ||||
} | } | ||||
/* | /* | ||||
* copy_file_range should evict cached data for the modified region of the | |||||
* destination file. | |||||
*/ | |||||
TEST_F(CopyFileRange, evicts_cache) | |||||
{ | |||||
const char FULLPATH1[] = "mountpoint/src.txt"; | |||||
const char RELPATH1[] = "src.txt"; | |||||
const char FULLPATH2[] = "mountpoint/dst.txt"; | |||||
const char RELPATH2[] = "dst.txt"; | |||||
void *buf0, *buf1, *buf; | |||||
const uint64_t ino1 = 42; | |||||
const uint64_t ino2 = 43; | |||||
const uint64_t fh1 = 0xdeadbeef1a7ebabe; | |||||
const uint64_t fh2 = 0xdeadc0de88c0ffee; | |||||
off_t fsize1 = 1 << 20; /* 1 MiB */ | |||||
off_t fsize2 = 1 << 19; /* 512 KiB */ | |||||
off_t start1 = 1 << 18; | |||||
off_t start2 = 3 << 17; | |||||
ssize_t len = m_maxbcachebuf; | |||||
int fd1, fd2; | |||||
buf0 = malloc(m_maxbcachebuf); | |||||
memset(buf0, 42, m_maxbcachebuf); | |||||
expect_lookup(RELPATH1, ino1, S_IFREG | 0644, fsize1, 1); | |||||
expect_lookup(RELPATH2, ino2, S_IFREG | 0644, fsize2, 1); | |||||
expect_open(ino1, 0, 1, fh1); | |||||
expect_open(ino2, 0, 1, fh2); | |||||
expect_read(ino2, start2, m_maxbcachebuf, m_maxbcachebuf, buf0, -1, | |||||
fh2); | |||||
EXPECT_CALL(*m_mock, process( | |||||
ResultOf([=](auto in) { | |||||
return (in.header.opcode == FUSE_COPY_FILE_RANGE && | |||||
in.header.nodeid == ino1 && | |||||
in.body.copy_file_range.fh_in == fh1 && | |||||
(off_t)in.body.copy_file_range.off_in == start1 && | |||||
in.body.copy_file_range.nodeid_out == ino2 && | |||||
in.body.copy_file_range.fh_out == fh2 && | |||||
(off_t)in.body.copy_file_range.off_out == start2 && | |||||
in.body.copy_file_range.len == (size_t)len && | |||||
in.body.copy_file_range.flags == 0); | |||||
}, Eq(true)), | |||||
_) | |||||
).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { | |||||
SET_OUT_HEADER_LEN(out, write); | |||||
out.body.write.size = len; | |||||
}))); | |||||
fd1 = open(FULLPATH1, O_RDONLY); | |||||
fd2 = open(FULLPATH2, O_RDWR); | |||||
// Prime cache | |||||
buf = malloc(m_maxbcachebuf); | |||||
ASSERT_EQ(m_maxbcachebuf, pread(fd2, buf, m_maxbcachebuf, start2)) | |||||
<< strerror(errno); | |||||
EXPECT_EQ(0, memcmp(buf0, buf, m_maxbcachebuf)); | |||||
// Tell the FUSE server overwrite the region we just read | |||||
ASSERT_EQ(len, copy_file_range(fd1, &start1, fd2, &start2, len, 0)); | |||||
// Read again. This should bypass the cache and read direct from server | |||||
buf1 = malloc(m_maxbcachebuf); | |||||
memset(buf1, 69, m_maxbcachebuf); | |||||
start2 -= len; | |||||
expect_read(ino2, start2, m_maxbcachebuf, m_maxbcachebuf, buf1, -1, | |||||
fh2); | |||||
ASSERT_EQ(m_maxbcachebuf, pread(fd2, buf, m_maxbcachebuf, start2)) | |||||
<< strerror(errno); | |||||
EXPECT_EQ(0, memcmp(buf1, buf, m_maxbcachebuf)); | |||||
free(buf1); | |||||
free(buf0); | |||||
free(buf); | |||||
leak(fd1); | |||||
leak(fd2); | |||||
} | |||||
/* | |||||
* If the server doesn't support FUSE_COPY_FILE_RANGE, the kernel should | * If the server doesn't support FUSE_COPY_FILE_RANGE, the kernel should | ||||
* fallback to a read/write based implementation. | * fallback to a read/write based implementation. | ||||
*/ | */ | ||||
TEST_F(CopyFileRange, fallback) | TEST_F(CopyFileRange, fallback) | ||||
{ | { | ||||
const char FULLPATH1[] = "mountpoint/src.txt"; | const char FULLPATH1[] = "mountpoint/src.txt"; | ||||
const char RELPATH1[] = "src.txt"; | const char RELPATH1[] = "src.txt"; | ||||
const char FULLPATH2[] = "mountpoint/dst.txt"; | const char FULLPATH2[] = "mountpoint/dst.txt"; | ||||
▲ Show 20 Lines • Show All 266 Lines • Show Last 20 Lines |