* [PATCH 6.12.y 2/8] btrfs: move BTRFS_BYTES_TO_BLKS() into fs.h
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 ` Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 3/8] btrfs: move btrfs_alloc_write_mask() " Sasha Levin
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable
Cc: Filipe Manana, Qu Wenruo, Johannes Thumshirn, David Sterba,
Sasha Levin
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit a4545b74e2de98989c1d14bc48c52c2f9fa734b6 ]
Currently BTRFS_BYTES_TO_BLKS() is defined in ctree.h but it's not related
at all to the btree data structure, so move it into fs.h.
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 15f7c86215e8 ("btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ctree.h | 3 ---
fs/btrfs/fs.h | 2 ++
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2034d37108333..6906b4dd82a81 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -506,9 +506,6 @@ static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_fs_info *info)
return BTRFS_MAX_ITEM_SIZE(info) - sizeof(struct btrfs_dir_item);
}
-#define BTRFS_BYTES_TO_BLKS(fs_info, bytes) \
- ((bytes) >> (fs_info)->sectorsize_bits)
-
static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping)
{
return mapping_gfp_constraint(mapping, ~__GFP_FS);
diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h
index 63e1ffac5d9b5..3174b45a80b1d 100644
--- a/fs/btrfs/fs.h
+++ b/fs/btrfs/fs.h
@@ -959,6 +959,8 @@ static inline u64 btrfs_calc_metadata_size(const struct btrfs_fs_info *fs_info,
#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) ((BTRFS_LEAF_DATA_SIZE(r->fs_info) >> 4) - \
sizeof(struct btrfs_item))
+#define BTRFS_BYTES_TO_BLKS(fs_info, bytes) ((bytes) >> (fs_info)->sectorsize_bits)
+
static inline bool btrfs_is_zoned(const struct btrfs_fs_info *fs_info)
{
return IS_ENABLED(CONFIG_BLK_DEV_ZONED) && fs_info->zone_size > 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 6.12.y 3/8] btrfs: move btrfs_alloc_write_mask() into fs.h
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 ` Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 4/8] btrfs: expose per-inode stable writes flag Sasha Levin
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable
Cc: Filipe Manana, Qu Wenruo, Johannes Thumshirn, David Sterba,
Sasha Levin
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 378f25d3fc429ad001fa686f615df5c0f9cd47e1 ]
Currently btrfs_alloc_write_mask() is defined in ctree.h but it's not
related at all to the btree data structure, so move it into fs.h.
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 15f7c86215e8 ("btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ctree.h | 6 ------
fs/btrfs/fs.h | 6 ++++++
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 6906b4dd82a81..ced5ac090293b 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -7,7 +7,6 @@
#define BTRFS_CTREE_H
#include "linux/cleanup.h"
-#include <linux/pagemap.h>
#include <linux/spinlock.h>
#include <linux/rbtree.h>
#include <linux/mutex.h>
@@ -506,11 +505,6 @@ static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_fs_info *info)
return BTRFS_MAX_ITEM_SIZE(info) - sizeof(struct btrfs_dir_item);
}
-static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping)
-{
- return mapping_gfp_constraint(mapping, ~__GFP_FS);
-}
-
void btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, u64 start, u64 end);
int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
u64 num_bytes, u64 *actual_bytes);
diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h
index 3174b45a80b1d..90b104dd38c23 100644
--- a/fs/btrfs/fs.h
+++ b/fs/btrfs/fs.h
@@ -18,6 +18,7 @@
#include <linux/rwsem.h>
#include <linux/semaphore.h>
#include <linux/list.h>
+#include <linux/pagemap.h>
#include <linux/radix-tree.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
@@ -893,6 +894,11 @@ struct btrfs_fs_info {
#define inode_to_fs_info(_inode) (BTRFS_I(_Generic((_inode), \
struct inode *: (_inode)))->root->fs_info)
+static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping)
+{
+ return mapping_gfp_constraint(mapping, ~__GFP_FS);
+}
+
static inline u64 btrfs_get_fs_generation(const struct btrfs_fs_info *fs_info)
{
return READ_ONCE(fs_info->generation);
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 6.12.y 4/8] btrfs: expose per-inode stable writes flag
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
2026-09-06 19:30 ` [PATCH 6.12.y 5/8] btrfs: update include and forward declarations in headers Sasha Levin
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable; +Cc: Qu Wenruo, David Sterba, Sasha Levin
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
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 6.12.y 5/8] btrfs: update include and forward declarations in headers
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
` (2 preceding siblings ...)
2026-09-06 19:30 ` [PATCH 6.12.y 4/8] btrfs: expose per-inode stable writes flag Sasha Levin
@ 2026-09-06 19:30 ` Sasha Levin
2026-09-06 19:30 ` [PATCH 6.12.y 6/8] btrfs: parameter constification in ioctl.c Sasha Levin
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable; +Cc: David Sterba, Sasha Levin
From: David Sterba <dsterba@suse.com>
[ Upstream commit 6149c82bdaff63203e58a4910d9245468d281f39 ]
Pass over all header files and add missing forward declarations,
includes or fix include types.
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 15f7c86215e8 ("btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/accessors.h | 1 +
fs/btrfs/acl.h | 2 ++
fs/btrfs/ctree.h | 2 +-
fs/btrfs/delayed-ref.h | 2 ++
fs/btrfs/dir-item.h | 1 +
fs/btrfs/direct-io.h | 2 ++
fs/btrfs/discard.h | 1 +
fs/btrfs/extent-tree.h | 1 -
fs/btrfs/file-item.h | 2 ++
fs/btrfs/file.h | 2 ++
fs/btrfs/fs.c | 1 -
fs/btrfs/ioctl.h | 2 ++
fs/btrfs/locking.c | 1 -
fs/btrfs/ordered-data.h | 1 +
fs/btrfs/print-tree.h | 2 ++
fs/btrfs/props.h | 1 +
fs/btrfs/qgroup.h | 3 +++
fs/btrfs/raid-stripe-tree.h | 1 +
fs/btrfs/send.c | 1 -
fs/btrfs/space-info.c | 2 +-
fs/btrfs/subpage.c | 1 -
fs/btrfs/sysfs.h | 1 +
fs/btrfs/volumes.h | 4 ++++
fs/btrfs/xattr.h | 2 ++
24 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h
index 7a7e0ef69973a..15ea6348800b0 100644
--- a/fs/btrfs/accessors.h
+++ b/fs/btrfs/accessors.h
@@ -12,6 +12,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <uapi/linux/btrfs_tree.h>
+#include "extent_io.h"
struct extent_buffer;
diff --git a/fs/btrfs/acl.h b/fs/btrfs/acl.h
index 48b9ddae4a46a..0458cd51ed489 100644
--- a/fs/btrfs/acl.h
+++ b/fs/btrfs/acl.h
@@ -3,6 +3,8 @@
#ifndef BTRFS_ACL_H
#define BTRFS_ACL_H
+#include <linux/types.h>
+
struct posix_acl;
struct inode;
struct btrfs_trans_handle;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ced5ac090293b..937f32e5ad72b 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -6,7 +6,7 @@
#ifndef BTRFS_CTREE_H
#define BTRFS_CTREE_H
-#include "linux/cleanup.h"
+#include <linux/cleanup.h>
#include <linux/spinlock.h>
#include <linux/rbtree.h>
#include <linux/mutex.h>
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index 352921e76c742..032c8e2c5be29 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -14,6 +14,8 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <uapi/linux/btrfs_tree.h>
+#include "fs.h"
+#include "messages.h"
struct btrfs_trans_handle;
struct btrfs_fs_info;
diff --git a/fs/btrfs/dir-item.h b/fs/btrfs/dir-item.h
index 5f6dfafc91f1f..518f947acc299 100644
--- a/fs/btrfs/dir-item.h
+++ b/fs/btrfs/dir-item.h
@@ -10,6 +10,7 @@ struct fscrypt_str;
struct btrfs_fs_info;
struct btrfs_key;
struct btrfs_path;
+struct btrfs_inode;
struct btrfs_root;
struct btrfs_trans_handle;
diff --git a/fs/btrfs/direct-io.h b/fs/btrfs/direct-io.h
index 3dc3ea926afe2..df5d45ee6de7a 100644
--- a/fs/btrfs/direct-io.h
+++ b/fs/btrfs/direct-io.h
@@ -5,6 +5,8 @@
#include <linux/types.h>
+struct kiocb;
+
int __init btrfs_init_dio(void);
void __cold btrfs_destroy_dio(void);
diff --git a/fs/btrfs/discard.h b/fs/btrfs/discard.h
index dddb0f9101ba9..2c5e85394092f 100644
--- a/fs/btrfs/discard.h
+++ b/fs/btrfs/discard.h
@@ -3,6 +3,7 @@
#ifndef BTRFS_DISCARD_H
#define BTRFS_DISCARD_H
+#include <linux/types.h>
#include <linux/sizes.h>
struct btrfs_fs_info;
diff --git a/fs/btrfs/extent-tree.h b/fs/btrfs/extent-tree.h
index 2ad51130c037e..82c054dbc3691 100644
--- a/fs/btrfs/extent-tree.h
+++ b/fs/btrfs/extent-tree.h
@@ -4,7 +4,6 @@
#define BTRFS_EXTENT_TREE_H
#include <linux/types.h>
-#include "misc.h"
#include "block-group.h"
#include "locking.h"
diff --git a/fs/btrfs/file-item.h b/fs/btrfs/file-item.h
index 0e13661a71f3b..6181a70ec3efb 100644
--- a/fs/btrfs/file-item.h
+++ b/fs/btrfs/file-item.h
@@ -3,8 +3,10 @@
#ifndef BTRFS_FILE_ITEM_H
#define BTRFS_FILE_ITEM_H
+#include <linux/blk_types.h>
#include <linux/list.h>
#include <uapi/linux/btrfs_tree.h>
+#include "ctree.h"
#include "accessors.h"
struct extent_map;
diff --git a/fs/btrfs/file.h b/fs/btrfs/file.h
index 912254e653cf9..c3a59b4d506c9 100644
--- a/fs/btrfs/file.h
+++ b/fs/btrfs/file.h
@@ -9,6 +9,8 @@ struct file;
struct extent_state;
struct kiocb;
struct iov_iter;
+struct inode;
+struct folio;
struct page;
struct btrfs_ioctl_encoded_io_args;
struct btrfs_drop_extents_args;
diff --git a/fs/btrfs/fs.c b/fs/btrfs/fs.c
index e2b2b0f4c770f..1993be818b2a5 100644
--- a/fs/btrfs/fs.c
+++ b/fs/btrfs/fs.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "messages.h"
-#include "ctree.h"
#include "fs.h"
#include "accessors.h"
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 0ea9f7beee336..389a9bf6fc1ed 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -9,6 +9,8 @@ struct file;
struct dentry;
struct mnt_idmap;
struct fileattr;
+struct inode;
+struct io_uring_cmd;
struct btrfs_fs_info;
struct btrfs_ioctl_balance_args;
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 6a0b7abb5bd9a..11ceb50a8527e 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -9,7 +9,6 @@
#include <linux/page-flags.h>
#include <asm/bug.h>
#include <trace/events/btrfs.h>
-#include "misc.h"
#include "ctree.h"
#include "extent_io.h"
#include "locking.h"
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index a1a9f8d46e10e..436a748da491a 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -17,6 +17,7 @@
struct inode;
struct page;
struct extent_state;
+struct btrfs_block_group;
struct btrfs_inode;
struct btrfs_root;
struct btrfs_fs_info;
diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h
index 8504bf1702c7a..d0e620bf5f5a6 100644
--- a/fs/btrfs/print-tree.h
+++ b/fs/btrfs/print-tree.h
@@ -6,6 +6,8 @@
#ifndef BTRFS_PRINT_TREE_H
#define BTRFS_PRINT_TREE_H
+#include <linux/types.h>
+
/* Buffer size to contain tree name and possibly additional data (offset) */
#define BTRFS_ROOT_NAME_BUF_LEN 48
diff --git a/fs/btrfs/props.h b/fs/btrfs/props.h
index 63546d0a9444f..86849d4e7938c 100644
--- a/fs/btrfs/props.h
+++ b/fs/btrfs/props.h
@@ -6,6 +6,7 @@
#ifndef BTRFS_PROPS_H
#define BTRFS_PROPS_H
+#include <linux/types.h>
#include <linux/compiler_types.h>
struct inode;
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index c229256d6fd51..c516bd60d05cc 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -22,6 +22,9 @@ struct btrfs_ioctl_quota_ctl_args;
struct btrfs_trans_handle;
struct btrfs_delayed_ref_root;
struct btrfs_inode;
+struct btrfs_transaction;
+struct btrfs_block_group;
+struct btrfs_qgroup_swapped_blocks;
/*
* Btrfs qgroup overview
diff --git a/fs/btrfs/raid-stripe-tree.h b/fs/btrfs/raid-stripe-tree.h
index 1ac1c21aac2f9..251137d067bf5 100644
--- a/fs/btrfs/raid-stripe-tree.h
+++ b/fs/btrfs/raid-stripe-tree.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <uapi/linux/btrfs_tree.h>
#include "fs.h"
+#include "accessors.h"
#define BTRFS_RST_SUPP_BLOCK_GROUP_MASK (BTRFS_BLOCK_GROUP_DUP | \
BTRFS_BLOCK_GROUP_RAID1_MASK | \
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 2fa577d4a232d..4db1ec30de3e1 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -17,7 +17,6 @@
#include <linux/compat.h>
#include <linux/crc32c.h>
#include <linux/fsverity.h>
-
#include "send.h"
#include "ctree.h"
#include "backref.h"
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
index 402eb3b54fb1e..662fdd91d9ebf 100644
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
-#include "linux/spinlock.h"
+#include <linux/spinlock.h>
#include <linux/minmax.h>
#include "misc.h"
#include "ctree.h"
diff --git a/fs/btrfs/subpage.c b/fs/btrfs/subpage.c
index 7e5ecc12b732a..9e4eb2c97b1c2 100644
--- a/fs/btrfs/subpage.c
+++ b/fs/btrfs/subpage.c
@@ -2,7 +2,6 @@
#include <linux/slab.h>
#include "messages.h"
-#include "ctree.h"
#include "subpage.h"
#include "btrfs_inode.h"
diff --git a/fs/btrfs/sysfs.h b/fs/btrfs/sysfs.h
index ec834a4af2e5d..613450e8985d1 100644
--- a/fs/btrfs/sysfs.h
+++ b/fs/btrfs/sysfs.h
@@ -7,6 +7,7 @@
#include <linux/compiler_types.h>
#include <linux/kobject.h>
+struct block_device;
struct btrfs_fs_info;
struct btrfs_device;
struct btrfs_fs_devices;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 4481575dd70f3..a2863d2583fb5 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -7,6 +7,7 @@
#define BTRFS_VOLUMES_H
#include <linux/blk_types.h>
+#include <linux/blkdev.h>
#include <linux/sizes.h>
#include <linux/atomic.h>
#include <linux/sort.h>
@@ -18,14 +19,17 @@
#include <linux/completion.h>
#include <linux/rbtree.h>
#include <uapi/linux/btrfs.h>
+#include <uapi/linux/btrfs_tree.h>
#include "messages.h"
#include "rcu-string.h"
+#include "extent-io-tree.h"
struct block_device;
struct bdev_handle;
struct btrfs_fs_info;
struct btrfs_block_group;
struct btrfs_trans_handle;
+struct btrfs_transaction;
struct btrfs_zoned_device_info;
#define BTRFS_MAX_DATA_CHUNK_SIZE (10ULL * SZ_1G)
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
index 8dc4cf49f6f06..0ce10e4ec8367 100644
--- a/fs/btrfs/xattr.h
+++ b/fs/btrfs/xattr.h
@@ -6,6 +6,8 @@
#ifndef BTRFS_XATTR_H
#define BTRFS_XATTR_H
+#include <linux/types.h>
+
struct dentry;
struct inode;
struct qstr;
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 6.12.y 6/8] btrfs: parameter constification in ioctl.c
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
` (3 preceding siblings ...)
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 ` 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
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable; +Cc: David Sterba, Sasha Levin
From: David Sterba <dsterba@suse.com>
[ Upstream commit 5e54f9420fc9b8096d0a4b579a84806a3ef0bf88 ]
Add const to function parameters that are not changed.
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 15f7c86215e8 ("btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 8997e65d32863..bbd7f0db6ae53 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -117,8 +117,8 @@ struct btrfs_ioctl_encoded_io_args_32 {
#endif
/* Mask out flags that are inappropriate for the given type of inode. */
-static unsigned int btrfs_mask_fsflags_for_type(struct inode *inode,
- unsigned int flags)
+static unsigned int btrfs_mask_fsflags_for_type(const struct inode *inode,
+ unsigned int flags)
{
if (S_ISDIR(inode->i_mode))
return flags;
@@ -132,7 +132,7 @@ static unsigned int btrfs_mask_fsflags_for_type(struct inode *inode,
* Export internal inode flags to the format expected by the FS_IOC_GETFLAGS
* ioctl.
*/
-static unsigned int btrfs_inode_flags_to_fsflags(struct btrfs_inode *binode)
+static unsigned int btrfs_inode_flags_to_fsflags(const struct btrfs_inode *binode)
{
unsigned int iflags = 0;
u32 flags = binode->flags;
@@ -218,7 +218,7 @@ static int check_fsflags(unsigned int old_flags, unsigned int flags)
return 0;
}
-static int check_fsflags_compatible(struct btrfs_fs_info *fs_info,
+static int check_fsflags_compatible(const struct btrfs_fs_info *fs_info,
unsigned int flags)
{
if (btrfs_is_zoned(fs_info) && (flags & FS_NOCOW_FL))
@@ -247,7 +247,7 @@ static int btrfs_check_ioctl_vol_args2_subvol_name(const struct btrfs_ioctl_vol_
*/
int btrfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
{
- struct btrfs_inode *binode = BTRFS_I(d_inode(dentry));
+ const struct btrfs_inode *binode = BTRFS_I(d_inode(dentry));
fileattr_fill_flags(fa, btrfs_inode_flags_to_fsflags(binode));
return 0;
@@ -485,7 +485,7 @@ void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
}
}
-static int btrfs_ioctl_getversion(struct inode *inode, int __user *arg)
+static int btrfs_ioctl_getversion(const struct inode *inode, int __user *arg)
{
return put_user(inode->i_generation, arg);
}
@@ -557,7 +557,7 @@ static noinline int btrfs_ioctl_fitrim(struct btrfs_fs_info *fs_info,
* Calculate the number of transaction items to reserve for creating a subvolume
* or snapshot, not including the inode, directory entries, or parent directory.
*/
-static unsigned int create_subvol_num_items(struct btrfs_qgroup_inherit *inherit)
+static unsigned int create_subvol_num_items(const struct btrfs_qgroup_inherit *inherit)
{
/*
* 1 to add root block
@@ -967,7 +967,7 @@ static int btrfs_may_delete(struct mnt_idmap *idmap,
/* copy of may_create in fs/namei.c() */
static inline int btrfs_may_create(struct mnt_idmap *idmap,
- struct inode *dir, struct dentry *child)
+ struct inode *dir, const struct dentry *child)
{
if (d_really_is_positive(child))
return -EEXIST;
@@ -1539,8 +1539,8 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
return ret;
}
-static noinline int key_in_sk(struct btrfs_key *key,
- struct btrfs_ioctl_search_key *sk)
+static noinline int key_in_sk(const struct btrfs_key *key,
+ const struct btrfs_ioctl_search_key *sk)
{
struct btrfs_key test;
int ret;
@@ -1565,7 +1565,7 @@ static noinline int key_in_sk(struct btrfs_key *key,
static noinline int copy_to_sk(struct btrfs_path *path,
struct btrfs_key *key,
- struct btrfs_ioctl_search_key *sk,
+ const struct btrfs_ioctl_search_key *sk,
u64 *buf_size,
char __user *ubuf,
unsigned long *sk_offset,
@@ -2844,7 +2844,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
return ret;
}
-static long btrfs_ioctl_fs_info(struct btrfs_fs_info *fs_info,
+static long btrfs_ioctl_fs_info(const struct btrfs_fs_info *fs_info,
void __user *arg)
{
struct btrfs_ioctl_fs_info_args *fi_args;
@@ -2898,7 +2898,7 @@ static long btrfs_ioctl_fs_info(struct btrfs_fs_info *fs_info,
return ret;
}
-static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
+static long btrfs_ioctl_dev_info(const struct btrfs_fs_info *fs_info,
void __user *arg)
{
BTRFS_DEV_LOOKUP_ARGS(args);
@@ -4356,7 +4356,7 @@ static int btrfs_ioctl_get_features(struct btrfs_fs_info *fs_info,
return 0;
}
-static int check_feature_bits(struct btrfs_fs_info *fs_info,
+static int check_feature_bits(const struct btrfs_fs_info *fs_info,
enum btrfs_feature_set set,
u64 change_mask, u64 flags, u64 supported_flags,
u64 safe_set, u64 safe_clear)
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 6.12.y 7/8] btrfs: pass struct btrfs_inode to btrfs_sync_inode_flags_to_i_flags()
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
` (4 preceding siblings ...)
2026-09-06 19:30 ` [PATCH 6.12.y 6/8] btrfs: parameter constification in ioctl.c Sasha Levin
@ 2026-09-06 19:30 ` 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
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable; +Cc: David Sterba, Sasha Levin
From: David Sterba <dsterba@suse.com>
[ Upstream commit 4f27a693940bcf313d17792ac4ec13a83f71cf25 ]
Pass a struct btrfs_inode to btrfs_sync_inode_flags_to_i_flags() as it's
an internal interface.
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 15f7c86215e8 ("btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/inode.c | 4 ++--
fs/btrfs/ioctl.c | 19 +++++++++----------
fs/btrfs/ioctl.h | 4 ++--
fs/btrfs/verity.c | 4 ++--
4 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 9f8b6a8a36928..3d0dd228c6dbd 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3972,7 +3972,7 @@ static int btrfs_read_locked_inode(struct inode *inode,
break;
}
- btrfs_sync_inode_flags_to_i_flags(inode);
+ btrfs_sync_inode_flags_to_i_flags(BTRFS_I(inode));
return 0;
}
@@ -6209,7 +6209,7 @@ static void btrfs_inherit_iflags(struct btrfs_inode *inode, struct btrfs_inode *
inode->flags |= BTRFS_INODE_NODATASUM;
}
- btrfs_sync_inode_flags_to_i_flags(&inode->vfs_inode);
+ btrfs_sync_inode_flags_to_i_flags(inode);
}
int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index bbd7f0db6ae53..8f87f13cf2500 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -166,25 +166,24 @@ static unsigned int btrfs_inode_flags_to_fsflags(const struct btrfs_inode *binod
/*
* Update inode->i_flags based on the btrfs internal flags.
*/
-void btrfs_sync_inode_flags_to_i_flags(struct inode *inode)
+void btrfs_sync_inode_flags_to_i_flags(struct btrfs_inode *inode)
{
- struct btrfs_inode *binode = BTRFS_I(inode);
unsigned int new_fl = 0;
- if (binode->flags & BTRFS_INODE_SYNC)
+ if (inode->flags & BTRFS_INODE_SYNC)
new_fl |= S_SYNC;
- if (binode->flags & BTRFS_INODE_IMMUTABLE)
+ if (inode->flags & BTRFS_INODE_IMMUTABLE)
new_fl |= S_IMMUTABLE;
- if (binode->flags & BTRFS_INODE_APPEND)
+ if (inode->flags & BTRFS_INODE_APPEND)
new_fl |= S_APPEND;
- if (binode->flags & BTRFS_INODE_NOATIME)
+ if (inode->flags & BTRFS_INODE_NOATIME)
new_fl |= S_NOATIME;
- if (binode->flags & BTRFS_INODE_DIRSYNC)
+ if (inode->flags & BTRFS_INODE_DIRSYNC)
new_fl |= S_DIRSYNC;
- if (binode->ro_flags & BTRFS_INODE_RO_VERITY)
+ if (inode->ro_flags & BTRFS_INODE_RO_VERITY)
new_fl |= S_VERITY;
- set_mask_bits(&inode->i_flags,
+ set_mask_bits(&inode->vfs_inode.i_flags,
S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC |
S_VERITY, new_fl);
}
@@ -395,7 +394,7 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
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);
+ btrfs_sync_inode_flags_to_i_flags(inode);
inode_inc_iversion(&inode->vfs_inode);
inode_set_ctime_current(&inode->vfs_inode);
ret = btrfs_update_inode(trans, inode);
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 389a9bf6fc1ed..d4e35fae1a25d 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -9,8 +9,8 @@ struct file;
struct dentry;
struct mnt_idmap;
struct fileattr;
-struct inode;
struct io_uring_cmd;
+struct btrfs_inode;
struct btrfs_fs_info;
struct btrfs_ioctl_balance_args;
@@ -20,7 +20,7 @@ int btrfs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
int btrfs_fileattr_set(struct mnt_idmap *idmap,
struct dentry *dentry, struct fileattr *fa);
int btrfs_ioctl_get_supported_features(void __user *arg);
-void btrfs_sync_inode_flags_to_i_flags(struct inode *inode);
+void btrfs_sync_inode_flags_to_i_flags(struct btrfs_inode *inode);
void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
struct btrfs_ioctl_balance_args *bargs);
diff --git a/fs/btrfs/verity.c b/fs/btrfs/verity.c
index e97ad824ae16d..b7a96a005487e 100644
--- a/fs/btrfs/verity.c
+++ b/fs/btrfs/verity.c
@@ -485,7 +485,7 @@ static int rollback_verity(struct btrfs_inode *inode)
goto out;
}
inode->ro_flags &= ~BTRFS_INODE_RO_VERITY;
- btrfs_sync_inode_flags_to_i_flags(&inode->vfs_inode);
+ btrfs_sync_inode_flags_to_i_flags(inode);
ret = btrfs_update_inode(trans, inode);
if (ret) {
btrfs_abort_transaction(trans, ret);
@@ -552,7 +552,7 @@ static int finish_verity(struct btrfs_inode *inode, const void *desc,
goto out;
}
inode->ro_flags |= BTRFS_INODE_RO_VERITY;
- btrfs_sync_inode_flags_to_i_flags(&inode->vfs_inode);
+ btrfs_sync_inode_flags_to_i_flags(inode);
ret = btrfs_update_inode(trans, inode);
if (ret)
goto end_trans;
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 6.12.y 8/8] btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag
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
` (5 preceding siblings ...)
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 ` Sasha Levin
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-09-06 19:30 UTC (permalink / raw)
To: stable; +Cc: Qu Wenruo, Filipe Manana, David Sterba, Sasha Levin
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit 15f7c86215e8d5f14b24127fa88af6c79363d50e ]
[TEST FAILURE]
The test case generic/628 will fail if MOUNT_OPTIONS is set to
"-o nodatasum":
FSTYP -- btrfs
PLATFORM -- Linux/x86_64 btrfs-vm 7.1.0-rc4-custom+ #383 SMP PREEMPT_DYNAMIC Sat May 30 07:35:42 ACST 2026
MKFS_OPTIONS -- -O bgt -K /dev/mapper/test-scratch1
MOUNT_OPTIONS -- -o nodatasum /dev/mapper/test-scratch1 /mnt/scratch
generic/628 1s ... - output mismatch (see /home/adam/xfstests/results//generic/628.out.bad)
--- tests/generic/628.out 2022-05-11 11:25:30.816666664 +0930
+++ /home/adam/xfstests/results//generic/628.out.bad 2026-06-08 18:56:49.878542927 +0930
@@ -8,8 +8,9 @@
310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/d
test reflink flag not set iflag
+XFS_IOC_CLONE: Invalid argument
310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
-310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/b
+d41d8cd98f00b204e9800998ecf8427e SCRATCH_MNT/b
...
[CAUSE]
The direct cause is that after "chattr +S", the btrfs inode will lose its
NODATASUM flag inherited from the mount option. E.g.:
# mkfs.btrfs -f $dev
# mount $dev $mnt -o nodatasum
# touch $mnt/foobar
# sync
# btrfs ins dump-tree -t 5 $dev | grep "(257 INODE_ITEM 0) itemoff" -A 3
item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160
generation 9 transid 9 size 0 nbytes 0
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 1 flags 0x1(NODATASUM)
^^^^^^^^^ Proper NODATASUM flag
# chattr +S $mnt/foobar
# sync
# btrfs ins dump-tree -t 5 $dev | grep "(257 INODE_ITEM 0) itemoff" -A 3
item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160
generation 9 transid 10 size 0 nbytes 0
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 2 flags 0x20(SYNC)
^^^^ Only the new SYNC flag
This makes the inode drop the old NODATASUM flag, while the new reflink
destination will still inherit the NODATASUM flag. The mismatching
NODATASUM flags will cause the reflink to fail.
The root cause is that, inside btrfs_fileattr_set() if no FS_NOCOW_FL is
set, we remove both NODATASUM and NODATACOW flag.
However we should not touch NODATASUM flag, as data COW doesn't require
checksum. Only NODATACOW implies NODATASUM, but DATACOW doesn't imply
DATASUM.
The deeper problems are:
- Fileattr API is too binary
It either clears or sets a flag, there is no "do not change" option.
So that why "chattr +S" implies "chattr -C", and is forcing us to
change NODATACOW along with NODATASUM flag.
- No way to change NODATASUM through fileattr API
In fact NODATASUM can only be modified through mount option.
The deeper problems are much harder to attack.
[FIX]
Remove NODATACOW flag when FS_NOCOW_FL is not set, but only remove
NODATASUM if "nodatasum" mount option is not set.
This allows the existing "chattr +C" then "chattr -C" to remove
both NODATACOW and NODATASUM flags on a default mount.
But for a mount with "nodatasum" option, the NODATASUM inode flag will
persist through either "chattr +C" and "chattr -C".
Fixes: 7e97b8daf634 ("btrfs: allow setting NOCOW for a zero sized file via ioctl")
Cc: stable@vger.kernel.org
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 8f87f13cf2500..bff52a6e475a6 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -329,14 +329,21 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
inode_flags |= BTRFS_INODE_NODATACOW;
}
} else {
- /*
- * Revert back under same assumptions as above
- */
- if (S_ISREG(inode->vfs_inode.i_mode)) {
- if (inode->vfs_inode.i_size == 0)
- inode_flags &= ~(BTRFS_INODE_NODATACOW |
- BTRFS_INODE_NODATASUM);
- } else {
+ /* We can only change NODATACOW for zero-sized regular file. */
+ if (S_ISREG(inode->vfs_inode.i_mode) && (inode->vfs_inode.i_size == 0)) {
+ inode_flags &= ~BTRFS_INODE_NODATACOW;
+ /*
+ * There is currently no way to change NODATASUM flag
+ * through fileattr API. If we unconditionally keep the
+ * current NODATASUM flag, chattr +C then chattr -C will
+ * keep the NODATASUM flag, and no way to remove that
+ * flag.
+ *
+ * So respect the current mount option for NODATASUM flag.
+ */
+ if (!btrfs_test_opt(fs_info, NODATASUM))
+ inode_flags &= ~BTRFS_INODE_NODATASUM;
+ } else if (!S_ISREG(inode->vfs_inode.i_mode)) {
inode_flags &= ~BTRFS_INODE_NODATACOW;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread