From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev, Jan Kara <jack@suse.cz>,
Zhang Yi <yi.zhang@huawei.com>, Theodore Tso <tytso@mit.edu>
Subject: [PATCH 6.16 3/9] ext4: fix stale data if it bail out of the extents mapping loop
Date: Fri, 22 Aug 2025 14:37:03 +0200 [thread overview]
Message-ID: <20250822123516.911484923@linuxfoundation.org> (raw)
In-Reply-To: <20250822123516.780248736@linuxfoundation.org>
6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <yi.zhang@huawei.com>
commit ded2d726a3041fce8afd88005cbfe15cd4737702 upstream.
During the process of writing back folios, if
mpage_map_and_submit_extent() exits the extent mapping loop due to an
ENOSPC or ENOMEM error, it may result in stale data or filesystem
inconsistency in environments where the block size is smaller than the
folio size.
When mapping a discontinuous folio in mpage_map_and_submit_extent(),
some buffers may have already be mapped. If we exit the mapping loop
prematurely, the folio data within the mapped range will not be written
back, and the file's disk size will not be updated. Once the transaction
that includes this range of extents is committed, this can lead to stale
data or filesystem inconsistency.
Fix this by submitting the current processing partially mapped folio.
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20250707140814.542883-4-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ext4/inode.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2363,6 +2363,47 @@ static int mpage_map_one_extent(handle_t
}
/*
+ * This is used to submit mapped buffers in a single folio that is not fully
+ * mapped for various reasons, such as insufficient space or journal credits.
+ */
+static int mpage_submit_partial_folio(struct mpage_da_data *mpd)
+{
+ struct inode *inode = mpd->inode;
+ struct folio *folio;
+ loff_t pos;
+ int ret;
+
+ folio = filemap_get_folio(inode->i_mapping,
+ mpd->start_pos >> PAGE_SHIFT);
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
+ /*
+ * The mapped position should be within the current processing folio
+ * but must not be the folio start position.
+ */
+ pos = ((loff_t)mpd->map.m_lblk) << inode->i_blkbits;
+ if (WARN_ON_ONCE((folio_pos(folio) == pos) ||
+ !folio_contains(folio, pos >> PAGE_SHIFT)))
+ return -EINVAL;
+
+ ret = mpage_submit_folio(mpd, folio);
+ if (ret)
+ goto out;
+ /*
+ * Update start_pos to prevent this folio from being released in
+ * mpage_release_unused_pages(), it will be reset to the aligned folio
+ * pos when this folio is written again in the next round. Additionally,
+ * do not update wbc->nr_to_write here, as it will be updated once the
+ * entire folio has finished processing.
+ */
+ mpd->start_pos = pos;
+out:
+ folio_unlock(folio);
+ folio_put(folio);
+ return ret;
+}
+
+/*
* mpage_map_and_submit_extent - map extent starting at mpd->lblk of length
* mpd->len and submit pages underlying it for IO
*
@@ -2412,8 +2453,16 @@ static int mpage_map_and_submit_extent(h
*/
if ((err == -ENOMEM) ||
(err == -ENOSPC && ext4_count_free_clusters(sb))) {
- if (progress)
+ /*
+ * We may have already allocated extents for
+ * some bhs inside the folio, issue the
+ * corresponding data to prevent stale data.
+ */
+ if (progress) {
+ if (mpage_submit_partial_folio(mpd))
+ goto invalidate_dirty_pages;
goto update_disksize;
+ }
return err;
}
ext4_msg(sb, KERN_CRIT,
next prev parent reply other threads:[~2025-08-22 12:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-22 12:37 [PATCH 6.16 0/9] 6.16.3-rc1 review Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 1/9] ext4: process folios writeback in bytes Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 2/9] ext4: move the calculation of wbc->nr_to_write to mpage_folio_done() Greg Kroah-Hartman
2025-08-22 12:37 ` Greg Kroah-Hartman [this message]
2025-08-22 12:37 ` [PATCH 6.16 4/9] ext4: refactor the block allocation process of ext4_page_mkwrite() Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 5/9] ext4: restart handle if credits are insufficient during allocating blocks Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 6/9] ext4: enhance tracepoints during the folios writeback Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 7/9] ext4: correct the reserved credits for extent conversion Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 8/9] ext4: reserved credits for one extent during the folio writeback Greg Kroah-Hartman
2025-08-22 12:37 ` [PATCH 6.16 9/9] ext4: replace ext4_writepage_trans_blocks() Greg Kroah-Hartman
2025-08-22 13:42 ` [PATCH 6.16 0/9] 6.16.3-rc1 review Ronald Warsow
2025-08-22 21:00 ` Takeshi Ogasawara
2025-08-22 21:29 ` Florian Fainelli
2025-08-22 23:27 ` Peter Schneider
2025-08-23 8:32 ` Naresh Kamboju
2025-08-23 12:42 ` Brett A C Sheffield
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=20250822123516.911484923@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=jack@suse.cz \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.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