From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Qu Wenruo <wqu@suse.com>, David Sterba <dsterba@suse.com>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.12.y 4/8] btrfs: expose per-inode stable writes flag
Date: Sun, 6 Sep 2026 15:30:44 -0400 [thread overview]
Message-ID: <20260906193048.1791749-4-sashal@kernel.org> (raw)
In-Reply-To: <20260906193048.1791749-1-sashal@kernel.org>
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit ecde48a1a6b3256bd49db8780bf37556b157783c ]
The address space flag AS_STABLE_WRITES determine if FGP_STABLE for will
wait for the folio to finish its writeback.
For btrfs, due to the default data checksum behavior, if we modify the
folio while it's still under writeback, it will cause data checksum
mismatch. Thus for quite some call sites we manually call
folio_wait_writeback() to prevent such problem from happening.
Currently there is only one call site inside btrfs really utilizing
FGP_STABLE, and in that case we also manually call folio_wait_writeback()
to do the waiting.
But it's better to properly expose the stable writes flag to a per-inode
basis, to allow call sites to fully benefit from FGP_STABLE flag.
E.g. for inodes with NODATASUM allowing beginning dirtying the page
without waiting for writeback.
This involves:
- Update the mapping's stable write flag when setting/clearing NODATASUM
inode flag using ioctl
This only works for empty files, so it should be fine.
- Update the mapping's stable write flag when reading an inode from disk
- Remove the explicit folio_wait_writeback() for FGP_BEGINWRITE call
site
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
[ sashal: Reduced backport -- upstream ecde48a1a6b32 touches 4 file(s), this
backport carries 3. Not backported here:
fs/btrfs/btrfs_inode.h
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: 15f7c86215e8 ("btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/file.c | 3 +--
fs/btrfs/inode.c | 8 ++++++++
fs/btrfs/ioctl.c | 4 ++++
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index fe60f2d7e8aec..8701f94002571 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -884,7 +884,7 @@ static int prepare_uptodate_page(struct inode *inode,
static fgf_t get_prepare_fgp_flags(bool nowait)
{
- fgf_t fgp_flags = FGP_LOCK | FGP_ACCESSED | FGP_CREAT;
+ fgf_t fgp_flags = FGP_LOCK | FGP_ACCESSED | FGP_CREAT | FGP_STABLE;
if (nowait)
fgp_flags |= FGP_NOWAIT;
@@ -954,7 +954,6 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
faili = i - 1;
goto fail;
}
- wait_on_page_writeback(pages[i]);
}
return 0;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ab7f19ca21457..9f8b6a8a36928 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3851,6 +3851,10 @@ static int btrfs_read_locked_inode(struct inode *inode,
btrfs_inode_split_flags(btrfs_inode_flags(leaf, inode_item),
&BTRFS_I(inode)->flags, &BTRFS_I(inode)->ro_flags);
+ if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)
+ mapping_clear_stable_writes(inode->i_mapping);
+ else
+ mapping_set_stable_writes(inode->i_mapping);
cache_index:
/*
@@ -6310,6 +6314,10 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
if (btrfs_test_opt(fs_info, NODATACOW))
BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW |
BTRFS_INODE_NODATASUM;
+ if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)
+ mapping_clear_stable_writes(inode->i_mapping);
+ else
+ mapping_set_stable_writes(inode->i_mapping);
}
ret = btrfs_insert_inode_locked(inode);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index df288213f91be..8997e65d32863 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -391,6 +391,10 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
update_flags:
inode->flags = inode_flags;
+ if (inode->flags & BTRFS_INODE_NODATASUM)
+ mapping_clear_stable_writes(inode->vfs_inode.i_mapping);
+ else
+ mapping_set_stable_writes(inode->vfs_inode.i_mapping);
btrfs_sync_inode_flags_to_i_flags(&inode->vfs_inode);
inode_inc_iversion(&inode->vfs_inode);
inode_set_ctime_current(&inode->vfs_inode);
--
2.53.0
next prev parent reply other threads:[~2026-09-06 19:30 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 13:24 FAILED: patch "[PATCH] btrfs: do not overwrite NODATASUM flag when removing" failed to apply to 6.12-stable tree gregkh
2026-09-06 19:30 ` [PATCH 6.12.y 1/8] btrfs: move btrfs_is_empty_uuid() from ioctl.c into fs.c Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 2/8] btrfs: move BTRFS_BYTES_TO_BLKS() into fs.h Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 3/8] btrfs: move btrfs_alloc_write_mask() " Sasha Levin
2026-09-06 19:30 ` Sasha Levin [this message]
2026-09-06 19:30 ` [PATCH 6.12.y 5/8] btrfs: update include and forward declarations in headers Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 6/8] btrfs: parameter constification in ioctl.c Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 7/8] btrfs: pass struct btrfs_inode to btrfs_sync_inode_flags_to_i_flags() Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 8/8] btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag Sasha Levin
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=20260906193048.1791749-4-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=dsterba@suse.com \
--cc=stable@vger.kernel.org \
--cc=wqu@suse.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.