From cad677915fbdaf6fe7774a1c19f74966d853978f Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Mon, 8 Apr 2019 18:45:41 +0000 Subject: [PATCH] fusefs: cache file attributes FUSE_LOOKUP, FUSE_GETATTR, FUSE_SETATTR, FUSE_MKDIR, FUSE_LINK, FUSE_SYMLINK, FUSE_MKNOD, and FUSE_CREATE all return file attributes with a cache validity period. fusefs will now cache the attributes, if the server returns a non-zero cache validity period. This change does _not_ implement finite attr cache timeouts. That will follow as part of PR 235773. PR: 235775 Reported by: cem Sponsored by: The FreeBSD Foundation --- sys/fs/fuse/fuse_internal.c | 62 +++++++++++++++++- sys/fs/fuse/fuse_internal.h | 4 ++ sys/fs/fuse/fuse_node.c | 3 + sys/fs/fuse/fuse_node.h | 2 +- sys/fs/fuse/fuse_vnops.c | 51 +++------------ tests/sys/fs/fusefs/allow_other.cc | 2 - tests/sys/fs/fusefs/create.cc | 68 +------------------- tests/sys/fs/fusefs/default_permissions.cc | 2 - tests/sys/fs/fusefs/flush.cc | 6 -- tests/sys/fs/fusefs/fsync.cc | 6 -- tests/sys/fs/fusefs/getattr.cc | 33 +++++++--- tests/sys/fs/fusefs/locks.cc | 9 --- tests/sys/fs/fusefs/lookup.cc | 5 +- tests/sys/fs/fusefs/open.cc | 4 -- tests/sys/fs/fusefs/read.cc | 17 ----- tests/sys/fs/fusefs/release.cc | 6 -- tests/sys/fs/fusefs/setattr.cc | 73 +--------------------- tests/sys/fs/fusefs/unlink.cc | 1 - tests/sys/fs/fusefs/utils.cc | 3 +- tests/sys/fs/fusefs/write.cc | 36 +---------- 20 files changed, 110 insertions(+), 283 deletions(-) diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c index ffe8c27bcd7c..bffe98b6097f 100644 --- a/sys/fs/fuse/fuse_internal.c +++ b/sys/fs/fuse/fuse_internal.c @@ -175,9 +175,9 @@ fuse_internal_access(struct vnode *vp, } /* - * Cache FUSE attributes from feo, in attr cache associated with vnode 'vp'. - * Optionally, if argument 'vap' is not NULL, store a copy of the converted - * attributes there as well. + * Cache FUSE attributes from attr, in attribute cache associated with vnode + * 'vp'. Optionally, if argument 'vap' is not NULL, store a copy of the + * converted attributes there as well. * * If the nominal attribute cache TTL is zero, do not cache on the 'vp' (but do * return the result to the caller). @@ -583,6 +583,62 @@ fuse_internal_forget_send(struct mount *mp, fdisp_destroy(&fdi); } +/* Read a vnode's attributes from cache or fetch them from the fuse daemon */ +int +fuse_internal_getattr(struct vnode *vp, struct vattr *vap, struct ucred *cred, + struct thread *td) +{ + struct fuse_dispatcher fdi; + struct fuse_vnode_data *fvdat = VTOFUD(vp); + struct vattr *attrs; + struct fuse_attr_out *fao; + int err = 0; + + if ((attrs = VTOVA(vp)) != NULL) { + /* struct copy */ + *vap = *attrs; + if ((fvdat->flag & FN_SIZECHANGE) != 0) + vap->va_size = fvdat->filesize; + return 0; + } + + fdisp_init(&fdi, 0); + if ((err = fdisp_simple_putget_vp(&fdi, FUSE_GETATTR, vp, td, cred))) { + if (err == ENOENT) { + fuse_internal_vnode_disappear(vp); + } + goto out; + } + + fao = (struct fuse_attr_out *)fdi.answ; + fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, + fao->attr_valid_nsec, vap); + if (vap->va_type != vnode_vtype(vp)) { + fuse_internal_vnode_disappear(vp); + err = ENOENT; + goto out; + } + if ((fvdat->flag & FN_SIZECHANGE) != 0) + vap->va_size = fvdat->filesize; + + if (vnode_isreg(vp) && (fvdat->flag & FN_SIZECHANGE) == 0) { + /* + * This is for those cases when the file size changed without us + * knowing, and we want to catch up. + */ + off_t new_filesize = fao->attr.size; + + if (fvdat->filesize != new_filesize) { + fuse_vnode_setsize(vp, cred, new_filesize); + fvdat->flag &= ~FN_SIZECHANGE; + } + } + +out: + fdisp_destroy(&fdi); + return err; +} + void fuse_internal_vnode_disappear(struct vnode *vp) { diff --git a/sys/fs/fuse/fuse_internal.h b/sys/fs/fuse/fuse_internal.h index 55c4b5da5696..49064994831b 100644 --- a/sys/fs/fuse/fuse_internal.h +++ b/sys/fs/fuse/fuse_internal.h @@ -199,6 +199,10 @@ int fuse_internal_fsync(struct vnode *vp, struct thread *td, int waitfor, bool datasync); int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio); +/* getattr */ +int fuse_internal_getattr(struct vnode *vp, struct vattr *vap, + struct ucred *cred, struct thread *td); + /* readdir */ struct pseudo_dirent { diff --git a/sys/fs/fuse/fuse_node.c b/sys/fs/fuse/fuse_node.c index 453645bc0e5b..66b6b1959b66 100644 --- a/sys/fs/fuse/fuse_node.c +++ b/sys/fs/fuse/fuse_node.c @@ -403,6 +403,7 @@ int fuse_vnode_setsize(struct vnode *vp, struct ucred *cred, off_t newsize) { struct fuse_vnode_data *fvdat = VTOFUD(vp); + struct vattr *attrs; off_t oldsize; size_t iosize; struct buf *bp = NULL; @@ -413,6 +414,8 @@ fuse_vnode_setsize(struct vnode *vp, struct ucred *cred, off_t newsize) iosize = fuse_iosize(vp); oldsize = fvdat->filesize; fvdat->filesize = newsize; + if ((attrs = VTOVA(vp)) != NULL) + attrs->va_size = newsize; fvdat->flag |= FN_SIZECHANGE; if (newsize < oldsize) { diff --git a/sys/fs/fuse/fuse_node.h b/sys/fs/fuse/fuse_node.h index f1d435218d47..fea87fcc9a4e 100644 --- a/sys/fs/fuse/fuse_node.h +++ b/sys/fs/fuse/fuse_node.h @@ -80,7 +80,7 @@ struct fuse_vnode_data { uint64_t parent_nid; /** I/O **/ - /* List of file data for each of the vnode's open file descriptors */ + /* List of file handles for all of the vnode's open file descriptors */ LIST_HEAD(, fuse_filehandle) handles; /** flags **/ diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 61e11725db52..2729956fda93 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -478,6 +478,8 @@ fuse_vnop_create(struct vop_create_args *ap) goto out; } ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create"); + fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, + feo->attr_valid_nsec, NULL); fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, td, cred, foo); fuse_vnode_open(*vpp, foo->open_flags, td); @@ -555,12 +557,9 @@ fuse_vnop_getattr(struct vop_getattr_args *ap) struct vattr *vap = ap->a_vap; struct ucred *cred = ap->a_cred; struct thread *td = curthread; - struct fuse_vnode_data *fvdat = VTOFUD(vp); - struct fuse_attr_out *fao; int err = 0; int dataflags; - struct fuse_dispatcher fdi; dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags; @@ -575,48 +574,14 @@ fuse_vnop_getattr(struct vop_getattr_args *ap) goto fake; } } - fdisp_init(&fdi, 0); - if ((err = fdisp_simple_putget_vp(&fdi, FUSE_GETATTR, vp, td, cred))) { - if ((err == ENOTCONN) && vnode_isvroot(vp)) { - /* see comment in fuse_vfsop_statfs() */ - fdisp_destroy(&fdi); - goto fake; - } - if (err == ENOENT) { - fuse_internal_vnode_disappear(vp); - } - goto out; + err = fuse_internal_getattr(vp, vap, cred, td); + if (err == ENOTCONN && vnode_isvroot(vp)) { + /* see comment in fuse_vfsop_statfs() */ + goto fake; + } else { + return err; } - fao = (struct fuse_attr_out *)fdi.answ; - fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, - fao->attr_valid_nsec, vap); - if (vap->va_type != vnode_vtype(vp)) { - fuse_internal_vnode_disappear(vp); - err = ENOENT; - goto out; - } - if ((fvdat->flag & FN_SIZECHANGE) != 0) - vap->va_size = fvdat->filesize; - - if (vnode_isreg(vp) && (fvdat->flag & FN_SIZECHANGE) == 0) { - /* - * This is for those cases when the file size changed without us - * knowing, and we want to catch up. - */ - off_t new_filesize = ((struct fuse_attr_out *) - fdi.answ)->attr.size; - - if (fvdat->filesize != new_filesize) { - fuse_vnode_setsize(vp, cred, new_filesize); - fvdat->flag &= ~FN_SIZECHANGE; - } - } - -out: - fdisp_destroy(&fdi); - return err; - fake: bzero(vap, sizeof(*vap)); vap->va_type = vnode_vtype(vp); diff --git a/tests/sys/fs/fusefs/allow_other.cc b/tests/sys/fs/fusefs/allow_other.cc index 9c47f5d4fcf4..3da51aca4598 100644 --- a/tests/sys/fs/fusefs/allow_other.cc +++ b/tests/sys/fs/fusefs/allow_other.cc @@ -80,7 +80,6 @@ TEST_F(AllowOther, allowed) expect_open(ino, 0, 1); expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, FH); - expect_getattr(ino, 0); }, []() { int fd; @@ -137,7 +136,6 @@ TEST_F(AllowOther, privilege_escalation) _) ).Times(AnyNumber()) .WillRepeatedly(Invoke(ReturnErrno(EPERM))); - expect_getattr(ino, 0); fd1 = open(FULLPATH, O_RDONLY); EXPECT_LE(0, fd1) << strerror(errno); diff --git a/tests/sys/fs/fusefs/create.cc b/tests/sys/fs/fusefs/create.cc index ccfaad17d6b6..21ec481f55ac 100644 --- a/tests/sys/fs/fusefs/create.cc +++ b/tests/sys/fs/fusefs/create.cc @@ -59,8 +59,7 @@ void expect_create(const char *relpath, ProcessMockerT r) * If FUSE_CREATE sets the attr_valid, then subsequent GETATTRs should use the * attribute cache */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */ -TEST_F(Create, DISABLED_attr_cache) +TEST_F(Create, attr_cache) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -151,19 +150,6 @@ TEST_F(Create, Enosys) SET_OUT_HEADER_LEN(out, open); }))); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0644; - }))); - fd = open(FULLPATH, O_CREAT | O_EXCL, mode); EXPECT_LE(0, fd) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ @@ -196,19 +182,6 @@ TEST_F(Create, entry_cache_negative) out->body.create.entry.attr_valid = UINT64_MAX; })); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0644; - }))); - fd = open(FULLPATH, O_CREAT | O_EXCL, mode); ASSERT_LE(0, fd) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ @@ -239,19 +212,6 @@ TEST_F(Create, entry_cache_negative_purge) out->body.create.entry.attr_valid = UINT64_MAX; })); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0644; - }))); - fd = open(FULLPATH, O_CREAT | O_EXCL, mode); ASSERT_LE(0, fd) << strerror(errno); @@ -296,19 +256,6 @@ TEST_F(Create, ok) out->body.create.entry.attr_valid = UINT64_MAX; })); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | mode; - }))); - fd = open(FULLPATH, O_CREAT | O_EXCL, mode); EXPECT_LE(0, fd) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ @@ -339,19 +286,6 @@ TEST_F(Create, wronly_0444) out->body.create.entry.attr_valid = UINT64_MAX; })); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | mode; - }))); - fd = open(FULLPATH, O_CREAT | O_WRONLY, mode); EXPECT_LE(0, fd) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ diff --git a/tests/sys/fs/fusefs/default_permissions.cc b/tests/sys/fs/fusefs/default_permissions.cc index c5b69632da02..0097e058dfa8 100644 --- a/tests/sys/fs/fusefs/default_permissions.cc +++ b/tests/sys/fs/fusefs/default_permissions.cc @@ -111,8 +111,6 @@ TEST_F(Open, ok) expect_lookup(RELPATH, ino, S_IFREG | 0644); expect_open(ino, 0, 1); - /* Until the attr cache is working, we may send an additional GETATTR */ - expect_getattr(ino, 0); fd = open(FULLPATH, O_RDONLY); EXPECT_LE(0, fd) << strerror(errno); diff --git a/tests/sys/fs/fusefs/flush.cc b/tests/sys/fs/fusefs/flush.cc index e9f17c667756..5ec6f1e7074b 100644 --- a/tests/sys/fs/fusefs/flush.cc +++ b/tests/sys/fs/fusefs/flush.cc @@ -96,7 +96,6 @@ TEST_F(Flush, open_twice) expect_lookup(RELPATH, ino, 2); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 2, 0, ReturnErrno(0)); expect_release(); @@ -127,7 +126,6 @@ TEST_F(Flush, eio) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 1, 0, ReturnErrno(EIO)); expect_release(); @@ -153,14 +151,12 @@ TEST_F(Flush, enosys) expect_lookup(RELPATH0, ino0, 1); expect_open(ino0, 0, 1); - expect_getattr(ino0, 0); /* On the 2nd close, FUSE_FLUSH won't be sent at all */ expect_flush(ino0, 1, 0, ReturnErrno(ENOSYS)); expect_release(); expect_lookup(RELPATH1, ino1, 1); expect_open(ino1, 0, 1); - expect_getattr(ino1, 0); /* On the 2nd close, FUSE_FLUSH won't be sent at all */ expect_release(); @@ -184,7 +180,6 @@ TEST_F(Flush, flush) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 1, 0, ReturnErrno(0)); expect_release(); @@ -210,7 +205,6 @@ TEST_F(FlushWithLocks, DISABLED_unlock_on_close) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_SETLK && diff --git a/tests/sys/fs/fusefs/fsync.cc b/tests/sys/fs/fusefs/fsync.cc index 2cfc23f2c38a..c602b2488e98 100644 --- a/tests/sys/fs/fusefs/fsync.cc +++ b/tests/sys/fs/fusefs/fsync.cc @@ -93,7 +93,6 @@ TEST_F(Fsync, aio_fsync) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, bufsize, CONTENTS); expect_fsync(ino, 0, 0); @@ -127,7 +126,6 @@ TEST_F(Fsync, close) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, bufsize, CONTENTS); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -164,7 +162,6 @@ TEST_F(Fsync, eio) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, bufsize, CONTENTS); expect_fsync(ino, FUSE_FSYNC_FDATASYNC, EIO); @@ -194,7 +191,6 @@ TEST_F(Fsync, DISABLED_enosys) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, bufsize, CONTENTS); expect_fsync(ino, FUSE_FSYNC_FDATASYNC, ENOSYS); @@ -220,7 +216,6 @@ TEST_F(Fsync, fdatasync) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, bufsize, CONTENTS); expect_fsync(ino, FUSE_FSYNC_FDATASYNC, 0); @@ -243,7 +238,6 @@ TEST_F(Fsync, fsync) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, bufsize, CONTENTS); expect_fsync(ino, 0, 0); diff --git a/tests/sys/fs/fusefs/getattr.cc b/tests/sys/fs/fusefs/getattr.cc index 9e81b3b46ab1..d4ba90907573 100644 --- a/tests/sys/fs/fusefs/getattr.cc +++ b/tests/sys/fs/fusefs/getattr.cc @@ -33,14 +33,32 @@ using namespace testing; -class Getattr : public FuseTest {}; +class Getattr : public FuseTest { +public: +void expect_lookup(const char *relpath, uint64_t ino, mode_t mode, + uint64_t size, int times, uint64_t attr_valid, uint32_t attr_valid_nsec) +{ + EXPECT_LOOKUP(1, relpath) + .Times(times) + .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + SET_OUT_HEADER_LEN(out, entry); + out->body.entry.attr.mode = mode; + out->body.entry.nodeid = ino; + out->body.entry.attr.nlink = 1; + out->body.entry.attr_valid = attr_valid; + out->body.entry.attr_valid_nsec = attr_valid_nsec; + out->body.entry.attr.size = size; + out->body.entry.entry_valid = UINT64_MAX; + }))); +} +}; + /* * If getattr returns a non-zero cache timeout, then subsequent VOP_GETATTRs * should use the cached attributes, rather than query the daemon */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */ -TEST_F(Getattr, DISABLED_attr_cache) +TEST_F(Getattr, attr_cache) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -52,6 +70,7 @@ TEST_F(Getattr, DISABLED_attr_cache) SET_OUT_HEADER_LEN(out, entry); out->body.entry.attr.mode = S_IFREG | 0644; out->body.entry.nodeid = ino; + out->body.entry.entry_valid = UINT64_MAX; }))); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -76,7 +95,7 @@ TEST_F(Getattr, DISABLED_attr_cache) * period passes. */ /* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */ -TEST_F(Getattr, attr_cache_timeout) +TEST_F(Getattr, DISABLED_attr_cache_timeout) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -88,7 +107,7 @@ TEST_F(Getattr, attr_cache_timeout) */ long timeout_ns = 250'000'000; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2, 0, 0); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { return (in->header.opcode == FUSE_GETATTR && @@ -116,7 +135,7 @@ TEST_F(Getattr, enoent) struct stat sb; const uint64_t ino = 42; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1, 0, 0); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { return (in->header.opcode == FUSE_GETATTR && @@ -135,7 +154,7 @@ TEST_F(Getattr, ok) const uint64_t ino = 42; struct stat sb; - expect_lookup(RELPATH, ino, S_IFREG | 0644, 1, 1); + expect_lookup(RELPATH, ino, S_IFREG | 0644, 1, 1, 0, 0); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { return (in->header.opcode == FUSE_GETATTR && diff --git a/tests/sys/fs/fusefs/locks.cc b/tests/sys/fs/fusefs/locks.cc index a1d37357ffb1..493110fa1a3c 100644 --- a/tests/sys/fs/fusefs/locks.cc +++ b/tests/sys/fs/fusefs/locks.cc @@ -80,7 +80,6 @@ TEST_F(GetlkFallback, local) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); @@ -110,7 +109,6 @@ TEST_F(Getlk, DISABLED_no_locks) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_GETLK && @@ -156,7 +154,6 @@ TEST_F(Getlk, DISABLED_lock_exists) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_GETLK && @@ -209,7 +206,6 @@ TEST_F(SetlkFallback, local) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); @@ -236,7 +232,6 @@ TEST_F(Setlk, DISABLED_set) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_SETLK && @@ -279,7 +274,6 @@ TEST_F(Setlk, DISABLED_set_eof) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_SETLK && @@ -322,7 +316,6 @@ TEST_F(Setlk, DISABLED_eagain) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_SETLK && @@ -364,7 +357,6 @@ TEST_F(SetlkwFallback, local) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); @@ -395,7 +387,6 @@ TEST_F(Setlkw, DISABLED_set) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_SETLK && diff --git a/tests/sys/fs/fusefs/lookup.cc b/tests/sys/fs/fusefs/lookup.cc index b4cc21a70ed6..8b47286bb4cf 100644 --- a/tests/sys/fs/fusefs/lookup.cc +++ b/tests/sys/fs/fusefs/lookup.cc @@ -43,8 +43,7 @@ class Lookup: public FuseTest {}; * If lookup returns a non-zero cache timeout, then subsequent VOP_GETATTRs * should use the cached attributes, rather than query the daemon */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */ -TEST_F(Lookup, DISABLED_attr_cache) +TEST_F(Lookup, attr_cache) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -106,7 +105,7 @@ TEST_F(Lookup, DISABLED_attr_cache) * the cached attributes and requery the daemon. */ /* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */ -TEST_F(Lookup, attr_cache_timeout) +TEST_F(Lookup, DISABLED_attr_cache_timeout) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; diff --git a/tests/sys/fs/fusefs/open.cc b/tests/sys/fs/fusefs/open.cc index 383c7f75c1ba..e73e329edfac 100644 --- a/tests/sys/fs/fusefs/open.cc +++ b/tests/sys/fs/fusefs/open.cc @@ -61,9 +61,6 @@ void test_ok(int os_flags, int fuse_flags) { SET_OUT_HEADER_LEN(out, open); }))); - /* Until the attr cache is working, we may send an additional GETATTR */ - expect_getattr(ino, 0); - fd = open(FULLPATH, os_flags); EXPECT_LE(0, fd) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ @@ -204,7 +201,6 @@ TEST_F(Open, multiple_creds) out->header.len = sizeof(out->header); SET_OUT_HEADER_LEN(out, open); }))); - expect_getattr(ino, 0); expect_flush(ino, 2, ReturnErrno(0)); expect_release(ino, fh0); expect_release(ino, fh1); diff --git a/tests/sys/fs/fusefs/read.cc b/tests/sys/fs/fusefs/read.cc index 70d43b233f0d..a85b2f0dd126 100644 --- a/tests/sys/fs/fusefs/read.cc +++ b/tests/sys/fs/fusefs/read.cc @@ -117,7 +117,6 @@ TEST_F(AioRead, aio_read) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDONLY); @@ -152,7 +151,6 @@ TEST_F(AioRead, async_read_disabled) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_READ && @@ -230,7 +228,6 @@ TEST_F(AsyncRead, DISABLED_async_read) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_READ && @@ -299,7 +296,6 @@ TEST_F(Read, direct_io_read_nothing) expect_lookup(RELPATH, ino, offset + 1000); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_getattr(ino, offset + 1000); fd = open(FULLPATH, O_RDONLY); ASSERT_LE(0, fd) << strerror(errno); @@ -325,7 +321,6 @@ TEST_F(Read, direct_io_pread) expect_lookup(RELPATH, ino, offset + bufsize); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_getattr(ino, offset + bufsize); expect_read(ino, offset, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDONLY); @@ -354,7 +349,6 @@ TEST_F(Read, direct_io_short_read) expect_lookup(RELPATH, ino, offset + bufsize); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_getattr(ino, offset + bufsize); expect_read(ino, offset, bufsize, halfbufsize, CONTENTS); fd = open(FULLPATH, O_RDONLY); @@ -378,7 +372,6 @@ TEST_F(Read, eio) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_READ); @@ -410,7 +403,6 @@ TEST_F(Read, keep_cache) FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2); expect_open(ino, FOPEN_KEEP_CACHE, 2); - expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); fd0 = open(FULLPATH, O_RDONLY); @@ -445,7 +437,6 @@ TEST_F(Read, keep_cache_disabled) FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2); expect_open(ino, 0, 2); - expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); fd0 = open(FULLPATH, O_RDONLY); @@ -482,7 +473,6 @@ TEST_F(ReadCacheable, mmap) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); /* mmap may legitimately try to read more data than is available */ EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -526,7 +516,6 @@ TEST_F(Read, o_direct) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDONLY); @@ -563,7 +552,6 @@ TEST_F(Read, pread) expect_lookup(RELPATH, ino, offset + bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, offset + bufsize); expect_read(ino, offset, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDONLY); @@ -586,7 +574,6 @@ TEST_F(Read, read) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDONLY); @@ -620,7 +607,6 @@ TEST_F(ReadCacheable, default_readahead) expect_lookup(RELPATH, ino, filesize); expect_open(ino, 0, 1); - expect_getattr(ino, filesize); expect_read(ino, 0, default_maxreadahead, default_maxreadahead, contents); @@ -651,7 +637,6 @@ TEST_F(ReadCacheable, sendfile) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); /* Like mmap, sendfile may request more data than is available */ EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -697,7 +682,6 @@ TEST_F(ReadCacheable, DISABLED_sendfile_eio) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_READ); @@ -739,7 +723,6 @@ TEST_P(ReadAhead, DISABLED_readahead) { expect_lookup(RELPATH, ino, filesize); expect_open(ino, 0, 1); - expect_getattr(ino, filesize); /* fuse(4) should only read ahead the allowed amount */ expect_read(ino, 0, GetParam(), GetParam(), contents); diff --git a/tests/sys/fs/fusefs/release.cc b/tests/sys/fs/fusefs/release.cc index 2e0252ede1b0..cad3a73d6406 100644 --- a/tests/sys/fs/fusefs/release.cc +++ b/tests/sys/fs/fusefs/release.cc @@ -81,7 +81,6 @@ TEST_F(Release, dup) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, 0, O_RDONLY, 0); @@ -111,7 +110,6 @@ TEST_F(Release, eio) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, 0, O_WRONLY, EIO); @@ -134,7 +132,6 @@ TEST_F(Release, DISABLED_flags) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, 0, O_RDWR | O_APPEND, 0); @@ -158,7 +155,6 @@ TEST_F(Release, multiple_opens) expect_lookup(RELPATH, ino, 2); expect_open(ino, 0, 2); - expect_getattr(ino, 0); expect_flush(ino, 2, ReturnErrno(0)); expect_release(ino, 0, O_RDONLY, 0); @@ -182,7 +178,6 @@ TEST_F(Release, ok) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, 0, O_RDONLY, 0); @@ -205,7 +200,6 @@ TEST_F(ReleaseWithLocks, DISABLED_unlock_on_close) expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); - expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_SETLK && diff --git a/tests/sys/fs/fusefs/setattr.cc b/tests/sys/fs/fusefs/setattr.cc index 3a63f9dd202e..8a413032059b 100644 --- a/tests/sys/fs/fusefs/setattr.cc +++ b/tests/sys/fs/fusefs/setattr.cc @@ -46,8 +46,7 @@ class Setattr : public FuseTest {}; * If setattr returns a non-zero cache timeout, then subsequent VOP_GETATTRs * should use the cached attributes, rather than query the daemon */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */ -TEST_F(Setattr, DISABLED_attr_cache) +TEST_F(Setattr, attr_cache) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -60,11 +59,11 @@ TEST_F(Setattr, DISABLED_attr_cache) SET_OUT_HEADER_LEN(out, entry); out->body.entry.attr.mode = S_IFREG | 0644; out->body.entry.nodeid = ino; + out->body.entry.entry_valid = UINT64_MAX; }))); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - /* In protocol 7.23, ctime will be changed too */ return (in->header.opcode == FUSE_SETATTR && in->header.nodeid == ino); }, Eq(true)), @@ -73,6 +72,7 @@ TEST_F(Setattr, DISABLED_attr_cache) SET_OUT_HEADER_LEN(out, attr); out->body.attr.attr.ino = ino; // Must match nodeid out->body.attr.attr.mode = S_IFREG | newmode; + out->body.attr.attr_valid = UINT64_MAX; }))); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -227,19 +227,6 @@ TEST_F(Setattr, fchmod) SET_OUT_HEADER_LEN(out, open); }))); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | oldmode; - }))); - EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { /* In protocol 7.23, ctime will be changed too */ @@ -294,20 +281,6 @@ TEST_F(Setattr, ftruncate) out->body.open.fh = fh; }))); - /* Until the attr cache is working, we may send an additional GETATTR */ - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0755; - out->body.attr.attr.size = oldsize; - }))); - EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { /* In protocol 7.23, ctime will be changed too */ @@ -502,26 +475,6 @@ TEST_F(Setattr, utimensat) { out->body.entry.attr.mtimensec = oldtimes[1].tv_nsec; }))); - /* - * Until bug 235775 is fixed, utimensat will make an extra FUSE_GETATTR - * call - */ - EXPECT_CALL(*m_mock, process( - ResultOf([](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0644; - out->body.attr.attr.atime = oldtimes[0].tv_sec; - out->body.attr.attr.atimensec = oldtimes[0].tv_nsec; - out->body.attr.attr.mtime = oldtimes[1].tv_sec; - out->body.attr.attr.mtimensec = oldtimes[1].tv_nsec; - }))); - EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { /* In protocol 7.23, ctime will be changed too */ @@ -576,26 +529,6 @@ TEST_F(Setattr, utimensat_mtime_only) { out->body.entry.attr.mtimensec = oldtimes[1].tv_nsec; }))); - /* - * Until bug 235775 is fixed, utimensat will make an extra FUSE_GETATTR - * call - */ - EXPECT_CALL(*m_mock, process( - ResultOf([](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0644; - out->body.attr.attr.atime = oldtimes[0].tv_sec; - out->body.attr.attr.atimensec = oldtimes[0].tv_nsec; - out->body.attr.attr.mtime = oldtimes[1].tv_sec; - out->body.attr.attr.mtimensec = oldtimes[1].tv_nsec; - }))); - EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { /* In protocol 7.23, ctime will be changed too */ diff --git a/tests/sys/fs/fusefs/unlink.cc b/tests/sys/fs/fusefs/unlink.cc index bdcdf4b8e151..b7516f192d5d 100644 --- a/tests/sys/fs/fusefs/unlink.cc +++ b/tests/sys/fs/fusefs/unlink.cc @@ -92,7 +92,6 @@ TEST_F(Unlink, open_but_deleted) expect_lookup(RELPATH, ino, 2); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_unlink(1, RELPATH, 0); fd = open(FULLPATH, O_RDWR); diff --git a/tests/sys/fs/fusefs/utils.cc b/tests/sys/fs/fusefs/utils.cc index 224de4a5d9df..27f8ca00db57 100644 --- a/tests/sys/fs/fusefs/utils.cc +++ b/tests/sys/fs/fusefs/utils.cc @@ -144,14 +144,13 @@ FuseTest::expect_flush(uint64_t ino, int times, ProcessMockerT r) void FuseTest::expect_getattr(uint64_t ino, uint64_t size) { - /* Until the attr cache is working, we may send an additional GETATTR */ EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in->header.opcode == FUSE_GETATTR && in->header.nodeid == ino); }, Eq(true)), _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto out) { SET_OUT_HEADER_LEN(out, attr); out->body.attr.attr.ino = ino; // Must match nodeid out->body.attr.attr.mode = S_IFREG | 0644; diff --git a/tests/sys/fs/fusefs/write.cc b/tests/sys/fs/fusefs/write.cc index cd863b91ef6b..dc2dfd744f06 100644 --- a/tests/sys/fs/fusefs/write.cc +++ b/tests/sys/fs/fusefs/write.cc @@ -153,7 +153,6 @@ TEST_F(AioWrite, DISABLED_aio_write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); fd = open(FULLPATH, O_WRONLY); @@ -197,7 +196,6 @@ TEST_F(Write, append) expect_lookup(RELPATH, ino, initial_offset); expect_open(ino, 0, 1); - expect_getattr(ino, initial_offset); expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS); /* Must open O_RDWR or fuse(4) implicitly sets direct_io */ @@ -220,7 +218,6 @@ TEST_F(Write, append_direct_io) expect_lookup(RELPATH, ino, initial_offset); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_getattr(ino, initial_offset); expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS); fd = open(FULLPATH, O_WRONLY | O_APPEND); @@ -245,7 +242,6 @@ TEST_F(Write, DISABLED_direct_io_evicts_cache) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); - expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS1); @@ -290,7 +286,6 @@ TEST_F(Write, indirect_io_short_write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize0, 0, CONTENTS); expect_write(ino, bufsize0, bufsize1, bufsize1, 0, contents1); @@ -318,7 +313,6 @@ TEST_F(Write, direct_io_short_write) expect_lookup(RELPATH, ino, 0); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, halfbufsize, 0, CONTENTS); fd = open(FULLPATH, O_WRONLY); @@ -349,7 +343,6 @@ TEST_F(Write, direct_io_short_write_iov) expect_lookup(RELPATH, ino, 0); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_getattr(ino, 0); expect_write(ino, 0, totalsize, size0, 0, EXPECTED0); fd = open(FULLPATH, O_WRONLY); @@ -392,7 +385,6 @@ TEST_F(Write, DISABLED_mmap) expect_lookup(RELPATH, ino, len); expect_open(ino, 0, 1); - expect_getattr(ino, len); expect_read(ino, 0, len, len, zeros); /* * Writes from the pager may or may not be associated with the correct @@ -429,7 +421,6 @@ TEST_F(WriteThrough, pwrite) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); fd = open(FULLPATH, O_WRONLY); @@ -451,7 +442,6 @@ TEST_F(Write, write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); fd = open(FULLPATH, O_WRONLY); @@ -481,7 +471,6 @@ TEST_F(Write, write_large) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, halfbufsize, halfbufsize, 0, contents); expect_write(ino, halfbufsize, halfbufsize, halfbufsize, 0, &contents[halfbufsize / sizeof(int)]); @@ -506,7 +495,6 @@ TEST_F(Write, write_nothing) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -527,7 +515,6 @@ TEST_F(WriteBack, close) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -564,9 +551,8 @@ TEST_F(WriteBack, rmw) int fd; ssize_t bufsize = strlen(CONTENTS); - expect_lookup(RELPATH, ino, 0); + FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, fsize, 1); expect_open(ino, 0, 1); - expect_getattr(ino, fsize); expect_read(ino, 0, fsize, fsize, INITIAL); expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); @@ -593,7 +579,6 @@ TEST_F(WriteBack, writeback) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); fd = open(FULLPATH, O_RDWR); @@ -626,7 +611,6 @@ TEST_F(WriteBack, o_direct) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); expect_read(ino, 0, bufsize, bufsize, CONTENTS); @@ -660,7 +644,6 @@ TEST_F(WriteThrough, DISABLED_writethrough) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_getattr(ino, 0); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); fd = open(FULLPATH, O_RDWR); @@ -676,8 +659,7 @@ TEST_F(WriteThrough, DISABLED_writethrough) } /* With writethrough caching, writes update the cached file size */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */ -TEST_F(WriteThrough, DISABLED_update_file_size) +TEST_F(WriteThrough, update_file_size) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -689,20 +671,6 @@ TEST_F(WriteThrough, DISABLED_update_file_size) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); - }, Eq(true)), - _) - ).Times(2) - .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out) { - SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | 0644; - out->body.attr.attr.size = 0; - out->body.attr.attr_valid = UINT64_MAX; - }))); expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); fd = open(FULLPATH, O_RDWR);