Date: Tue, 03 Sep 2019 14:06:11 -0000 From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r345852 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs Message-ID: <201904031959.x33JxkKS047902@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: asomers Date: Wed Apr 3 19:59:45 2019 New Revision: 345852 URL: https://svnweb.freebsd.org/changeset/base/345852 Log: fusefs: send FUSE_FLUSH during VOP_CLOSE The FUSE protocol says that FUSE_FLUSH should be send every time a file descriptor is closed. That's not quite possible in FreeBSD because multiple file descriptors can share a single struct file, and closef doesn't call fo_close until the last close. However, we can still send FUSE_FLUSH on every VOP_CLOSE, which is probably good enough. There are two purposes for FUSE_FLUSH. One is to allow file systems to return EIO if they have an error when writing data that's cached server-side. The other is to release POSIX file locks (which fusefs(5) does not yet support). PR: 236405, 236327 Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_file.c projects/fuse2/sys/fs/fuse/fuse_file.h projects/fuse2/sys/fs/fuse/fuse_io.c projects/fuse2/sys/fs/fuse/fuse_node.c projects/fuse2/sys/fs/fuse/fuse_vnops.c projects/fuse2/tests/sys/fs/fusefs/allow_other.cc projects/fuse2/tests/sys/fs/fusefs/flush.cc projects/fuse2/tests/sys/fs/fusefs/fsync.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.cc projects/fuse2/tests/sys/fs/fusefs/open.cc projects/fuse2/tests/sys/fs/fusefs/release.cc projects/fuse2/tests/sys/fs/fusefs/utils.cc projects/fuse2/tests/sys/fs/fusefs/utils.hh projects/fuse2/tests/sys/fs/fusefs/write.cc Modified: projects/fuse2/sys/fs/fuse/fuse_file.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.c Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/sys/fs/fuse/fuse_file.c Wed Apr 3 19:59:45 2019 (r345852) @@ -273,12 +273,14 @@ fuse_filehandle_validrw(struct vnode *vp, int mode, } int -fuse_filehandle_get(struct vnode *vp, fufh_type_t fufh_type, +fuse_filehandle_get(struct vnode *vp, int fflag, struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid) { struct fuse_vnode_data *fvdat = VTOFUD(vp); struct fuse_filehandle *fufh; + fufh_type_t fufh_type; + fufh_type = fflags_2_fufh_type(fflag); if (cred == NULL) goto fallback; @@ -307,14 +309,14 @@ found: } int -fuse_filehandle_getrw(struct vnode *vp, fufh_type_t fufh_type, +fuse_filehandle_getrw(struct vnode *vp, int fflag, struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid) { int err; - err = fuse_filehandle_get(vp, fufh_type, fufhp, cred, pid); + err = fuse_filehandle_get(vp, fflag, fufhp, cred, pid); if (err) - err = fuse_filehandle_get(vp, FUFH_RDWR, fufhp, cred, pid); + err = fuse_filehandle_get(vp, FREAD | FWRITE, fufhp, cred, pid); return err; } Modified: projects/fuse2/sys/fs/fuse/fuse_file.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.h Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/sys/fs/fuse/fuse_file.h Wed Apr 3 19:59:45 2019 (r345852) @@ -150,10 +150,10 @@ struct fuse_filehandle { bool fuse_filehandle_validrw(struct vnode *vp, int mode, struct ucred *cred, pid_t pid); -int fuse_filehandle_get(struct vnode *vp, fufh_type_t fufh_type, +int fuse_filehandle_get(struct vnode *vp, int fflag, struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid); -int fuse_filehandle_getrw(struct vnode *vp, fufh_type_t fufh_type, +int fuse_filehandle_getrw(struct vnode *vp, int fflag, struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid); Modified: projects/fuse2/sys/fs/fuse/fuse_io.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_io.c Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/sys/fs/fuse/fuse_io.c Wed Apr 3 19:59:45 2019 (r345852) @@ -127,12 +127,12 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, in { struct fuse_filehandle *fufh; int err, directio; - fufh_type_t fufh_type; + int fflag; MPASS(vp->v_type == VREG || vp->v_type == VDIR); - fufh_type = (uio->uio_rw == UIO_READ) ? FUFH_RDONLY : FUFH_WRONLY; - err = fuse_filehandle_getrw(vp, fufh_type, &fufh, cred, pid); + fflag = (uio->uio_rw == UIO_READ) ? FREAD : FWRITE; + err = fuse_filehandle_getrw(vp, fflag, &fufh, cred, pid); if (err) { printf("FUSE: io dispatch: filehandles are closed\n"); return err; @@ -643,7 +643,7 @@ fuse_io_strategy(struct vnode *vp, struct buf *bp) struct uio uio; struct iovec io; int error = 0; - fufh_type_t fufh_type; + int fflag; /* We don't know the true pid when we're dealing with the cache */ pid_t pid = 0; @@ -652,9 +652,9 @@ fuse_io_strategy(struct vnode *vp, struct buf *bp) MPASS(vp->v_type == VREG || vp->v_type == VDIR); MPASS(bp->b_iocmd == BIO_READ || bp->b_iocmd == BIO_WRITE); - fufh_type = bp->b_iocmd == BIO_READ ? FUFH_RDONLY : FUFH_WRONLY; + fflag = bp->b_iocmd == BIO_READ ? FREAD : FWRITE; cred = bp->b_iocmd == BIO_READ ? bp->b_rcred : bp->b_wcred; - error = fuse_filehandle_getrw(vp, fufh_type, &fufh, cred, pid); + error = fuse_filehandle_getrw(vp, fflag, &fufh, cred, pid); if (bp->b_iocmd == BIO_READ && error == EBADF) { /* * This may be a read-modify-write operation on a cached file @@ -662,8 +662,7 @@ fuse_io_strategy(struct vnode *vp, struct buf *bp) * * TODO: eliminate this hacky check once the FUFH table is gone */ - fufh_type = FUFH_WRONLY; - error = fuse_filehandle_get(vp, fufh_type, &fufh, cred, pid); + error = fuse_filehandle_get(vp, FWRITE, &fufh, cred, pid); } if (error) { printf("FUSE: strategy: filehandles are closed\n"); Modified: projects/fuse2/sys/fs/fuse/fuse_node.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_node.c Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/sys/fs/fuse/fuse_node.c Wed Apr 3 19:59:45 2019 (r345852) @@ -378,7 +378,7 @@ fuse_vnode_savesize(struct vnode *vp, struct ucred *cr fsai->size = fvdat->filesize; fsai->valid |= FATTR_SIZE; - fuse_filehandle_getrw(vp, FUFH_WRONLY, &fufh, cred, pid); + fuse_filehandle_getrw(vp, FWRITE, &fufh, cred, pid); if (fufh) { fsai->fh = fufh->fh_id; fsai->valid |= FATTR_FH; Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vnops.c Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Wed Apr 3 19:59:45 2019 (r345852) @@ -221,11 +221,43 @@ static int fuse_filehandle_get_dir(struct vnode *vp, struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid) { - if (fuse_filehandle_get(vp, FUFH_RDONLY, fufhp, cred, pid) == 0) + if (fuse_filehandle_get(vp, FREAD, fufhp, cred, pid) == 0) return 0; - return fuse_filehandle_get(vp, FUFH_EXEC, fufhp, cred, pid); + return fuse_filehandle_get(vp, FEXEC, fufhp, cred, pid); } +/* Send FUSE_FLUSH for this vnode */ +static int +fuse_flush(struct vnode *vp, struct ucred *cred, pid_t pid, int fflag) +{ + struct fuse_flush_in *ffi; + struct fuse_filehandle *fufh; + struct fuse_dispatcher fdi; + struct thread *td = curthread; + struct mount *mp = vnode_mount(vp); + int err; + + if (!fsess_isimpl(vnode_mount(vp), FUSE_FLUSH)) + return 0; + + err = fuse_filehandle_get(vp, fflag, &fufh, cred, pid); + if (err) + return err; + + fdisp_init(&fdi, sizeof(*ffi)); + fdisp_make_vp(&fdi, FUSE_FLUSH, vp, td, cred); + ffi = fdi.indata; + ffi->fh = fufh->fh_id; + + err = fdisp_wait_answ(&fdi); + if (err == ENOSYS) { + fsess_set_notimpl(mp, FUSE_FLUSH); + err = 0; + } + fdisp_destroy(&fdi); + return err; +} + /* struct vnop_access_args { struct vnode *a_vp; @@ -275,7 +307,7 @@ fuse_vnop_access(struct vop_access_args *ap) } /* - struct vnop_close_args { + struct vop_close_args { struct vnode *a_vp; int a_fflag; struct ucred *a_cred; @@ -290,6 +322,7 @@ fuse_vnop_close(struct vop_close_args *ap) int fflag = ap->a_fflag; struct thread *td = ap->a_td; pid_t pid = td->td_proc->p_pid; + int err = 0; if (fuse_isdeadfs(vp)) { return 0; @@ -297,6 +330,8 @@ fuse_vnop_close(struct vop_close_args *ap) if (vnode_isdir(vp)) { struct fuse_filehandle *fufh; + // XXX: what if two file descriptors have the same directory + // opened? We shouldn't close the file handle too soon. if (fuse_filehandle_get_dir(vp, &fufh, cred, pid) == 0) fuse_filehandle_close(vp, fufh, NULL, cred); return 0; @@ -304,11 +339,12 @@ fuse_vnop_close(struct vop_close_args *ap) if (fflag & IO_NDELAY) { return 0; } + err = fuse_flush(vp, cred, pid, fflag); /* TODO: close the file handle, if we're sure it's no longer used */ if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) { fuse_vnode_savesize(vp, cred, td->td_proc->p_pid); } - return 0; + return err; } static void @@ -1611,7 +1647,7 @@ fuse_vnop_setattr(struct vop_setattr_args *ap) newsize = vap->va_size; fsai->valid |= FATTR_SIZE; - fuse_filehandle_getrw(vp, FUFH_WRONLY, &fufh, cred, pid); + fuse_filehandle_getrw(vp, FWRITE, &fufh, cred, pid); if (fufh) { fsai->fh = fufh->fh_id; fsai->valid |= FATTR_FH; Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/allow_other.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/allow_other.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -78,6 +78,7 @@ TEST_F(AllowOther, allowed) expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_open(ino, 0, 1); + expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, FH); expect_getattr(ino, 0); }, []() { Modified: projects/fuse2/tests/sys/fs/fusefs/flush.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/flush.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/flush.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -41,7 +41,8 @@ using namespace testing; class Flush: public FuseTest { public: -void expect_flush(uint64_t ino, int times, pid_t lo, ProcessMockerT r) +void +expect_flush(uint64_t ino, int times, pid_t lo, ProcessMockerT r) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -55,9 +56,9 @@ void expect_flush(uint64_t ino, int times, pid_t lo, P .WillRepeatedly(Invoke(r)); } -void expect_lookup(const char *relpath, uint64_t ino) +void expect_lookup(const char *relpath, uint64_t ino, int times) { - FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1); + FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, times); } /* @@ -82,16 +83,18 @@ class FlushWithLocks: public Flush { } }; -/* If a file descriptor is duplicated, every close causes FLUSH */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236405 */ -TEST_F(Flush, DISABLED_dup) +/* + * If multiple file descriptors refer to the same file handle, closing each + * should send FUSE_FLUSH + */ +TEST_F(Flush, open_twice) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; int fd, fd2; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 2); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_flush(ino, 2, 0, ReturnErrno(0)); @@ -100,10 +103,11 @@ TEST_F(Flush, DISABLED_dup) fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); - fd2 = dup(fd); + fd2 = open(FULLPATH, O_WRONLY); + EXPECT_LE(0, fd2) << strerror(errno); - ASSERT_EQ(0, close(fd2)) << strerror(errno); - ASSERT_EQ(0, close(fd)) << strerror(errno); + EXPECT_EQ(0, close(fd2)) << strerror(errno); + EXPECT_EQ(0, close(fd)) << strerror(errno); } /* @@ -114,15 +118,14 @@ TEST_F(Flush, DISABLED_dup) * all. */ /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236405 */ -TEST_F(Flush, DISABLED_eio) +TEST_F(Flush, eio) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; int fd; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_flush(ino, 1, 0, ReturnErrno(EIO)); @@ -138,41 +141,48 @@ TEST_F(Flush, DISABLED_eio) * If the filesystem returns ENOSYS, it will be treated as success and * no more FUSE_FLUSH operations will be sent to the daemon */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236405 */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */ -TEST_F(Flush, DISABLED_enosys) +TEST_F(Flush, enosys) { - const char FULLPATH[] = "mountpoint/some_file.txt"; - const char RELPATH[] = "some_file.txt"; - uint64_t ino = 42; - int fd, fd2; + const char FULLPATH0[] = "mountpoint/some_file.txt"; + const char RELPATH0[] = "some_file.txt"; + const char FULLPATH1[] = "mountpoint/other_file.txt"; + const char RELPATH1[] = "other_file.txt"; + uint64_t ino0 = 42; + uint64_t ino1 = 43; + int fd0, fd1; - expect_lookup(RELPATH, ino); - expect_open(ino, 0, 1); - expect_getattr(ino, 0); + 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(ino, 1, 0, ReturnErrno(ENOSYS)); + expect_flush(ino0, 1, 0, ReturnErrno(ENOSYS)); expect_release(); - fd = open(FULLPATH, O_WRONLY); - EXPECT_LE(0, fd) << strerror(errno); + 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(); - fd2 = dup(fd); + fd0 = open(FULLPATH0, O_WRONLY); + ASSERT_LE(0, fd0) << strerror(errno); - EXPECT_EQ(0, close(fd2)) << strerror(errno); - EXPECT_EQ(0, close(fd)) << strerror(errno); + fd1 = open(FULLPATH1, O_WRONLY); + ASSERT_LE(0, fd1) << strerror(errno); + + EXPECT_EQ(0, close(fd0)) << strerror(errno); + EXPECT_EQ(0, close(fd1)) << strerror(errno); } /* A FUSE_FLUSH should be sent on close(2) */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236405 */ -TEST_F(Flush, DISABLED_flush) +TEST_F(Flush, flush) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; int fd; - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); expect_getattr(ino, 0); expect_flush(ino, 1, 0, ReturnErrno(0)); @@ -188,7 +198,6 @@ TEST_F(Flush, DISABLED_flush) * When closing a file with a POSIX file lock, flush should release the lock, * _even_if_ it's not the process's last file descriptor for this file. */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236405 */ /* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=234581 */ TEST_F(FlushWithLocks, DISABLED_unlock_on_close) { @@ -199,7 +208,7 @@ TEST_F(FlushWithLocks, DISABLED_unlock_on_close) struct flock fl; pid_t pid = getpid(); - expect_lookup(RELPATH, ino); + expect_lookup(RELPATH, ino, 1); expect_open(ino, 0, 1); expect_getattr(ino, 0); EXPECT_CALL(*m_mock, process( Modified: projects/fuse2/tests/sys/fs/fusefs/fsync.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/fsync.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/fsync.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -139,6 +139,7 @@ TEST_F(Fsync, close) }, Eq(true)), _) ).Times(0); + expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, FH); fd = open(FULLPATH, O_RDWR); Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -169,7 +169,8 @@ void debug_fuseop(const mockfs_buf_in *in) in->body.open.flags, name); break; case FUSE_FLUSH: - printf(" lock_owner=%lu", in->body.flush.lock_owner); + printf(" fh=%#lx lock_owner=%lu", in->body.flush.fh, + in->body.flush.lock_owner); break; case FUSE_FORGET: printf(" nlookup=%lu", in->body.forget.nlookup); Modified: projects/fuse2/tests/sys/fs/fusefs/open.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/open.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/open.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -205,6 +205,7 @@ TEST_F(Open, multiple_creds) SET_OUT_HEADER_LEN(out, open); }))); expect_getattr(ino, 0); + expect_flush(ino, 2, ReturnErrno(0)); expect_release(ino, fh0); expect_release(ino, fh1); Modified: projects/fuse2/tests/sys/fs/fusefs/release.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/release.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/release.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -82,6 +82,7 @@ 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); fd = open(FULLPATH, O_RDONLY); @@ -111,6 +112,7 @@ 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); fd = open(FULLPATH, O_WRONLY); @@ -133,6 +135,7 @@ 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); fd = open(FULLPATH, O_RDWR | O_APPEND); @@ -156,6 +159,7 @@ 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); fd = open(FULLPATH, O_RDONLY); @@ -179,6 +183,7 @@ 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); fd = open(FULLPATH, O_RDONLY); @@ -212,6 +217,7 @@ TEST_F(ReleaseWithLocks, DISABLED_unlock_on_close) SET_OUT_HEADER_LEN(out, setlk); out->body.setlk.lk = in->body.setlk.lk; }))); + expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, (uint64_t)pid, O_RDWR, 0); fd = open(FULLPATH, O_RDWR); Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/utils.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -114,6 +114,19 @@ FuseTest::expect_access(uint64_t ino, mode_t access_mo ).WillOnce(Invoke(ReturnErrno(error))); } +void +FuseTest::expect_flush(uint64_t ino, int times, ProcessMockerT r) +{ + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in->header.opcode == FUSE_FLUSH && + in->header.nodeid == ino); + }, Eq(true)), + _) + ).Times(times) + .WillRepeatedly(Invoke(r)); +} + void FuseTest::expect_getattr(uint64_t ino, uint64_t size) { /* Until the attr cache is working, we may send an additional GETATTR */ Modified: projects/fuse2/tests/sys/fs/fusefs/utils.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.hh Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/utils.hh Wed Apr 3 19:59:45 2019 (r345852) @@ -70,10 +70,16 @@ class FuseTest : public ::testing::Test { } /* - * Create an expectation that FUSE_ACCESS will be called oncde for the + * Create an expectation that FUSE_ACCESS will be called once for the * given inode with the given access_mode, returning the given errno */ void expect_access(uint64_t ino, mode_t access_mode, int error); + + /* + * Create an expectation that FUSE_FLUSH will be called times times for + * the given inode + */ + void expect_flush(uint64_t ino, int times, ProcessMockerT r); /* * Create an expectation that FUSE_GETATTR will be called for the given Modified: projects/fuse2/tests/sys/fs/fusefs/write.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/write.cc Wed Apr 3 19:35:07 2019 (r345851) +++ projects/fuse2/tests/sys/fs/fusefs/write.cc Wed Apr 3 19:59:45 2019 (r345852) @@ -374,6 +374,7 @@ TEST_F(Write, DISABLED_mmap) * pid, so they must set FUSE_WRITE_CACHE */ expect_write(ino, 0, len, len, FUSE_WRITE_CACHE, expected); + expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, ReturnErrno(0)); fd = open(FULLPATH, O_RDWR); @@ -512,6 +513,7 @@ TEST_F(WriteBack, close) SET_OUT_HEADER_LEN(out, attr); out->body.attr.attr.ino = ino; // Must match nodeid }))); + expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, ReturnErrno(0)); fd = open(FULLPATH, O_RDWR);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904031959.x33JxkKS047902>