git: d86025c1d49c - main - fusefs: Fix intermittency in the BadServer.ShortWrite test case

From: Alan Somers <asomers_at_FreeBSD.org>
Date: Mon, 27 Oct 2025 19:11:43 UTC
The branch main has been updated by asomers:

URL: https://cgit.FreeBSD.org/src/commit/?id=d86025c1d49c84c4dc8c3635c83c078ad56e5a53

commit d86025c1d49c84c4dc8c3635c83c078ad56e5a53
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2025-10-25 22:38:30 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2025-10-27 19:11:19 +0000

    fusefs: Fix intermittency in the BadServer.ShortWrite test case
    
    We were using the m_quit bit for two similar but distinct uses:
    
    * To instruct the server to quit
    * To cope with the kernel forcibly unmounting the fs
    
    Fix the intermittent test failure by adding a separate bit,
    m_expect_unmount, to handle cases like the latter.
    
    Reported by:    Siva Mahadevan <me@svmhdvn.name>
    MFC after:      1 week
    Revied by:      Siva Mahadevan <me@svmhdvn.name>
    Differential Revision: https://reviews.freebsd.org/D53357
---
 tests/sys/fs/fusefs/bad_server.cc | 8 ++++----
 tests/sys/fs/fusefs/mockfs.cc     | 5 +++--
 tests/sys/fs/fusefs/mockfs.hh     | 3 +++
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/tests/sys/fs/fusefs/bad_server.cc b/tests/sys/fs/fusefs/bad_server.cc
index c3d195735446..825523cac2bb 100644
--- a/tests/sys/fs/fusefs/bad_server.cc
+++ b/tests/sys/fs/fusefs/bad_server.cc
@@ -64,12 +64,12 @@ TEST_F(BadServer, ShortWrite)
 	out.header.error = 0;
 	out.header.unique = 0;			// Asynchronous notification
 	out.expected_errno = EINVAL;
-	m_mock->write_response(out);
 	/*
-	 * Tell the event loop to quit.  The kernel has already disconnected us
+	 * Tell the event loop to quit.  The kernel will disconnect us
 	 * because of the short write.
 	 */
-	m_mock->m_quit = true;
+	m_mock->m_expect_unmount = true;
+	m_mock->write_response(out);
 }
 
 /*
@@ -98,7 +98,7 @@ TEST_F(BadServer, ErrorWithPayload)
 		out.push_back(std::move(out1));
 
 		// The kernel may disconnect us for bad behavior, so don't try
-		// to read any more.
+		// to read or write any more.
 		m_mock->m_quit = true;
 	}));
 
diff --git a/tests/sys/fs/fusefs/mockfs.cc b/tests/sys/fs/fusefs/mockfs.cc
index 55c191716629..b6a32d9b60af 100644
--- a/tests/sys/fs/fusefs/mockfs.cc
+++ b/tests/sys/fs/fusefs/mockfs.cc
@@ -433,7 +433,8 @@ MockFS::MockFS(int max_read, int max_readahead, bool allow_other,
 	  m_child_pid(-1),
 	  m_maxwrite(MIN(max_write, max_max_write)),
 	  m_nready(-1),
-	  m_quit(false)
+	  m_quit(false),
+	  m_expect_unmount(false)
 {
 	struct sigaction sa;
 	struct iovec *iov = NULL;
@@ -979,7 +980,7 @@ void MockFS::read_request(mockfs_buf_in &in, ssize_t &res) {
 	}
 	res = read(m_fuse_fd, &in, sizeof(in));
 
-	if (res < 0 && !m_quit) {
+	if (res < 0 && errno != EBADF && !m_quit && !m_expect_unmount) {
 		m_quit = true;
 		FAIL() << "read: " << strerror(errno);
 	}
diff --git a/tests/sys/fs/fusefs/mockfs.hh b/tests/sys/fs/fusefs/mockfs.hh
index 4b0628d34dd7..f98a5337c9d1 100644
--- a/tests/sys/fs/fusefs/mockfs.hh
+++ b/tests/sys/fs/fusefs/mockfs.hh
@@ -360,6 +360,9 @@ class MockFS {
 	/* Tell the daemon to shut down ASAP */
 	bool m_quit;
 
+	/* Tell the daemon that the server might forcibly unmount us */
+	bool m_expect_unmount;
+
 	/* Create a new mockfs and mount it to a tempdir */
 	MockFS(int max_read, int max_readahead, bool allow_other,
 		bool default_permissions, bool push_symlinks_in, bool ro,