svn commit: r359213 - in stable/12: sys/fs/fuse tests/sys/fs/fusefs
Alan Somers
asomers at FreeBSD.org
Sun Mar 22 15:17:00 UTC 2020
Author: asomers
Date: Sun Mar 22 15:16:59 2020
New Revision: 359213
URL: https://svnweb.freebsd.org/changeset/base/359213
Log:
MFC r358798:
fusefs: fix fsync for files with multiple open handles
We were reusing a structure for multiple operations, but failing to
reinitialize one member. The result is that a server that cares about FUSE
file handle IDs would see one correct FUSE_FSYNC operation, and one with the
FHID unset.
PR: 244431
Reported by: Agata <chogata at gmail.com>
Modified:
stable/12/sys/fs/fuse/fuse_internal.c
stable/12/tests/sys/fs/fusefs/fsync.cc
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/fs/fuse/fuse_internal.c
==============================================================================
--- stable/12/sys/fs/fuse/fuse_internal.c Sun Mar 22 15:03:09 2020 (r359212)
+++ stable/12/sys/fs/fuse/fuse_internal.c Sun Mar 22 15:16:59 2020 (r359213)
@@ -345,6 +345,7 @@ fuse_internal_fsync(struct vnode *vp,
* which file handle the caller is really referring to.
*/
LIST_FOREACH(fufh, &fvdat->handles, next) {
+ fdi.iosize = sizeof(*ffsi);
if (ffsi == NULL)
fdisp_make_vp(&fdi, op, vp, td, NULL);
else
Modified: stable/12/tests/sys/fs/fusefs/fsync.cc
==============================================================================
--- stable/12/tests/sys/fs/fusefs/fsync.cc Sun Mar 22 15:03:09 2020 (r359212)
+++ stable/12/tests/sys/fs/fusefs/fsync.cc Sun Mar 22 15:16:59 2020 (r359213)
@@ -52,7 +52,7 @@ using namespace testing;
class Fsync: public FuseTest {
public:
-void expect_fsync(uint64_t ino, uint32_t flags, int error)
+void expect_fsync(uint64_t ino, uint32_t flags, int error, int times = 1)
{
EXPECT_CALL(*m_mock, process(
ResultOf([=](auto in) {
@@ -67,12 +67,13 @@ void expect_fsync(uint64_t ino, uint32_t flags, int er
in.body.fsync.fsync_flags == flags);
}, Eq(true)),
_)
- ).WillOnce(Invoke(ReturnErrno(error)));
+ ).Times(times)
+ .WillRepeatedly(Invoke(ReturnErrno(error)));
}
-void expect_lookup(const char *relpath, uint64_t ino)
+void expect_lookup(const char *relpath, uint64_t ino, int times = 1)
{
- FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1);
+ FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, times);
}
void expect_write(uint64_t ino, uint64_t size, const void *contents)
@@ -257,4 +258,30 @@ TEST_F(Fsync, fsync)
ASSERT_EQ(0, fsync(fd)) << strerror(errno);
leak(fd);
+}
+
+/* If multiple FUSE file handles are active, we must fsync them all */
+TEST_F(Fsync, two_handles)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ const char *CONTENTS = "abcdefgh";
+ ssize_t bufsize = strlen(CONTENTS);
+ uint64_t ino = 42;
+ int fd1, fd2;
+
+ expect_lookup(RELPATH, ino, 2);
+ expect_open(ino, 0, 2);
+ expect_write(ino, bufsize, CONTENTS);
+ expect_fsync(ino, 0, 0, 2);
+
+ fd1 = open(FULLPATH, O_WRONLY);
+ ASSERT_LE(0, fd1) << strerror(errno);
+ fd2 = open(FULLPATH, O_RDONLY);
+ ASSERT_LE(0, fd2) << strerror(errno);
+ ASSERT_EQ(bufsize, write(fd1, CONTENTS, bufsize)) << strerror(errno);
+ ASSERT_EQ(0, fsync(fd1)) << strerror(errno);
+
+ leak(fd1);
+ leak(fd2);
}
More information about the svn-src-all
mailing list