mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
btrfs: assert proper locks are held at tree_insert_offset()
There are multiple code paths leading to tree_insert_offset(), and each path takes the necessary locks before tree_insert_offset() is called, since they do other things that require those locks to be held. This makes it easy to miss the locking somewhere, so make tree_insert_offset() assert that the required locks are being held by the calling task. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
0d6bac4d30
commit
13c2018fcc
1 changed files with 19 additions and 6 deletions
|
@ -1598,12 +1598,25 @@ static inline u64 offset_to_bitmap(struct btrfs_free_space_ctl *ctl,
|
|||
return bitmap_start;
|
||||
}
|
||||
|
||||
static int tree_insert_offset(struct rb_root *root,
|
||||
static int tree_insert_offset(struct btrfs_free_space_ctl *ctl,
|
||||
struct btrfs_free_cluster *cluster,
|
||||
struct btrfs_free_space *new_entry)
|
||||
{
|
||||
struct rb_node **p = &root->rb_node;
|
||||
struct rb_root *root;
|
||||
struct rb_node **p;
|
||||
struct rb_node *parent = NULL;
|
||||
|
||||
lockdep_assert_held(&ctl->tree_lock);
|
||||
|
||||
if (cluster) {
|
||||
lockdep_assert_held(&cluster->lock);
|
||||
root = &cluster->root;
|
||||
} else {
|
||||
root = &ctl->free_space_offset;
|
||||
}
|
||||
|
||||
p = &root->rb_node;
|
||||
|
||||
while (*p) {
|
||||
struct btrfs_free_space *info;
|
||||
|
||||
|
@ -1836,7 +1849,7 @@ static int link_free_space(struct btrfs_free_space_ctl *ctl,
|
|||
int ret = 0;
|
||||
|
||||
ASSERT(info->bytes || info->bitmap);
|
||||
ret = tree_insert_offset(&ctl->free_space_offset, info);
|
||||
ret = tree_insert_offset(ctl, NULL, info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3013,7 +3026,7 @@ static void __btrfs_return_cluster_to_free_space(
|
|||
entry->bytes;
|
||||
}
|
||||
}
|
||||
tree_insert_offset(&ctl->free_space_offset, entry);
|
||||
tree_insert_offset(ctl, NULL, entry);
|
||||
rb_add_cached(&entry->bytes_index, &ctl->free_space_bytes,
|
||||
entry_less);
|
||||
}
|
||||
|
@ -3387,7 +3400,7 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group *block_group,
|
|||
*/
|
||||
RB_CLEAR_NODE(&entry->bytes_index);
|
||||
|
||||
ret = tree_insert_offset(&cluster->root, entry);
|
||||
ret = tree_insert_offset(ctl, cluster, entry);
|
||||
ASSERT(!ret); /* -EEXIST; Logic error */
|
||||
|
||||
trace_btrfs_setup_cluster(block_group, cluster,
|
||||
|
@ -3477,7 +3490,7 @@ setup_cluster_no_bitmap(struct btrfs_block_group *block_group,
|
|||
|
||||
rb_erase(&entry->offset_index, &ctl->free_space_offset);
|
||||
rb_erase_cached(&entry->bytes_index, &ctl->free_space_bytes);
|
||||
ret = tree_insert_offset(&cluster->root, entry);
|
||||
ret = tree_insert_offset(ctl, cluster, entry);
|
||||
total_size += entry->bytes;
|
||||
ASSERT(!ret); /* -EEXIST; Logic error */
|
||||
} while (node && entry != last);
|
||||
|
|
Loading…
Reference in a new issue