提交 27f0afc7 编写于 作者: D Dennis Zhou 提交者: David Sterba

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: NDennis Zhou <dennis@kernel.org>
Signed-off-by: NDavid Sterba <dsterba@suse.com>
上级 f9bb615a
...@@ -1959,6 +1959,18 @@ static void add_new_bitmap(struct btrfs_free_space_ctl *ctl, ...@@ -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, static void free_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info) 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); unlink_free_space(ctl, bitmap_info);
kmem_cache_free(btrfs_free_space_bitmap_cachep, bitmap_info->bitmap); kmem_cache_free(btrfs_free_space_bitmap_cachep, bitmap_info->bitmap);
kmem_cache_free(btrfs_free_space_cachep, bitmap_info); 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) ...@@ -2776,6 +2788,8 @@ void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
{ {
spin_lock(&ctl->tree_lock); spin_lock(&ctl->tree_lock);
__btrfs_remove_free_space_cache_locked(ctl); __btrfs_remove_free_space_cache_locked(ctl);
if (ctl->private)
btrfs_discard_update_discardable(ctl->private, ctl);
spin_unlock(&ctl->tree_lock); spin_unlock(&ctl->tree_lock);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册