Commit bb3ac5a4dfc8eeb881206c77d9f925e320d9c41a
Committed by
Chris Mason
1 parent
f4ac904c41
Exists in
master
and in
38 other branches
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>
Showing 1 changed file with 11 additions and 5 deletions Side-by-side Diff
fs/btrfs/free-space-cache.c
... | ... | @@ -1168,9 +1168,9 @@ |
1168 | 1168 | div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); |
1169 | 1169 | } |
1170 | 1170 | |
1171 | -static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, | |
1172 | - struct btrfs_free_space *info, u64 offset, | |
1173 | - u64 bytes) | |
1171 | +static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, | |
1172 | + struct btrfs_free_space *info, | |
1173 | + u64 offset, u64 bytes) | |
1174 | 1174 | { |
1175 | 1175 | unsigned long start, count; |
1176 | 1176 | |
... | ... | @@ -1181,6 +1181,13 @@ |
1181 | 1181 | bitmap_clear(info->bitmap, start, count); |
1182 | 1182 | |
1183 | 1183 | info->bytes -= bytes; |
1184 | +} | |
1185 | + | |
1186 | +static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, | |
1187 | + struct btrfs_free_space *info, u64 offset, | |
1188 | + u64 bytes) | |
1189 | +{ | |
1190 | + __bitmap_clear_bits(ctl, info, offset, bytes); | |
1184 | 1191 | ctl->free_space -= bytes; |
1185 | 1192 | } |
1186 | 1193 | |
... | ... | @@ -1984,7 +1991,7 @@ |
1984 | 1991 | return 0; |
1985 | 1992 | |
1986 | 1993 | ret = search_start; |
1987 | - bitmap_clear_bits(ctl, entry, ret, bytes); | |
1994 | + __bitmap_clear_bits(ctl, entry, ret, bytes); | |
1988 | 1995 | |
1989 | 1996 | return ret; |
1990 | 1997 | } |
... | ... | @@ -2039,7 +2046,6 @@ |
2039 | 2046 | continue; |
2040 | 2047 | } |
2041 | 2048 | } else { |
2042 | - | |
2043 | 2049 | ret = entry->offset; |
2044 | 2050 | |
2045 | 2051 | entry->offset += bytes; |