]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
btrfs: add comment about locking to btrfs_split_ordered_extent()
authorFilipe Manana <fdmanana@suse.com>
Mon, 3 Jun 2024 15:50:31 +0000 (16:50 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 11 Jul 2024 13:33:23 +0000 (15:33 +0200)
There are subtle details about why the root's ordered_extent_lock is held,
so add a comment mentioning them.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
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>
fs/btrfs/ordered-data.c

index 1cabcfa85e7cda358e2f825a418ad6fd843f4a04..1f7f6720b2ea6e54bdeea08cd3a0c2a16bd7bd4c 100644 (file)
@@ -1247,6 +1247,23 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent(
        /* One ref for the tree. */
        refcount_inc(&new->refs);
 
+       /*
+        * Take the root's ordered_extent_lock to avoid a race with
+        * btrfs_wait_ordered_extents() when updating the disk_bytenr and
+        * disk_num_bytes fields of the ordered extent below. And we disable
+        * IRQs because the inode's ordered_tree_lock is used in IRQ context
+        * elsewhere.
+        *
+        * There's no concern about a previous caller of
+        * btrfs_wait_ordered_extents() getting the trimmed ordered extent
+        * before we insert the new one, because even if it gets the ordered
+        * extent before it's trimmed and the new one inserted, right before it
+        * uses it or during its use, the ordered extent might have been
+        * trimmed in the meanwhile, and it missed the new ordered extent.
+        * There's no way around this and it's harmless for current use cases,
+        * so we take the root's ordered_extent_lock to fix that race during
+        * trimming and silence tools like KCSAN.
+        */
        spin_lock_irq(&root->ordered_extent_lock);
        spin_lock(&inode->ordered_tree_lock);
        /* Remove from tree once */