From: "Iván Ezequiel Rodriguez" <ivanrwcm25@gmail.com>
To: David Howells <dhowells@redhat.com>,
Paulo Alcantara <pc@manguebit.org>,
netfs@lists.linux.dev
Cc: Shyam Prasad N <sprasad@microsoft.com>,
Steve French <stfrench@microsoft.com>,
linux-fsdevel@vger.kernel.org, linux-cifs@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH netfs v1 2/2] netfs: add KUnit coverage for reissue prepare_write errno
Date: Wed, 28 Oct 2026 15:12:29 -0300 [thread overview]
Message-ID: <20261028181229.1408342-3-ivanrwcm25@gmail.com> (raw)
In-Reply-To: <20261028181229.1408342-1-ivanrwcm25@gmail.com>
Stub netfs_write_subrequest_terminated() and call netfs_reissue_write()
with FAILED + -EIO. Unpatched trees terminate with 0; patched keep -EIO.
./tools/testing/kunit/kunit.py run --kunitconfig=fs/netfs/.kunitconfig \
netfs_reissue_write*
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
---
fs/netfs/.kunitconfig | 3 ++
fs/netfs/Kconfig | 9 +++++
fs/netfs/Makefile | 2 +
fs/netfs/write_collect.c | 4 ++
fs/netfs/write_reissue_kunit.c | 73 ++++++++++++++++++++++++++++++++++
5 files changed, 91 insertions(+)
create mode 100644 fs/netfs/.kunitconfig
create mode 100644 fs/netfs/write_reissue_kunit.c
diff --git a/fs/netfs/.kunitconfig b/fs/netfs/.kunitconfig
new file mode 100644
index 000000000000..c783d180ab8f
--- /dev/null
+++ b/fs/netfs/.kunitconfig
@@ -0,0 +1,3 @@
+CONFIG_KUNIT=y
+CONFIG_NETFS_SUPPORT=y
+CONFIG_NETFS_KUNIT_TESTS=y
diff --git a/fs/netfs/Kconfig b/fs/netfs/Kconfig
index d0e7b0971fa3..d796dbe4bd7c 100644
--- a/fs/netfs/Kconfig
+++ b/fs/netfs/Kconfig
@@ -33,6 +33,15 @@ config NETFS_DEBUG
management module. If this is set, the debugging output may be
enabled by setting bits in /sys/module/netfs/parameters/debug.
+config NETFS_KUNIT_TESTS
+ tristate "KUnit tests for netfs" if !KUNIT_ALL_TESTS
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ select NETFS_SUPPORT
+ help
+ This builds netfs KUnit tests (e.g. write reissue errno).
+ Say N unless developing netfs.
+
config FSCACHE
bool "General filesystem local caching manager"
depends on NETFS_SUPPORT
diff --git a/fs/netfs/Makefile b/fs/netfs/Makefile
index 54834cde7e56..fa1544b9a199 100644
--- a/fs/netfs/Makefile
+++ b/fs/netfs/Makefile
@@ -33,4 +33,6 @@ netfs-$(CONFIG_FSCACHE) += fscache_proc.o
endif
netfs-$(CONFIG_FSCACHE_STATS) += fscache_stats.o
+netfs-$(CONFIG_NETFS_KUNIT_TESTS) += write_reissue_kunit.o
+
obj-$(CONFIG_NETFS_SUPPORT) += netfs.o
diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c
index 6e8ea534230d..f3236fe494bf 100644
--- a/fs/netfs/write_collect.c
+++ b/fs/netfs/write_collect.c
@@ -11,6 +11,7 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
+#include <kunit/static_stub.h>
#include "internal.h"
/* Notes made in the collector */
@@ -529,6 +530,9 @@ void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error)
struct netfs_io_subrequest *subreq = _op;
struct netfs_io_request *wreq = subreq->rreq;
+ KUNIT_STATIC_STUB_REDIRECT(netfs_write_subrequest_terminated,
+ _op, transferred_or_error);
+
_enter("%x[%x] %zd", wreq->debug_id, subreq->debug_index, transferred_or_error);
switch (subreq->source) {
diff --git a/fs/netfs/write_reissue_kunit.c b/fs/netfs/write_reissue_kunit.c
new file mode 100644
index 000000000000..fca5f7dd9265
--- /dev/null
+++ b/fs/netfs/write_reissue_kunit.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * netfs_reissue_write must not clear prepare_write() errno.
+ */
+#include <kunit/test.h>
+#include <kunit/static_stub.h>
+#include <linux/uio.h>
+#include "internal.h"
+
+struct term_capture {
+ ssize_t transferred_or_error;
+ bool called;
+};
+
+static void capture_terminated(void *_op, ssize_t transferred_or_error)
+{
+ struct netfs_io_subrequest *subreq = _op;
+ struct term_capture *cap = kunit_get_current_test()->priv;
+
+ cap->called = true;
+ cap->transferred_or_error = transferred_or_error;
+ /* Mirror production: leave subreq->error as prepare_write set it. */
+ (void)subreq;
+}
+
+/*
+ * prepare_write_failed() sets FAILED + errno, then write_retry still calls
+ * reissue_write(). Before the fix, reissue wiped error to 0 so terminated
+ * reported success and mapping_set_error(0) was a no-op.
+ */
+static void reissue_preserves_prep_error(struct kunit *test)
+{
+ struct term_capture cap = {};
+ struct netfs_io_request wreq = {};
+ struct netfs_io_stream stream = {
+ .source = NETFS_UPLOAD_TO_SERVER,
+ };
+ struct netfs_io_subrequest subreq = {
+ .rreq = &wreq,
+ .len = 1,
+ .transferred = 0,
+ .error = -EIO,
+ .source = NETFS_UPLOAD_TO_SERVER,
+ };
+ char buf[1] = { 0 };
+ struct kvec kvec = { .iov_base = buf, .iov_len = 1 };
+ struct iov_iter source;
+
+ __set_bit(NETFS_SREQ_FAILED, &subreq.flags);
+ iov_iter_kvec(&source, ITER_SOURCE, &kvec, 1, 1);
+
+ test->priv = ∩
+ kunit_activate_static_stub(test, netfs_write_subrequest_terminated,
+ capture_terminated);
+
+ netfs_reissue_write(&stream, &subreq, &source);
+
+ KUNIT_EXPECT_TRUE(test, cap.called);
+ KUNIT_EXPECT_EQ(test, cap.transferred_or_error, -EIO);
+ KUNIT_EXPECT_EQ(test, subreq.error, -EIO);
+}
+
+static struct kunit_case netfs_reissue_test_cases[] = {
+ KUNIT_CASE(reissue_preserves_prep_error),
+ {}
+};
+
+static struct kunit_suite netfs_reissue_test_suite = {
+ .name = "netfs_reissue_write",
+ .test_cases = netfs_reissue_test_cases,
+};
+
+kunit_test_suite(netfs_reissue_test_suite);
--
2.43.0
next prev parent reply other threads:[~2026-10-28 18:12 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 18:12 [PATCH netfs v1 0/2] preserve prepare_write errno across write reissue Iván Ezequiel Rodriguez
2026-10-28 18:12 ` [PATCH netfs v1 1/2] netfs: preserve prepare_write errno on reissue Iván Ezequiel Rodriguez
2026-10-28 18:12 ` Iván Ezequiel Rodriguez [this message]
2026-10-29 10:19 ` [PATCH netfs v1 2/2] netfs: add KUnit coverage for reissue prepare_write errno kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028181229.1408342-3-ivanrwcm25@gmail.com \
--to=ivanrwcm25@gmail.com \
--cc=dhowells@redhat.com \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netfs@lists.linux.dev \
--cc=pc@manguebit.org \
--cc=sprasad@microsoft.com \
--cc=stfrench@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox