]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: fix copying the flags of btrfs_bio after split
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Mon, 26 Jan 2026 08:05:24 +0000 (09:05 +0100)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 06:56:24 +0000 (07:56 +0100)
When a btrfs_bio gets split, only 'bbio->csum_search_commit_root' gets
copied to the new btrfs_bio, all the other flags don't.

When a bio is split in btrfs_submit_chunk(), btrfs_split_bio() creates
the new split bio via btrfs_bio_init() which zeroes the struct with
memset. Looking at btrfs_split_bio(), it copies csum_search_commit_root
from the original but does not copy can_use_append.

After the split, the code does:

    bbio = split;
    bio = &bbio->bio;

This means the split bio (with can_use_append = false) gets submitted,
not the original. In btrfs_submit_dev_bio(), the condition:

    if (btrfs_bio(bio)->can_use_append && btrfs_dev_is_sequential(...))

Will be false for the split bio even when writing to a sequential zone.
Does the split bio need to inherit can_use_append from the original? The
old code used a local variable use_append which persisted across the
split.

Copy the rest of the flags as well.

Link: https://lore.kernel.org/linux-btrfs/20260125132120.2525146-1-clm@meta.com/
Reported-by: Chris Mason <clm@meta.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/bio.c

index d3475d179362480ec0260d70f85aa922e4c161f7..0a69e09bfe28d898a30f2cf002706b15f408217d 100644 (file)
@@ -97,7 +97,13 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
                bbio->orig_logical = orig_bbio->orig_logical;
                orig_bbio->orig_logical += map_length;
        }
+
        bbio->csum_search_commit_root = orig_bbio->csum_search_commit_root;
+       bbio->can_use_append = orig_bbio->can_use_append;
+       bbio->is_scrub = orig_bbio->is_scrub;
+       bbio->is_remap = orig_bbio->is_remap;
+       bbio->async_csum = orig_bbio->async_csum;
+
        atomic_inc(&orig_bbio->pending_ios);
        return bbio;
 }