* [PATCH 1/7] btrfs: change unaligned root messages to error level in btrfs_validate_super()
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
@ 2026-02-04 15:51 ` fdmanana
2026-02-04 15:51 ` [PATCH 2/7] btrfs: mark all error and warning checks as unlikely " fdmanana
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:51 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
If the root nodes for the chunk root, tree root or log root are not sector
size aligned, we are logging a warning message but these are in fact
errors that makes the super block validation fail. So change the level of
the messages from warning to error.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 069f8017d425..a6011da279e3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2425,18 +2425,18 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
/* Root alignment check */
if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) {
- btrfs_warn(fs_info, "tree_root block unaligned: %llu",
- btrfs_super_root(sb));
+ btrfs_err(fs_info, "tree_root block unaligned: %llu",
+ btrfs_super_root(sb));
ret = -EINVAL;
}
if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) {
- btrfs_warn(fs_info, "chunk_root block unaligned: %llu",
+ btrfs_err(fs_info, "chunk_root block unaligned: %llu",
btrfs_super_chunk_root(sb));
ret = -EINVAL;
}
if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) {
- btrfs_warn(fs_info, "log_root block unaligned: %llu",
- btrfs_super_log_root(sb));
+ btrfs_err(fs_info, "log_root block unaligned: %llu",
+ btrfs_super_log_root(sb));
ret = -EINVAL;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 2/7] btrfs: mark all error and warning checks as unlikely in btrfs_validate_super()
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
2026-02-04 15:51 ` [PATCH 1/7] btrfs: change unaligned root messages to error level in btrfs_validate_super() fdmanana
@ 2026-02-04 15:51 ` fdmanana
2026-02-05 12:04 ` David Sterba
2026-02-04 15:52 ` [PATCH 3/7] btrfs: pass transaction handle to write_all_supers() fdmanana
` (6 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:51 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
When validating a super block, either when mounting or every time we write
a super block to disk, we do many checks for error and warnings and we
don't expect to hit any. So mark each one as unlikely to reflect that and
allow the compiler to potentially generate better code.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 78 +++++++++++++++++++++++-----------------------
1 file changed, 39 insertions(+), 39 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a6011da279e3..b9eb38072191 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2363,11 +2363,11 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
int ret = 0;
const bool ignore_flags = btrfs_test_opt(fs_info, IGNORESUPERFLAGS);
- if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
+ if (unlikely(btrfs_super_magic(sb) != BTRFS_MAGIC)) {
btrfs_err(fs_info, "no valid FS found");
ret = -EINVAL;
}
- if ((btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)) {
+ if (unlikely(btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)) {
if (!ignore_flags) {
btrfs_err(fs_info,
"unrecognized or unsupported super flag 0x%llx",
@@ -2379,17 +2379,17 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
}
}
- if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) {
+ if (unlikely(btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL)) {
btrfs_err(fs_info, "tree_root level too big: %d >= %d",
btrfs_super_root_level(sb), BTRFS_MAX_LEVEL);
ret = -EINVAL;
}
- if (btrfs_super_chunk_root_level(sb) >= BTRFS_MAX_LEVEL) {
+ if (unlikely(btrfs_super_chunk_root_level(sb) >= BTRFS_MAX_LEVEL)) {
btrfs_err(fs_info, "chunk_root level too big: %d >= %d",
btrfs_super_chunk_root_level(sb), BTRFS_MAX_LEVEL);
ret = -EINVAL;
}
- if (btrfs_super_log_root_level(sb) >= BTRFS_MAX_LEVEL) {
+ if (unlikely(btrfs_super_log_root_level(sb) >= BTRFS_MAX_LEVEL)) {
btrfs_err(fs_info, "log_root level too big: %d >= %d",
btrfs_super_log_root_level(sb), BTRFS_MAX_LEVEL);
ret = -EINVAL;
@@ -2399,65 +2399,65 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
* Check sectorsize and nodesize first, other check will need it.
* Check all possible sectorsize(4K, 8K, 16K, 32K, 64K) here.
*/
- if (!is_power_of_2(sectorsize) || sectorsize < BTRFS_MIN_BLOCKSIZE ||
- sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE) {
+ if (unlikely(!is_power_of_2(sectorsize) || sectorsize < BTRFS_MIN_BLOCKSIZE ||
+ sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE)) {
btrfs_err(fs_info, "invalid sectorsize %llu", sectorsize);
ret = -EINVAL;
}
- if (!btrfs_supported_blocksize(sectorsize)) {
+ if (unlikely(!btrfs_supported_blocksize(sectorsize))) {
btrfs_err(fs_info,
"sectorsize %llu not yet supported for page size %lu",
sectorsize, PAGE_SIZE);
ret = -EINVAL;
}
- if (!is_power_of_2(nodesize) || nodesize < sectorsize ||
- nodesize > BTRFS_MAX_METADATA_BLOCKSIZE) {
+ if (unlikely(!is_power_of_2(nodesize) || nodesize < sectorsize ||
+ nodesize > BTRFS_MAX_METADATA_BLOCKSIZE)) {
btrfs_err(fs_info, "invalid nodesize %llu", nodesize);
ret = -EINVAL;
}
- if (nodesize != le32_to_cpu(sb->__unused_leafsize)) {
+ if (unlikely(nodesize != le32_to_cpu(sb->__unused_leafsize))) {
btrfs_err(fs_info, "invalid leafsize %u, should be %llu",
le32_to_cpu(sb->__unused_leafsize), nodesize);
ret = -EINVAL;
}
/* Root alignment check */
- if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) {
+ if (unlikely(!IS_ALIGNED(btrfs_super_root(sb), sectorsize))) {
btrfs_err(fs_info, "tree_root block unaligned: %llu",
btrfs_super_root(sb));
ret = -EINVAL;
}
- if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) {
+ if (unlikely(!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize))) {
btrfs_err(fs_info, "chunk_root block unaligned: %llu",
btrfs_super_chunk_root(sb));
ret = -EINVAL;
}
- if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) {
+ if (unlikely(!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize))) {
btrfs_err(fs_info, "log_root block unaligned: %llu",
btrfs_super_log_root(sb));
ret = -EINVAL;
}
- if (!fs_info->fs_devices->temp_fsid &&
- memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) {
+ if (unlikely(!fs_info->fs_devices->temp_fsid &&
+ memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0)) {
btrfs_err(fs_info,
"superblock fsid doesn't match fsid of fs_devices: %pU != %pU",
sb->fsid, fs_info->fs_devices->fsid);
ret = -EINVAL;
}
- if (memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb),
- BTRFS_FSID_SIZE) != 0) {
+ if (unlikely(memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb),
+ BTRFS_FSID_SIZE) != 0)) {
btrfs_err(fs_info,
"superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU",
btrfs_sb_fsid_ptr(sb), fs_info->fs_devices->metadata_uuid);
ret = -EINVAL;
}
- if (memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid,
- BTRFS_FSID_SIZE) != 0) {
+ if (unlikely(memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid,
+ BTRFS_FSID_SIZE) != 0)) {
btrfs_err(fs_info,
"dev_item UUID does not match metadata fsid: %pU != %pU",
fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid);
@@ -2468,9 +2468,9 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
* Artificial requirement for block-group-tree to force newer features
* (free-space-tree, no-holes) so the test matrix is smaller.
*/
- if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
- (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
- !btrfs_fs_incompat(fs_info, NO_HOLES))) {
+ if (unlikely(btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
+ (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
+ !btrfs_fs_incompat(fs_info, NO_HOLES)))) {
btrfs_err(fs_info,
"block-group-tree feature requires free-space-tree and no-holes");
ret = -EINVAL;
@@ -2481,25 +2481,25 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
* Reduce test matrix for remap tree by requiring block-group-tree
* and no-holes. Free-space-tree is a hard requirement.
*/
- if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
- !btrfs_fs_incompat(fs_info, NO_HOLES) ||
- !btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE)) {
+ if (unlikely(!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
+ !btrfs_fs_incompat(fs_info, NO_HOLES) ||
+ !btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE))) {
btrfs_err(fs_info,
"remap-tree feature requires free-space-tree, no-holes, and block-group-tree");
ret = -EINVAL;
}
- if (btrfs_fs_incompat(fs_info, MIXED_GROUPS)) {
+ if (unlikely(btrfs_fs_incompat(fs_info, MIXED_GROUPS))) {
btrfs_err(fs_info, "remap-tree not supported with mixed-bg");
ret = -EINVAL;
}
- if (btrfs_fs_incompat(fs_info, ZONED)) {
+ if (unlikely(btrfs_fs_incompat(fs_info, ZONED))) {
btrfs_err(fs_info, "remap-tree not supported with zoned devices");
ret = -EINVAL;
}
- if (sectorsize > PAGE_SIZE) {
+ if (unlikely(sectorsize > PAGE_SIZE)) {
btrfs_err(fs_info, "remap-tree not supported when block size > page size");
ret = -EINVAL;
}
@@ -2509,32 +2509,32 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
* Hint to catch really bogus numbers, bitflips or so, more exact checks are
* done later
*/
- if (btrfs_super_bytes_used(sb) < 6 * btrfs_super_nodesize(sb)) {
+ if (unlikely(btrfs_super_bytes_used(sb) < 6 * btrfs_super_nodesize(sb))) {
btrfs_err(fs_info, "bytes_used is too small %llu",
btrfs_super_bytes_used(sb));
ret = -EINVAL;
}
- if (!is_power_of_2(btrfs_super_stripesize(sb))) {
+ if (unlikely(!is_power_of_2(btrfs_super_stripesize(sb)))) {
btrfs_err(fs_info, "invalid stripesize %u",
btrfs_super_stripesize(sb));
ret = -EINVAL;
}
- if (btrfs_super_num_devices(sb) > (1UL << 31))
+ if (unlikely(btrfs_super_num_devices(sb) > (1UL << 31)))
btrfs_warn(fs_info, "suspicious number of devices: %llu",
btrfs_super_num_devices(sb));
- if (btrfs_super_num_devices(sb) == 0) {
+ if (unlikely(btrfs_super_num_devices(sb) == 0)) {
btrfs_err(fs_info, "number of devices is 0");
ret = -EINVAL;
}
- if (mirror_num >= 0 &&
- btrfs_super_bytenr(sb) != btrfs_sb_offset(mirror_num)) {
+ if (unlikely(mirror_num >= 0 &&
+ btrfs_super_bytenr(sb) != btrfs_sb_offset(mirror_num))) {
btrfs_err(fs_info, "super offset mismatch %llu != %u",
btrfs_super_bytenr(sb), BTRFS_SUPER_INFO_OFFSET);
ret = -EINVAL;
}
- if (ret)
+ if (unlikely(ret))
return ret;
ret = validate_sys_chunk_array(fs_info, sb);
@@ -2543,13 +2543,13 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
* The generation is a global counter, we'll trust it more than the others
* but it's still possible that it's the one that's wrong.
*/
- if (btrfs_super_generation(sb) < btrfs_super_chunk_root_generation(sb))
+ if (unlikely(btrfs_super_generation(sb) < btrfs_super_chunk_root_generation(sb)))
btrfs_warn(fs_info,
"suspicious: generation < chunk_root_generation: %llu < %llu",
btrfs_super_generation(sb),
btrfs_super_chunk_root_generation(sb));
- if (btrfs_super_generation(sb) < btrfs_super_cache_generation(sb)
- && btrfs_super_cache_generation(sb) != (u64)-1)
+ if (unlikely(btrfs_super_generation(sb) < btrfs_super_cache_generation(sb) &&
+ btrfs_super_cache_generation(sb) != (u64)-1))
btrfs_warn(fs_info,
"suspicious: generation < cache_generation: %llu < %llu",
btrfs_super_generation(sb),
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 2/7] btrfs: mark all error and warning checks as unlikely in btrfs_validate_super()
2026-02-04 15:51 ` [PATCH 2/7] btrfs: mark all error and warning checks as unlikely " fdmanana
@ 2026-02-05 12:04 ` David Sterba
0 siblings, 0 replies; 13+ messages in thread
From: David Sterba @ 2026-02-05 12:04 UTC (permalink / raw)
To: fdmanana; +Cc: linux-btrfs
On Wed, Feb 04, 2026 at 03:51:59PM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> When validating a super block, either when mounting or every time we write
> a super block to disk, we do many checks for error and warnings and we
> don't expect to hit any. So mark each one as unlikely to reflect that and
> allow the compiler to potentially generate better code.
>
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
I've checked the generated assembly and it seems to have the expected
effect of reordering the message prints to the end of the function while
keeping the optimistic hot paths as a series of conditional followed by
jumps. The final .ko size is a bit larger (like +150 bytes), still
acceptable.
So I guess we want to continue these annotations because the compiler
does not infer it from the context or the __cold annotations of
_btrfs_printk().
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/7] btrfs: pass transaction handle to write_all_supers()
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
2026-02-04 15:51 ` [PATCH 1/7] btrfs: change unaligned root messages to error level in btrfs_validate_super() fdmanana
2026-02-04 15:51 ` [PATCH 2/7] btrfs: mark all error and warning checks as unlikely " fdmanana
@ 2026-02-04 15:52 ` fdmanana
2026-02-04 15:52 ` [PATCH 4/7] btrfs: abort transaction on error in write_all_supers() fdmanana
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:52 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
We are holding a transaction In every context we call write_all_supers(),
so pass the transaction handle instead of fs_info to it. This will allow
us to abort the transaction in write_all_supers() instead of calling
btrfs_handle_fs_error() in a later patch.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 3 ++-
fs/btrfs/disk-io.h | 2 +-
fs/btrfs/transaction.c | 2 +-
fs/btrfs/tree-log.c | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b9eb38072191..6454cbbcaa88 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -4019,8 +4019,9 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
return min_tolerated;
}
-int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
+int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
{
+ struct btrfs_fs_info *fs_info = trans->fs_info;
struct list_head *head;
struct btrfs_device *dev;
struct btrfs_super_block *sb;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 5320da83d0cf..081a6860861c 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -58,7 +58,7 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info);
int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
const struct btrfs_super_block *sb, int mirror_num);
int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
-int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
+int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors);
int btrfs_commit_super(struct btrfs_fs_info *fs_info);
struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
const struct btrfs_key *key);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 463238ca8a4d..08f691661874 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -2557,7 +2557,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
goto scrub_continue;
}
- ret = write_all_supers(fs_info, 0);
+ ret = write_all_supers(trans, 0);
/*
* the super is written, we can safely allow the tree-loggers
* to go about their business
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e1bd03ebfd98..ed5704e0a92c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3569,7 +3569,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
btrfs_set_super_log_root(fs_info->super_for_commit, log_root_start);
btrfs_set_super_log_root_level(fs_info->super_for_commit, log_root_level);
- ret = write_all_supers(fs_info, 1);
+ ret = write_all_supers(trans, 1);
mutex_unlock(&fs_info->tree_log_mutex);
if (unlikely(ret)) {
btrfs_set_log_full_commit(trans);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 4/7] btrfs: abort transaction on error in write_all_supers()
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
` (2 preceding siblings ...)
2026-02-04 15:52 ` [PATCH 3/7] btrfs: pass transaction handle to write_all_supers() fdmanana
@ 2026-02-04 15:52 ` fdmanana
2026-02-04 15:52 ` [PATCH 5/7] btrfs: tag error branches as unlikely during super block writes fdmanana
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:52 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
We are in a transaction context and have an handle, so instead of using
the less preferred btrfs_handle_fs_error(), abort the transaction and
log an error to give some context information.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6454cbbcaa88..6e474c2d6b74 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -4054,8 +4054,8 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
if (ret) {
mutex_unlock(
&fs_info->fs_devices->device_list_mutex);
- btrfs_handle_fs_error(fs_info, ret,
- "errors while submitting device barriers.");
+ btrfs_abort_transaction(trans, ret);
+ btrfs_err(fs_info, "error while submitting device barriers");
return ret;
}
}
@@ -4089,9 +4089,10 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
ret = btrfs_validate_write_super(fs_info, sb);
if (unlikely(ret < 0)) {
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
- btrfs_handle_fs_error(fs_info, -EUCLEAN,
- "unexpected superblock corruption detected");
- return -EUCLEAN;
+ btrfs_abort_transaction(trans, ret);
+ btrfs_err(fs_info,
+ "unexpected superblock corruption before writing it");
+ return ret;
}
ret = write_dev_supers(dev, sb, max_mirrors);
@@ -4104,9 +4105,8 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
/* FUA is masked off if unsupported and can't be the reason */
- btrfs_handle_fs_error(fs_info, -EIO,
- "%d errors while writing supers",
- total_errors);
+ btrfs_abort_transaction(trans, -EIO);
+ btrfs_err(fs_info, "%d errors while writing supers", total_errors);
return -EIO;
}
@@ -4124,9 +4124,8 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
}
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
if (unlikely(total_errors > max_errors)) {
- btrfs_handle_fs_error(fs_info, -EIO,
- "%d errors while writing supers",
- total_errors);
+ btrfs_abort_transaction(trans, -EIO);
+ btrfs_err(fs_info, "%d errors while writing supers", total_errors);
return -EIO;
}
return 0;
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 5/7] btrfs: tag error branches as unlikely during super block writes
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
` (3 preceding siblings ...)
2026-02-04 15:52 ` [PATCH 4/7] btrfs: abort transaction on error in write_all_supers() fdmanana
@ 2026-02-04 15:52 ` fdmanana
2026-02-04 15:52 ` [PATCH 6/7] btrfs: remove max_mirrors argument from write_all_supers() fdmanana
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:52 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
Mark all the unexpected error checks as unlikely, to make it more clear
they are unexpected and to allow the compiler to potentially generate
better code.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6e474c2d6b74..19f7927a000d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2580,7 +2580,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
int ret;
ret = btrfs_validate_super(fs_info, sb, -1);
- if (ret < 0)
+ if (unlikely(ret < 0))
goto out;
if (unlikely(!btrfs_supported_super_csum(btrfs_super_csum_type(sb)))) {
ret = -EUCLEAN;
@@ -2597,7 +2597,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
goto out;
}
out:
- if (ret < 0)
+ if (unlikely(ret < 0))
btrfs_err(fs_info,
"super block corruption detected before writing it to disk");
return ret;
@@ -3855,7 +3855,7 @@ static int wait_dev_supers(struct btrfs_device *device, int max_mirrors)
ret = btrfs_sb_log_location(device, i, READ, &bytenr);
if (ret == -ENOENT) {
break;
- } else if (ret < 0) {
+ } else if (unlikely(ret < 0)) {
errors++;
if (i == 0)
primary_failed = true;
@@ -3877,9 +3877,8 @@ static int wait_dev_supers(struct btrfs_device *device, int max_mirrors)
}
errors += atomic_read(&device->sb_write_errors);
- if (errors >= BTRFS_SUPER_PRIMARY_WRITE_ERROR)
- primary_failed = true;
- if (primary_failed) {
+
+ if (unlikely(primary_failed || errors >= BTRFS_SUPER_PRIMARY_WRITE_ERROR)) {
btrfs_err(device->fs_info, "error writing primary super block to device %llu",
device->devid);
return -1;
@@ -3930,7 +3929,7 @@ static bool wait_dev_flush(struct btrfs_device *device)
wait_for_completion_io(&device->flush_wait);
- if (bio->bi_status) {
+ if (unlikely(bio->bi_status)) {
set_bit(BTRFS_DEV_STATE_FLUSH_FAILED, &device->dev_state);
btrfs_dev_stat_inc_and_print(device, BTRFS_DEV_STAT_FLUSH_ERRS);
return true;
@@ -3968,7 +3967,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
list_for_each_entry(dev, head, dev_list) {
if (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state))
continue;
- if (!dev->bdev) {
+ if (unlikely(!dev->bdev)) {
errors_wait++;
continue;
}
@@ -3976,7 +3975,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
!test_bit(BTRFS_DEV_STATE_WRITEABLE, &dev->dev_state))
continue;
- if (wait_dev_flush(dev))
+ if (unlikely(wait_dev_flush(dev)))
errors_wait++;
}
@@ -4051,7 +4050,7 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
if (do_barriers) {
ret = barrier_all_devices(fs_info);
- if (ret) {
+ if (unlikely(ret)) {
mutex_unlock(
&fs_info->fs_devices->device_list_mutex);
btrfs_abort_transaction(trans, ret);
@@ -4061,7 +4060,7 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
}
list_for_each_entry(dev, head, dev_list) {
- if (!dev->bdev) {
+ if (unlikely(!dev->bdev)) {
total_errors++;
continue;
}
@@ -4096,7 +4095,7 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
}
ret = write_dev_supers(dev, sb, max_mirrors);
- if (ret)
+ if (unlikely(ret))
total_errors++;
}
if (unlikely(total_errors > max_errors)) {
@@ -4112,14 +4111,14 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
total_errors = 0;
list_for_each_entry(dev, head, dev_list) {
- if (!dev->bdev)
+ if (unlikely(!dev->bdev))
continue;
if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &dev->dev_state) ||
!test_bit(BTRFS_DEV_STATE_WRITEABLE, &dev->dev_state))
continue;
ret = wait_dev_supers(dev, max_mirrors);
- if (ret)
+ if (unlikely(ret))
total_errors++;
}
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 6/7] btrfs: remove max_mirrors argument from write_all_supers()
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
` (4 preceding siblings ...)
2026-02-04 15:52 ` [PATCH 5/7] btrfs: tag error branches as unlikely during super block writes fdmanana
@ 2026-02-04 15:52 ` fdmanana
2026-02-08 15:49 ` Chris Mason
2026-02-04 15:52 ` [PATCH 7/7] btrfs: set written super flag once in write_all_supers() fdmanana
` (2 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:52 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
There's no need to pass max_mirrors to write_all_supers() since from the
given transaction handle we can infer if we are in a transaction commit
or fsync context, so we can determine how many mirrors we need to use.
So remove the max_mirror argument from write_all_supers() and stop
adjusting it in the callees write_dev_supers() and wait_dev_supers(),
simplifying them besides the parameter list for write_all_supers().
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 24 +++++++++---------------
fs/btrfs/disk-io.h | 2 +-
fs/btrfs/transaction.c | 2 +-
fs/btrfs/tree-log.c | 2 +-
4 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 19f7927a000d..cf4ab067be72 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3742,8 +3742,7 @@ static void btrfs_end_super_write(struct bio *bio)
* Write superblock @sb to the @device. Do not wait for completion, all the
* folios we use for writing are locked.
*
- * Write @max_mirrors copies of the superblock, where 0 means default that fit
- * the expected device size at commit time. Note that max_mirrors must be
+ * Write @max_mirrors copies of the superblock. Note that max_mirrors must be
* same for write and wait phases.
*
* Return number of errors when folio is not found or submission fails.
@@ -3759,9 +3758,6 @@ static int write_dev_supers(struct btrfs_device *device,
atomic_set(&device->sb_write_errors, 0);
- if (max_mirrors == 0)
- max_mirrors = BTRFS_SUPER_MIRROR_MAX;
-
for (i = 0; i < max_mirrors; i++) {
struct folio *folio;
struct bio *bio;
@@ -3846,9 +3842,6 @@ static int wait_dev_supers(struct btrfs_device *device, int max_mirrors)
int ret;
u64 bytenr;
- if (max_mirrors == 0)
- max_mirrors = BTRFS_SUPER_MIRROR_MAX;
-
for (i = 0; i < max_mirrors; i++) {
struct folio *folio;
@@ -4018,13 +4011,14 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
return min_tolerated;
}
-int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
+int write_all_supers(struct btrfs_trans_handle *trans)
{
struct btrfs_fs_info *fs_info = trans->fs_info;
struct list_head *head;
struct btrfs_device *dev;
struct btrfs_super_block *sb;
struct btrfs_dev_item *dev_item;
+ int max_mirrors;
int ret;
int do_barriers;
int max_errors;
@@ -4033,13 +4027,13 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
do_barriers = !btrfs_test_opt(fs_info, NOBARRIER);
- /*
- * max_mirrors == 0 indicates we're from commit_transaction,
- * not from fsync where the tree roots in fs_info have not
- * been consistent on disk.
- */
- if (max_mirrors == 0)
+ if (trans->in_fsync) {
+ max_mirrors = 1;
+ } else {
+ /* We are called from transaction commit. */
+ max_mirrors = BTRFS_SUPER_MIRROR_MAX;
backup_super_roots(fs_info);
+ }
sb = fs_info->super_for_commit;
dev_item = &sb->dev_item;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 081a6860861c..163f5114973a 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -58,7 +58,7 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info);
int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
const struct btrfs_super_block *sb, int mirror_num);
int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
-int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors);
+int write_all_supers(struct btrfs_trans_handle *trans);
int btrfs_commit_super(struct btrfs_fs_info *fs_info);
struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
const struct btrfs_key *key);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 08f691661874..aea84ac65ea7 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -2557,7 +2557,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
goto scrub_continue;
}
- ret = write_all_supers(trans, 0);
+ ret = write_all_supers(trans);
/*
* the super is written, we can safely allow the tree-loggers
* to go about their business
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index ed5704e0a92c..e2806ca410f6 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3569,7 +3569,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
btrfs_set_super_log_root(fs_info->super_for_commit, log_root_start);
btrfs_set_super_log_root_level(fs_info->super_for_commit, log_root_level);
- ret = write_all_supers(trans, 1);
+ ret = write_all_supers(trans);
mutex_unlock(&fs_info->tree_log_mutex);
if (unlikely(ret)) {
btrfs_set_log_full_commit(trans);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 6/7] btrfs: remove max_mirrors argument from write_all_supers()
2026-02-04 15:52 ` [PATCH 6/7] btrfs: remove max_mirrors argument from write_all_supers() fdmanana
@ 2026-02-08 15:49 ` Chris Mason
2026-02-08 18:24 ` Filipe Manana
0 siblings, 1 reply; 13+ messages in thread
From: Chris Mason @ 2026-02-08 15:49 UTC (permalink / raw)
To: fdmanana; +Cc: linux-btrfs
fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> There's no need to pass max_mirrors to write_all_supers() since from the
> given transaction handle we can infer if we are in a transaction commit
> or fsync context, so we can determine how many mirrors we need to use.
>
> So remove the max_mirror argument from write_all_supers() and stop
> adjusting it in the callees write_dev_supers() and wait_dev_supers(),
> simplifying them besides the parameter list for write_all_supers().
Hi everyone,
I'm running the btrfs for-next branch, along with the encryption patch set
through my AI review prompts:
https://github.com/masoncl/review-prompts
I'm working on some btrfs specific instructions, but hopefully these reviews
are already useful. I've kept the headers to make it easier to double check
that I'm actually replying to the right email, but please let me know if any
parts of this are incorrect:
commit a30345d606f40c870c69fb77195b3516a6dd6504
Author: Filipe Manana <fdmanana@suse.com>
btrfs: remove max_mirrors argument from write_all_supers()
This commit removes the max_mirrors parameter from write_all_supers()
and determines the mirror count from the transaction handle's in_fsync
flag, claiming this simplifies the code while maintaining correctness.
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 19f7927a000d9..cf4ab067be72c 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
[ ... ]
> @@ -4018,13 +4011,14 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
> return min_tolerated;
> }
>
> -int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
> +int write_all_supers(struct btrfs_trans_handle *trans)
> {
> struct btrfs_fs_info *fs_info = trans->fs_info;
> struct list_head *head;
> struct btrfs_device *dev;
> struct btrfs_super_block *sb;
> struct btrfs_dev_item *dev_item;
> + int max_mirrors;
> int ret;
> int do_barriers;
> int max_errors;
> @@ -4033,13 +4027,13 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
>
> do_barriers = !btrfs_test_opt(fs_info, NOBARRIER);
>
> - /*
> - * max_mirrors == 0 indicates we're from commit_transaction,
> - * not from fsync where the tree roots in fs_info have not
> - * been consistent on disk.
> - */
> - if (max_mirrors == 0)
> + if (trans->in_fsync) {
> + max_mirrors = 1;
> + } else {
> + /* We are called from transaction commit. */
> + max_mirrors = BTRFS_SUPER_MIRROR_MAX;
> backup_super_roots(fs_info);
> + }
Can this logic handle the case where btrfs_sync_file() falls through to
btrfs_commit_transaction()? Looking at fs/btrfs/file.c, when a full_sync
encounters a log sync failure or BTRFS_LOG_FORCE_COMMIT, the code flow is:
btrfs_sync_file()
trans->in_fsync = true; /* Set at file.c:1728 */
...
btrfs_sync_log() /* May fail or return BTRFS_LOG_FORCE_COMMIT */
...
btrfs_commit_transaction(trans) /* Fallthrough at file.c:1787-1816 */
write_all_supers(trans)
if (trans->in_fsync) /* Still true here */
max_mirrors = 1; /* But we're in transaction commit */
The OLD code always passed max_mirrors=0 from btrfs_commit_transaction()
(transaction.c:2560), ensuring full superblock redundancy with
BTRFS_SUPER_MIRROR_MAX=3 and calling backup_super_roots() regardless of
how the transaction commit was triggered.
The NEW code uses trans->in_fsync which remains true during the
fsync-to-commit fallthrough path. This causes write_all_supers() to set
max_mirrors=1 and skip backup_super_roots(), reducing superblock
redundancy from 3 copies to 1 and skipping tree root backups during these
commits.
Is the commit message claim that "from the given transaction handle we can
infer if we are in a transaction commit or fsync context" accurate for
this case?
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 6/7] btrfs: remove max_mirrors argument from write_all_supers()
2026-02-08 15:49 ` Chris Mason
@ 2026-02-08 18:24 ` Filipe Manana
0 siblings, 0 replies; 13+ messages in thread
From: Filipe Manana @ 2026-02-08 18:24 UTC (permalink / raw)
To: Chris Mason; +Cc: linux-btrfs
On Sun, Feb 8, 2026 at 3:52 PM Chris Mason <clm@meta.com> wrote:
>
> fdmanana@kernel.org wrote:
> > From: Filipe Manana <fdmanana@suse.com>
> >
> > There's no need to pass max_mirrors to write_all_supers() since from the
> > given transaction handle we can infer if we are in a transaction commit
> > or fsync context, so we can determine how many mirrors we need to use.
> >
> > So remove the max_mirror argument from write_all_supers() and stop
> > adjusting it in the callees write_dev_supers() and wait_dev_supers(),
> > simplifying them besides the parameter list for write_all_supers().
>
> Hi everyone,
>
> I'm running the btrfs for-next branch, along with the encryption patch set
> through my AI review prompts:
>
> https://github.com/masoncl/review-prompts
>
> I'm working on some btrfs specific instructions, but hopefully these reviews
> are already useful. I've kept the headers to make it easier to double check
> that I'm actually replying to the right email, but please let me know if any
> parts of this are incorrect:
>
> commit a30345d606f40c870c69fb77195b3516a6dd6504
> Author: Filipe Manana <fdmanana@suse.com>
>
> btrfs: remove max_mirrors argument from write_all_supers()
>
> This commit removes the max_mirrors parameter from write_all_supers()
> and determines the mirror count from the transaction handle's in_fsync
> flag, claiming this simplifies the code while maintaining correctness.
>
> > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> > index 19f7927a000d9..cf4ab067be72c 100644
> > --- a/fs/btrfs/disk-io.c
> > +++ b/fs/btrfs/disk-io.c
>
> [ ... ]
>
> > @@ -4018,13 +4011,14 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
> > return min_tolerated;
> > }
> >
> > -int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
> > +int write_all_supers(struct btrfs_trans_handle *trans)
> > {
> > struct btrfs_fs_info *fs_info = trans->fs_info;
> > struct list_head *head;
> > struct btrfs_device *dev;
> > struct btrfs_super_block *sb;
> > struct btrfs_dev_item *dev_item;
> > + int max_mirrors;
> > int ret;
> > int do_barriers;
> > int max_errors;
> > @@ -4033,13 +4027,13 @@ int write_all_supers(struct btrfs_trans_handle *trans, int max_mirrors)
> >
> > do_barriers = !btrfs_test_opt(fs_info, NOBARRIER);
> >
> > - /*
> > - * max_mirrors == 0 indicates we're from commit_transaction,
> > - * not from fsync where the tree roots in fs_info have not
> > - * been consistent on disk.
> > - */
> > - if (max_mirrors == 0)
> > + if (trans->in_fsync) {
> > + max_mirrors = 1;
> > + } else {
> > + /* We are called from transaction commit. */
> > + max_mirrors = BTRFS_SUPER_MIRROR_MAX;
> > backup_super_roots(fs_info);
> > + }
>
> Can this logic handle the case where btrfs_sync_file() falls through to
> btrfs_commit_transaction()? Looking at fs/btrfs/file.c, when a full_sync
> encounters a log sync failure or BTRFS_LOG_FORCE_COMMIT, the code flow is:
>
> btrfs_sync_file()
> trans->in_fsync = true; /* Set at file.c:1728 */
> ...
> btrfs_sync_log() /* May fail or return BTRFS_LOG_FORCE_COMMIT */
> ...
> btrfs_commit_transaction(trans) /* Fallthrough at file.c:1787-1816 */
> write_all_supers(trans)
> if (trans->in_fsync) /* Still true here */
> max_mirrors = 1; /* But we're in transaction commit */
>
> The OLD code always passed max_mirrors=0 from btrfs_commit_transaction()
> (transaction.c:2560), ensuring full superblock redundancy with
> BTRFS_SUPER_MIRROR_MAX=3 and calling backup_super_roots() regardless of
> how the transaction commit was triggered.
>
> The NEW code uses trans->in_fsync which remains true during the
> fsync-to-commit fallthrough path. This causes write_all_supers() to set
> max_mirrors=1 and skip backup_super_roots(), reducing superblock
> redundancy from 3 copies to 1 and skipping tree root backups during these
> commits.
Oh yes, it won't write the super block to all mirrors if a fsync falls
back to a transaction commit.
This fixup addresses the issue (which I'll fold into for-next):
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e95c699a0bae..67117e7516bf 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -4026,7 +4026,8 @@ int write_all_supers(struct btrfs_trans_handle *trans)
do_barriers = !btrfs_test_opt(fs_info, NOBARRIER);
- if (trans->in_fsync) {
+ if (trans->transaction->state < TRANS_STATE_UNBLOCKED) {
+ /* We are called from fsync. */
max_mirrors = 1;
} else {
/* We are called from transaction commit. */
Thanks.
>
> Is the commit message claim that "from the given transaction handle we can
> infer if we are in a transaction commit or fsync context" accurate for
> this case?
>
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/7] btrfs: set written super flag once in write_all_supers()
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
` (5 preceding siblings ...)
2026-02-04 15:52 ` [PATCH 6/7] btrfs: remove max_mirrors argument from write_all_supers() fdmanana
@ 2026-02-04 15:52 ` fdmanana
2026-02-05 12:04 ` [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path David Sterba
2026-02-05 21:12 ` Qu Wenruo
8 siblings, 0 replies; 13+ messages in thread
From: fdmanana @ 2026-02-04 15:52 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
In case we have multiple devices, there is no point in setting the written
flag in the super block on every iteration over the device list. Just do
it once before the loop.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/disk-io.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index cf4ab067be72..e95c699a0bae 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -4023,7 +4023,6 @@ int write_all_supers(struct btrfs_trans_handle *trans)
int do_barriers;
int max_errors;
int total_errors = 0;
- u64 flags;
do_barriers = !btrfs_test_opt(fs_info, NOBARRIER);
@@ -4053,6 +4052,8 @@ int write_all_supers(struct btrfs_trans_handle *trans)
}
}
+ btrfs_set_super_flags(sb, btrfs_super_flags(sb) | BTRFS_HEADER_FLAG_WRITTEN);
+
list_for_each_entry(dev, head, dev_list) {
if (unlikely(!dev->bdev)) {
total_errors++;
@@ -4076,9 +4077,6 @@ int write_all_supers(struct btrfs_trans_handle *trans)
memcpy(dev_item->fsid, dev->fs_devices->metadata_uuid,
BTRFS_FSID_SIZE);
- flags = btrfs_super_flags(sb);
- btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN);
-
ret = btrfs_validate_write_super(fs_info, sb);
if (unlikely(ret < 0)) {
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
` (6 preceding siblings ...)
2026-02-04 15:52 ` [PATCH 7/7] btrfs: set written super flag once in write_all_supers() fdmanana
@ 2026-02-05 12:04 ` David Sterba
2026-02-05 21:12 ` Qu Wenruo
8 siblings, 0 replies; 13+ messages in thread
From: David Sterba @ 2026-02-05 12:04 UTC (permalink / raw)
To: fdmanana; +Cc: linux-btrfs
On Wed, Feb 04, 2026 at 03:51:57PM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> Details in the change logs.
>
> Filipe Manana (7):
> btrfs: change unaligned root messages to error level in btrfs_validate_super()
> btrfs: mark all error and warning checks as unlikely in btrfs_validate_super()
> btrfs: pass transaction handle to write_all_supers()
> btrfs: abort transaction on error in write_all_supers()
> btrfs: tag error branches as unlikely during super block writes
> btrfs: remove max_mirrors argument from write_all_supers()
> btrfs: set written super flag once in write_all_supers()
Reviewed-by: David Sterba <dsterba@suse.com>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path
2026-02-04 15:51 [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path fdmanana
` (7 preceding siblings ...)
2026-02-05 12:04 ` [PATCH 0/7] btrfs: minor tweaks and cleanups to the super block writing path David Sterba
@ 2026-02-05 21:12 ` Qu Wenruo
8 siblings, 0 replies; 13+ messages in thread
From: Qu Wenruo @ 2026-02-05 21:12 UTC (permalink / raw)
To: fdmanana, linux-btrfs
在 2026/2/5 02:21, fdmanana@kernel.org 写道:
> From: Filipe Manana <fdmanana@suse.com>
>
> Details in the change logs.
Reviewed-by: Qu Wenruo <wqu@suse.com>
Thanks,
Qu
>
> Filipe Manana (7):
> btrfs: change unaligned root messages to error level in btrfs_validate_super()
> btrfs: mark all error and warning checks as unlikely in btrfs_validate_super()
> btrfs: pass transaction handle to write_all_supers()
> btrfs: abort transaction on error in write_all_supers()
> btrfs: tag error branches as unlikely during super block writes
> btrfs: remove max_mirrors argument from write_all_supers()
> btrfs: set written super flag once in write_all_supers()
>
> fs/btrfs/disk-io.c | 167 +++++++++++++++++++----------------------
> fs/btrfs/disk-io.h | 2 +-
> fs/btrfs/transaction.c | 2 +-
> fs/btrfs/tree-log.c | 2 +-
> 4 files changed, 82 insertions(+), 91 deletions(-)
>
^ permalink raw reply [flat|nested] 13+ messages in thread