]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
btrfs: handle empty list of NOCOW ordered extents with checksum list
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Fri, 4 Oct 2024 13:19:01 +0000 (15:19 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 11 Nov 2024 13:34:14 +0000 (14:34 +0100)
Currently we BUG_ON() in btrfs_finish_one_ordered() if we are finishing
an ordered extent that is flagged as NOCOW, but it's checksum list is
not empty.

This is clearly a logic error which we can recover from by aborting the
transaction.

For developer builds which enable CONFIG_BTRFS_ASSERT, also ASSERT()
that the list is empty.

Suggested-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
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/inode.c

index 5d8da882d4871955c7219e9dbe9265ed915307bc..8da5e47db751ae1f1d4fc8dd99b0bc3778545b3f 100644 (file)
@@ -3088,7 +3088,12 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
 
        if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
                /* Logic error */
-               BUG_ON(!list_empty(&ordered_extent->list));
+               ASSERT(list_empty(&ordered_extent->list));
+               if (!list_empty(&ordered_extent->list)) {
+                       ret = -EINVAL;
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
 
                btrfs_inode_safe_disk_i_size_write(inode, 0);
                ret = btrfs_update_inode_fallback(trans, inode);