svn commit: r345852 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Alan Somers
asomers at FreeBSD.org
Wed Apr 3 19:59:49 UTC 2019
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);
More information about the svn-src-projects
mailing list