Commit bb3ac5a4dfc8eeb881206c77d9f925e320d9c41a

Authored by Miao Xie
Committed by Chris Mason
1 parent f4ac904c41

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;