mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-04 09:59:32 +00:00
Btrfs: fix wrong free space information
Btrfs subtracted the size of the allocated space twice when it allocated the space from the bitmap in the cluster, it broke the free space information and led to oops finally. And this patch also fixes the bug that ctl->free_space was subtracted without lock. Reported-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
f4ac904c41
commit
bb3ac5a4df
1 changed files with 11 additions and 5 deletions
|
@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
|
||||||
div64_u64(extent_bytes, (sizeof(struct btrfs_free_space)));
|
div64_u64(extent_bytes, (sizeof(struct btrfs_free_space)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
|
static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
|
||||||
struct btrfs_free_space *info, u64 offset,
|
struct btrfs_free_space *info,
|
||||||
u64 bytes)
|
u64 offset, u64 bytes)
|
||||||
{
|
{
|
||||||
unsigned long start, count;
|
unsigned long start, count;
|
||||||
|
|
||||||
|
@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
|
||||||
bitmap_clear(info->bitmap, start, count);
|
bitmap_clear(info->bitmap, start, count);
|
||||||
|
|
||||||
info->bytes -= bytes;
|
info->bytes -= bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
|
||||||
|
struct btrfs_free_space *info, u64 offset,
|
||||||
|
u64 bytes)
|
||||||
|
{
|
||||||
|
__bitmap_clear_bits(ctl, info, offset, bytes);
|
||||||
ctl->free_space -= bytes;
|
ctl->free_space -= bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = search_start;
|
ret = search_start;
|
||||||
bitmap_clear_bits(ctl, entry, ret, bytes);
|
__bitmap_clear_bits(ctl, entry, ret, bytes);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ret = entry->offset;
|
ret = entry->offset;
|
||||||
|
|
||||||
entry->offset += bytes;
|
entry->offset += bytes;
|
||||||
|
|
Loading…
Reference in a new issue