* FAILED: patch "[PATCH] iomap: don't lose a failed direct I/O bio's error when zeroing the tail" failed to apply to 6.18-stable tree
@ 2026-11-07 10:11 Sasha Levin
2026-11-10 20:07 ` [PATCH 6.18.y 1/2] iomap: use largest_zero_folio() in iomap_dio_zero() Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2026-11-07 10:11 UTC (permalink / raw)
To: parri.andrea, djwong, p.raghav, hch, brauner; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x a9fd24bcbe690ed4a5b8ea6a7516fa297fae9360
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '20261107051102-failed-6.18-a9fd24bcbe69@kernel.org' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From a9fd24bcbe690ed4a5b8ea6a7516fa297fae9360 Mon Sep 17 00:00:00 2001
From: Andrea Parri <parri.andrea@gmail.com>
Date: Mon, 28 Sep 2026 10:48:09 +0200
Subject: [PATCH] iomap: don't lose a failed direct I/O bio's error when
zeroing the tail
iomap_dio_bio_iter() falls through to the sub-block tail zeroing when
the data bio submission fails, so that the rest of the block is still
zeroed and stale data is not exposed. The zeroing result was assigned
to ret, which overwrote the submission error with the successful
zeroing result (zero) and the failed write was reported as success.
iomap_dio_zero() can only return an error from a can't-happen
WARN_ON_ONCE() (nr_vecs exceeding BIO_MAX_VECS, which the existing
comment there says "shall never be reached" for any in-tree
filesystem), so it isn't a real runtime failure worth reporting to
userspace, let alone one worth losing the actual submission error for.
Make iomap_dio_zero() return void and drop the error handling at both
call sites instead of threading the result through a separate
variable.
Fixes: 10553a91652d ("iomap: fix iomap_dio_zero() for fs bs > system page size")
Cc: stable@vger.kernel.org # v6.12
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Link: https://patch.msgid.link/0cbce1012f5333690be36a9adafb3e190fe2ca77.1790342457.git.parri.andrea@gmail.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
fs/iomap/direct-io.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index 0e8d7ddf4e511..b54540391cdec 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -304,7 +304,7 @@ u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend)
return vec_count;
}
-static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
+static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
loff_t pos, unsigned len)
{
struct inode *inode = file_inode(dio->iocb->ki_filp);
@@ -313,14 +313,14 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
int nr_vecs = max(1, i_blocksize(inode) / folio_size(zero_folio));
if (!len)
- return 0;
+ return;
/*
* This limit shall never be reached as most filesystems have a
* maximum blocksize of 64k.
*/
if (WARN_ON_ONCE(nr_vecs > BIO_MAX_VECS))
- return -EINVAL;
+ return;
bio = iomap_dio_alloc_bio(iter, dio, nr_vecs,
REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
@@ -336,8 +336,6 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
len -= io_len;
}
iomap_dio_submit_bio(iter, dio, bio, pos);
-
- return 0;
}
static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter,
@@ -541,10 +539,7 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
if (need_zeroout) {
/* zero out from the start of the block to the write offset */
pad = pos & (fs_block_size - 1);
-
- ret = iomap_dio_zero(iter, dio, pos - pad, pad);
- if (ret)
- goto out;
+ iomap_dio_zero(iter, dio, pos - pad, pad);
}
do {
@@ -582,8 +577,7 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
/* zero out from the end of the write to the end of the block */
pad = pos & (fs_block_size - 1);
if (pad)
- ret = iomap_dio_zero(iter, dio, pos,
- fs_block_size - pad);
+ iomap_dio_zero(iter, dio, pos, fs_block_size - pad);
}
out:
/* Undo iter limitation to current extent */
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 6.18.y 1/2] iomap: use largest_zero_folio() in iomap_dio_zero()
2026-11-07 10:11 FAILED: patch "[PATCH] iomap: don't lose a failed direct I/O bio's error when zeroing the tail" failed to apply to 6.18-stable tree Sasha Levin
@ 2026-11-10 20:07 ` Sasha Levin
2026-11-10 20:07 ` [PATCH 6.18.y 2/2] iomap: don't lose a failed direct I/O bio's error when zeroing the tail Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2026-11-10 20:07 UTC (permalink / raw)
To: stable; +Cc: Pankaj Raghav, Darrick J. Wong, Christian Brauner, Sasha Levin
From: Pankaj Raghav <p.raghav@samsung.com>
[ Upstream commit 10436adf9df60ae73390754b47a4bdebf728529f ]
iomap_dio_zero() uses a custom allocated memory of zeroes for padding
zeroes. This was a temporary solution until there was a way to request a
zero folio that was greater than the PAGE_SIZE.
Use largest_zero_folio() function instead of using the custom allocated
memory of zeroes. There is no guarantee from largest_zero_folio()
function that it will always return a PMD sized folio. Adapt the code so
that it can also work if largest_zero_folio() returns a ZERO_PAGE.
Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: a9fd24bcbe69 ("iomap: don't lose a failed direct I/O bio's error when zeroing the tail")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/direct-io.c | 38 +++++++++++++++-----------------------
1 file changed, 15 insertions(+), 23 deletions(-)
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index bb276321c9521..5a97614507530 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -24,13 +24,6 @@
#define IOMAP_DIO_WRITE (1U << 30)
#define IOMAP_DIO_DIRTY (1U << 31)
-/*
- * Used for sub block zeroing in iomap_dio_zero()
- */
-#define IOMAP_ZERO_PAGE_SIZE (SZ_64K)
-#define IOMAP_ZERO_PAGE_ORDER (get_order(IOMAP_ZERO_PAGE_SIZE))
-static struct page *zero_page;
-
struct iomap_dio {
struct kiocb *iocb;
const struct iomap_dio_ops *dops;
@@ -296,24 +289,35 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
{
struct inode *inode = file_inode(dio->iocb->ki_filp);
struct bio *bio;
+ struct folio *zero_folio = largest_zero_folio();
+ int nr_vecs = max(1, i_blocksize(inode) / folio_size(zero_folio));
if (!len)
return 0;
+
/*
- * Max block size supported is 64k
+ * This limit shall never be reached as most filesystems have a
+ * maximum blocksize of 64k.
*/
- if (WARN_ON_ONCE(len > IOMAP_ZERO_PAGE_SIZE))
+ if (WARN_ON_ONCE(nr_vecs > BIO_MAX_VECS))
return -EINVAL;
- bio = iomap_dio_alloc_bio(iter, dio, 1, REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
+ bio = iomap_dio_alloc_bio(iter, dio, nr_vecs,
+ REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
GFP_KERNEL);
bio->bi_iter.bi_sector = iomap_sector(&iter->iomap, pos);
bio->bi_private = dio;
bio->bi_end_io = iomap_dio_bio_end_io;
- __bio_add_page(bio, zero_page, len, 0);
+ while (len > 0) {
+ unsigned int io_len = min(len, folio_size(zero_folio));
+
+ bio_add_folio_nofail(bio, zero_folio, io_len, 0);
+ len -= io_len;
+ }
iomap_dio_submit_bio(iter, dio, bio, pos);
+
return 0;
}
@@ -841,15 +845,3 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
return iomap_dio_complete(dio);
}
EXPORT_SYMBOL_GPL(iomap_dio_rw);
-
-static int __init iomap_dio_init(void)
-{
- zero_page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
- IOMAP_ZERO_PAGE_ORDER);
-
- if (!zero_page)
- return -ENOMEM;
-
- return 0;
-}
-fs_initcall(iomap_dio_init);
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 6.18.y 2/2] iomap: don't lose a failed direct I/O bio's error when zeroing the tail
2026-11-10 20:07 ` [PATCH 6.18.y 1/2] iomap: use largest_zero_folio() in iomap_dio_zero() Sasha Levin
@ 2026-11-10 20:07 ` Sasha Levin
0 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-11-10 20:07 UTC (permalink / raw)
To: stable
Cc: Andrea Parri, Darrick J. Wong, Pankaj Raghav, Christoph Hellwig,
Christian Brauner (Amutable), Sasha Levin
From: Andrea Parri <parri.andrea@gmail.com>
[ Upstream commit a9fd24bcbe690ed4a5b8ea6a7516fa297fae9360 ]
iomap_dio_bio_iter() falls through to the sub-block tail zeroing when
the data bio submission fails, so that the rest of the block is still
zeroed and stale data is not exposed. The zeroing result was assigned
to ret, which overwrote the submission error with the successful
zeroing result (zero) and the failed write was reported as success.
iomap_dio_zero() can only return an error from a can't-happen
WARN_ON_ONCE() (nr_vecs exceeding BIO_MAX_VECS, which the existing
comment there says "shall never be reached" for any in-tree
filesystem), so it isn't a real runtime failure worth reporting to
userspace, let alone one worth losing the actual submission error for.
Make iomap_dio_zero() return void and drop the error handling at both
call sites instead of threading the result through a separate
variable.
Fixes: 10553a91652d ("iomap: fix iomap_dio_zero() for fs bs > system page size")
Cc: stable@vger.kernel.org # v6.12
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Link: https://patch.msgid.link/0cbce1012f5333690be36a9adafb3e190fe2ca77.1790342457.git.parri.andrea@gmail.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/direct-io.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index 5a97614507530..4301145674259 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -284,7 +284,7 @@ u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend)
return vec_count;
}
-static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
+static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
loff_t pos, unsigned len)
{
struct inode *inode = file_inode(dio->iocb->ki_filp);
@@ -293,14 +293,14 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
int nr_vecs = max(1, i_blocksize(inode) / folio_size(zero_folio));
if (!len)
- return 0;
+ return;
/*
* This limit shall never be reached as most filesystems have a
* maximum blocksize of 64k.
*/
if (WARN_ON_ONCE(nr_vecs > BIO_MAX_VECS))
- return -EINVAL;
+ return;
bio = iomap_dio_alloc_bio(iter, dio, nr_vecs,
REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
@@ -317,8 +317,6 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
len -= io_len;
}
iomap_dio_submit_bio(iter, dio, bio, pos);
-
- return 0;
}
/*
@@ -424,10 +422,7 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
if (need_zeroout) {
/* zero out from the start of the block to the write offset */
pad = pos & (fs_block_size - 1);
-
- ret = iomap_dio_zero(iter, dio, pos - pad, pad);
- if (ret)
- goto out;
+ iomap_dio_zero(iter, dio, pos - pad, pad);
}
nr_pages = bio_iov_vecs_to_alloc(dio->submit.iter, BIO_MAX_VECS);
@@ -509,8 +504,7 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
/* zero out from the end of the write to the end of the block */
pad = pos & (fs_block_size - 1);
if (pad)
- ret = iomap_dio_zero(iter, dio, pos,
- fs_block_size - pad);
+ iomap_dio_zero(iter, dio, pos, fs_block_size - pad);
}
out:
/* Undo iter limitation to current extent */
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-10 20:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-07 10:11 FAILED: patch "[PATCH] iomap: don't lose a failed direct I/O bio's error when zeroing the tail" failed to apply to 6.18-stable tree Sasha Levin
2026-11-10 20:07 ` [PATCH 6.18.y 1/2] iomap: use largest_zero_folio() in iomap_dio_zero() Sasha Levin
2026-11-10 20:07 ` [PATCH 6.18.y 2/2] iomap: don't lose a failed direct I/O bio's error when zeroing the tail Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox