btrfs: ensure removal of discardable_* in free_bitmap()
Most callers of free_bitmap() only call it if bitmap_info->bytes is 0. However, there are certain cases where we may free the free space cache via __btrfs_remove_free_space_cache(). This exposes a path where free_bitmap() is called regardless. This may result in a bad accounting situation for discardable_bytes and discardable_extents. So, remove the stats and call btrfs_discard_update_discardable(). Signed-off-by: Dennis Zhou <dennis@kernel.org> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f9bb615af2
commit
27f0afc737
|
@ -1959,6 +1959,18 @@ static void add_new_bitmap(struct btrfs_free_space_ctl *ctl,
|
|||
static void free_bitmap(struct btrfs_free_space_ctl *ctl,
|
||||
struct btrfs_free_space *bitmap_info)
|
||||
{
|
||||
/*
|
||||
* Normally when this is called, the bitmap is completely empty. However,
|
||||
* if we are blowing up the free space cache for one reason or another
|
||||
* via __btrfs_remove_free_space_cache(), then it may not be freed and
|
||||
* we may leave stats on the table.
|
||||
*/
|
||||
if (bitmap_info->bytes && !btrfs_free_space_trimmed(bitmap_info)) {
|
||||
ctl->discardable_extents[BTRFS_STAT_CURR] -=
|
||||
bitmap_info->bitmap_extents;
|
||||
ctl->discardable_bytes[BTRFS_STAT_CURR] -= bitmap_info->bytes;
|
||||
|
||||
}
|
||||
unlink_free_space(ctl, bitmap_info);
|
||||
kmem_cache_free(btrfs_free_space_bitmap_cachep, bitmap_info->bitmap);
|
||||
kmem_cache_free(btrfs_free_space_cachep, bitmap_info);
|
||||
|
@ -2776,6 +2788,8 @@ void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
|
|||
{
|
||||
spin_lock(&ctl->tree_lock);
|
||||
__btrfs_remove_free_space_cache_locked(ctl);
|
||||
if (ctl->private)
|
||||
btrfs_discard_update_discardable(ctl->private, ctl);
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user