fusefs: set FUSE_WRITE_CACHE when writing from cache
This bit tells the server that we're not sure which uid, gid, and/or pid originated the write. I don't know of a single file system that cares, but it's part of the protocol. Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
7637cc62ab
commit
bda39894c5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=348313
@ -119,7 +119,7 @@ fuse_read_biobackend(struct vnode *vp, struct uio *uio, int ioflag,
|
||||
static int
|
||||
fuse_write_directbackend(struct vnode *vp, struct uio *uio,
|
||||
struct ucred *cred, struct fuse_filehandle *fufh, off_t filesize,
|
||||
int ioflag);
|
||||
int ioflag, bool pages);
|
||||
static int
|
||||
fuse_write_biobackend(struct vnode *vp, struct uio *uio,
|
||||
struct ucred *cred, struct fuse_filehandle *fufh, int ioflag, pid_t pid);
|
||||
@ -245,7 +245,7 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag, bool pages,
|
||||
if (!pages )
|
||||
v_inval_buf_range(vp, start, end, iosize);
|
||||
err = fuse_write_directbackend(vp, uio, cred, fufh,
|
||||
filesize, ioflag);
|
||||
filesize, ioflag, pages);
|
||||
} else {
|
||||
SDT_PROBE2(fusefs, , io, trace, 1,
|
||||
"buffered write of vnode");
|
||||
@ -405,7 +405,7 @@ fuse_read_directbackend(struct vnode *vp, struct uio *uio,
|
||||
static int
|
||||
fuse_write_directbackend(struct vnode *vp, struct uio *uio,
|
||||
struct ucred *cred, struct fuse_filehandle *fufh, off_t filesize,
|
||||
int ioflag)
|
||||
int ioflag, bool pages)
|
||||
{
|
||||
struct fuse_vnode_data *fvdat = VTOFUD(vp);
|
||||
struct fuse_data *data;
|
||||
@ -418,9 +418,29 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio,
|
||||
int diff;
|
||||
int err = 0;
|
||||
bool direct_io = fufh->fuse_open_flags & FOPEN_DIRECT_IO;
|
||||
uint32_t write_flags;
|
||||
|
||||
data = fuse_get_mpdata(vp->v_mount);
|
||||
|
||||
/*
|
||||
* Don't set FUSE_WRITE_LOCKOWNER in write_flags. It can't be set
|
||||
* accurately when using POSIX AIO, libfuse doesn't use it, and I'm not
|
||||
* aware of any file systems that do. It was an attempt to add
|
||||
* Linux-style mandatory locking to the FUSE protocol, but mandatory
|
||||
* locking is deprecated even on Linux. See Linux commit
|
||||
* f33321141b273d60cbb3a8f56a5489baad82ba5e .
|
||||
*/
|
||||
/*
|
||||
* Set FUSE_WRITE_CACHE whenever we don't know the uid, gid, and/or pid
|
||||
* that originated a write. For example when writing from the
|
||||
* writeback cache. I don't know of a single file system that cares,
|
||||
* but the protocol says we're supposed to do this.
|
||||
*/
|
||||
write_flags = !pages && (
|
||||
(ioflag & IO_DIRECT) ||
|
||||
!fsess_opt_datacache(vnode_mount(vp)) ||
|
||||
fuse_data_cache_mode != FUSE_CACHE_WB) ? 0 : FUSE_WRITE_CACHE;
|
||||
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
|
||||
@ -439,17 +459,8 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio,
|
||||
fwi->fh = fufh->fh_id;
|
||||
fwi->offset = uio->uio_offset;
|
||||
fwi->size = chunksize;
|
||||
fwi->write_flags = write_flags;
|
||||
if (fuse_libabi_geq(data, 7, 9)) {
|
||||
/*
|
||||
* Don't set FUSE_WRITE_LOCKOWNER. It can't be set
|
||||
* accurately when using POSIX AIO, libfuse doesn't use
|
||||
* it, and I'm not aware of any file systems that do.
|
||||
* It was an attempt to add Linux-style mandatory
|
||||
* locking to the FUSE protocol, but mandatory locking
|
||||
* is deprecated even on Linux. See Linux commit
|
||||
* f33321141b273d60cbb3a8f56a5489baad82ba5e .
|
||||
*/
|
||||
fwi->write_flags = 0;
|
||||
fwi->flags = 0; /* TODO */
|
||||
fwi_data = (char *)fdi.indata + sizeof(*fwi);
|
||||
} else {
|
||||
@ -525,6 +536,7 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio,
|
||||
fwi->fh = fufh->fh_id;
|
||||
fwi->offset = as_written_offset;
|
||||
fwi->size = diff;
|
||||
fwi->write_flags = write_flags;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
@ -884,7 +896,7 @@ fuse_io_strategy(struct vnode *vp, struct buf *bp)
|
||||
uiop->uio_rw = UIO_WRITE;
|
||||
|
||||
error = fuse_write_directbackend(vp, uiop, cred, fufh,
|
||||
filesize, 0);
|
||||
filesize, 0, false);
|
||||
|
||||
if (error == EINTR || error == ETIMEDOUT
|
||||
|| (!error && (bp->b_flags & B_NEEDCOMMIT))) {
|
||||
|
@ -1229,7 +1229,7 @@ TEST_F(Write, clear_suid)
|
||||
expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1);
|
||||
expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, wbuf);
|
||||
expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf);
|
||||
expect_chmod(ino, newmode, sizeof(wbuf));
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
@ -1255,7 +1255,7 @@ TEST_F(Write, clear_sgid)
|
||||
expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1);
|
||||
expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, wbuf);
|
||||
expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf);
|
||||
expect_chmod(ino, newmode, sizeof(wbuf));
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
@ -1285,7 +1285,7 @@ TEST_F(Write, recursion_panic_while_clearing_suid)
|
||||
expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1);
|
||||
expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, wbuf);
|
||||
expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf);
|
||||
/* XXX Return a smaller file size than what we just wrote! */
|
||||
expect_chmod(ino, newmode, 0);
|
||||
|
||||
|
@ -75,7 +75,7 @@ void expect_lookup(const char *relpath, uint64_t ino)
|
||||
|
||||
void expect_write(uint64_t ino, uint64_t size, const void *contents)
|
||||
{
|
||||
FuseTest::expect_write(ino, 0, size, size, 0, contents);
|
||||
FuseTest::expect_write(ino, 0, size, size, 0, 0, contents);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -377,15 +377,17 @@ void FuseTest::expect_unlink(uint64_t parent, const char *path, int error)
|
||||
}
|
||||
|
||||
void FuseTest::expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, uint32_t flags, const void *contents)
|
||||
uint64_t osize, uint32_t flags_set, uint32_t flags_unset,
|
||||
const void *contents)
|
||||
{
|
||||
EXPECT_CALL(*m_mock, process(
|
||||
ResultOf([=](auto in) {
|
||||
const char *buf = (const char*)in.body.bytes +
|
||||
sizeof(struct fuse_write_in);
|
||||
bool pid_ok;
|
||||
uint32_t wf = in.body.write.write_flags;
|
||||
|
||||
if (in.body.write.write_flags & FUSE_WRITE_CACHE)
|
||||
if (wf & FUSE_WRITE_CACHE)
|
||||
pid_ok = true;
|
||||
else
|
||||
pid_ok = (pid_t)in.header.pid == getpid();
|
||||
@ -396,7 +398,8 @@ void FuseTest::expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
in.body.write.offset == offset &&
|
||||
in.body.write.size == isize &&
|
||||
pid_ok &&
|
||||
in.body.write.write_flags == flags &&
|
||||
(wf & flags_set) == flags_set &&
|
||||
(wf & flags_unset) == 0 &&
|
||||
0 == bcmp(buf, contents, isize));
|
||||
}, Eq(true)),
|
||||
_)
|
||||
@ -407,7 +410,7 @@ void FuseTest::expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
}
|
||||
|
||||
void FuseTest::expect_write_7_8(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, uint32_t flags, const void *contents)
|
||||
uint64_t osize, const void *contents)
|
||||
{
|
||||
EXPECT_CALL(*m_mock, process(
|
||||
ResultOf([=](auto in) {
|
||||
@ -420,7 +423,6 @@ void FuseTest::expect_write_7_8(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
in.body.write.offset == offset &&
|
||||
in.body.write.size == isize &&
|
||||
pid_ok &&
|
||||
in.body.write.write_flags == flags &&
|
||||
0 == bcmp(buf, contents, isize));
|
||||
}, Eq(true)),
|
||||
_)
|
||||
|
@ -169,15 +169,18 @@ class FuseTest : public ::testing::Test {
|
||||
|
||||
/*
|
||||
* Create an expectation that FUSE_WRITE will be called exactly once
|
||||
* for the given inode, at offset offset, with write_flags flags,
|
||||
* size isize and buffer contents. It will return osize
|
||||
* for the given inode, at offset offset, with size isize and buffer
|
||||
* contents. Any flags present in flags_set must be set, and any
|
||||
* present in flags_unset must not be set. Other flags are don't care.
|
||||
* It will return osize.
|
||||
*/
|
||||
void expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, uint32_t flags, const void *contents);
|
||||
uint64_t osize, uint32_t flags_set, uint32_t flags_unset,
|
||||
const void *contents);
|
||||
|
||||
/* Protocol 7.8 version of expect_write */
|
||||
void expect_write_7_8(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, uint32_t flags, const void *contents);
|
||||
uint64_t osize, const void *contents);
|
||||
|
||||
/*
|
||||
* Helper that runs code in a child process.
|
||||
|
@ -65,6 +65,12 @@ void expect_release(uint64_t ino, ProcessMockerT r)
|
||||
).WillRepeatedly(Invoke(r));
|
||||
}
|
||||
|
||||
void expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, const void *contents)
|
||||
{
|
||||
FuseTest::expect_write(ino, offset, isize, osize, 0, 0, contents);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Write_7_8: public FuseTest {
|
||||
@ -100,7 +106,7 @@ virtual void SetUp() {
|
||||
|
||||
/* Tests for the write-through cache mode */
|
||||
class WriteThrough: public Write {
|
||||
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
const char *cache_mode_node = "vfs.fusefs.data_cache_mode";
|
||||
int val = 0;
|
||||
@ -117,11 +123,17 @@ virtual void SetUp() {
|
||||
"(writethrough) for this test";
|
||||
}
|
||||
|
||||
void expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, const void *contents)
|
||||
{
|
||||
FuseTest::expect_write(ino, offset, isize, osize, 0, FUSE_WRITE_CACHE,
|
||||
contents);
|
||||
}
|
||||
};
|
||||
|
||||
/* Tests for the writeback cache mode */
|
||||
class WriteBack: public Write {
|
||||
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
const char *node = "vfs.fusefs.data_cache_mode";
|
||||
int val = 0;
|
||||
@ -138,6 +150,12 @@ virtual void SetUp() {
|
||||
"(writeback) for this test";
|
||||
}
|
||||
|
||||
void expect_write(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
uint64_t osize, const void *contents)
|
||||
{
|
||||
FuseTest::expect_write(ino, offset, isize, osize, FUSE_WRITE_CACHE, 0,
|
||||
contents);
|
||||
}
|
||||
};
|
||||
|
||||
/* AIO writes need to set the header's pid field correctly */
|
||||
@ -155,7 +173,7 @@ TEST_F(AioWrite, DISABLED_aio_write)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, offset, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -196,7 +214,7 @@ TEST_F(Write, append)
|
||||
|
||||
expect_lookup(RELPATH, ino, initial_offset);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS);
|
||||
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, CONTENTS);
|
||||
|
||||
/* Must open O_RDWR or fuse(4) implicitly sets direct_io */
|
||||
fd = open(FULLPATH, O_RDWR | O_APPEND);
|
||||
@ -218,7 +236,7 @@ TEST_F(Write, append_direct_io)
|
||||
|
||||
expect_lookup(RELPATH, ino, initial_offset);
|
||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS);
|
||||
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY | O_APPEND);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -242,7 +260,7 @@ TEST_F(Write, direct_io_evicts_cache)
|
||||
expect_lookup(RELPATH, ino, bufsize);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS0);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS1);
|
||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS1);
|
||||
|
||||
fd = open(FULLPATH, O_RDWR);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -285,9 +303,8 @@ TEST_F(Write, indirect_io_short_write)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize0, 0, CONTENTS);
|
||||
expect_write(ino, bufsize0, bufsize1, bufsize1, 0,
|
||||
contents1);
|
||||
expect_write(ino, 0, bufsize, bufsize0, CONTENTS);
|
||||
expect_write(ino, bufsize0, bufsize1, bufsize1, contents1);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -312,7 +329,7 @@ TEST_F(Write, direct_io_short_write)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||
expect_write(ino, 0, bufsize, halfbufsize, 0, CONTENTS);
|
||||
expect_write(ino, 0, bufsize, halfbufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -342,7 +359,7 @@ TEST_F(Write, direct_io_short_write_iov)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||
expect_write(ino, 0, totalsize, size0, 0, EXPECTED0);
|
||||
expect_write(ino, 0, totalsize, size0, EXPECTED0);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -388,9 +405,8 @@ TEST_F(Write, mmap)
|
||||
/*
|
||||
* Writes from the pager may or may not be associated with the correct
|
||||
* pid, so they must set FUSE_WRITE_CACHE.
|
||||
* TODO: expect FUSE_WRITE_CACHE after upgrading to protocol 7.9
|
||||
*/
|
||||
expect_write(ino, 0, len, len, 0, expected);
|
||||
FuseTest::expect_write(ino, 0, len, len, FUSE_WRITE_CACHE, 0, expected);
|
||||
expect_flush(ino, 1, ReturnErrno(0));
|
||||
expect_release(ino, ReturnErrno(0));
|
||||
|
||||
@ -435,7 +451,7 @@ TEST_F(WriteThrough, evicts_read_cache)
|
||||
expect_lookup(RELPATH, ino, bufsize);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_read(ino, 0, bufsize, bufsize, contents0);
|
||||
expect_write(ino, 0, wrsize, wrsize, 0, contents1);
|
||||
expect_write(ino, 0, wrsize, wrsize, contents1);
|
||||
|
||||
fd = open(FULLPATH, O_RDWR);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -468,7 +484,7 @@ TEST_F(WriteThrough, pwrite)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, offset, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -489,7 +505,7 @@ TEST_F(Write, write)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -518,8 +534,8 @@ TEST_F(Write, write_large)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, halfbufsize, halfbufsize, 0, contents);
|
||||
expect_write(ino, halfbufsize, halfbufsize, halfbufsize, 0,
|
||||
expect_write(ino, 0, halfbufsize, halfbufsize, contents);
|
||||
expect_write(ino, halfbufsize, halfbufsize, halfbufsize,
|
||||
&contents[halfbufsize / sizeof(int)]);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
@ -561,7 +577,7 @@ TEST_F(Write_7_8, write)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write_7_8(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write_7_8(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -582,7 +598,7 @@ TEST_F(WriteBack, close)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
EXPECT_CALL(*m_mock, process(
|
||||
ResultOf([=](auto in) {
|
||||
return (in.header.opcode == FUSE_SETATTR);
|
||||
@ -621,7 +637,7 @@ TEST_F(WriteBack, rmw)
|
||||
FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, fsize, 1);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_read(ino, 0, fsize, fsize, INITIAL);
|
||||
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, offset, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_WRONLY);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -646,7 +662,7 @@ TEST_F(WriteBack, writeback)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_RDWR);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -678,7 +694,8 @@ TEST_F(WriteBack, o_direct)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
FuseTest::expect_write(ino, 0, bufsize, bufsize, 0, FUSE_WRITE_CACHE,
|
||||
CONTENTS);
|
||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_RDWR | O_DIRECT);
|
||||
@ -711,7 +728,7 @@ TEST_F(WriteThrough, DISABLED_writethrough)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_RDWR);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
@ -738,7 +755,7 @@ TEST_F(WriteThrough, update_file_size)
|
||||
|
||||
expect_lookup(RELPATH, ino, 0);
|
||||
expect_open(ino, 0, 1);
|
||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS);
|
||||
|
||||
fd = open(FULLPATH, O_RDWR);
|
||||
EXPECT_LE(0, fd) << strerror(errno);
|
||||
|
Loading…
Reference in New Issue
Block a user