diff options
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r-- | fs/btrfs/free-space-cache.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index ab8cad8b46c9..af99b78b288e 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -238,6 +238,7 @@ static void unlink_free_space(struct btrfs_block_group_cache *block_group, | |||
238 | { | 238 | { |
239 | rb_erase(&info->offset_index, &block_group->free_space_offset); | 239 | rb_erase(&info->offset_index, &block_group->free_space_offset); |
240 | block_group->free_extents--; | 240 | block_group->free_extents--; |
241 | block_group->free_space -= info->bytes; | ||
241 | } | 242 | } |
242 | 243 | ||
243 | static int link_free_space(struct btrfs_block_group_cache *block_group, | 244 | static int link_free_space(struct btrfs_block_group_cache *block_group, |
@@ -251,6 +252,7 @@ static int link_free_space(struct btrfs_block_group_cache *block_group, | |||
251 | if (ret) | 252 | if (ret) |
252 | return ret; | 253 | return ret; |
253 | 254 | ||
255 | block_group->free_space += info->bytes; | ||
254 | block_group->free_extents++; | 256 | block_group->free_extents++; |
255 | return ret; | 257 | return ret; |
256 | } | 258 | } |
@@ -285,36 +287,40 @@ static void recalculate_thresholds(struct btrfs_block_group_cache *block_group) | |||
285 | } | 287 | } |
286 | } | 288 | } |
287 | 289 | ||
288 | static void bitmap_clear_bits(struct btrfs_free_space *info, u64 offset, u64 bytes, | 290 | static void bitmap_clear_bits(struct btrfs_block_group_cache *block_group, |
289 | u64 sectorsize) | 291 | struct btrfs_free_space *info, u64 offset, |
292 | u64 bytes) | ||
290 | { | 293 | { |
291 | unsigned long start, end; | 294 | unsigned long start, end; |
292 | unsigned long i; | 295 | unsigned long i; |
293 | 296 | ||
294 | start = offset_to_bit(info->offset, sectorsize, offset); | 297 | start = offset_to_bit(info->offset, block_group->sectorsize, offset); |
295 | end = start + bytes_to_bits(bytes, sectorsize); | 298 | end = start + bytes_to_bits(bytes, block_group->sectorsize); |
296 | BUG_ON(end > BITS_PER_BITMAP); | 299 | BUG_ON(end > BITS_PER_BITMAP); |
297 | 300 | ||
298 | for (i = start; i < end; i++) | 301 | for (i = start; i < end; i++) |
299 | clear_bit(i, info->bitmap); | 302 | clear_bit(i, info->bitmap); |
300 | 303 | ||
301 | info->bytes -= bytes; | 304 | info->bytes -= bytes; |
305 | block_group->free_space -= bytes; | ||
302 | } | 306 | } |
303 | 307 | ||
304 | static void bitmap_set_bits(struct btrfs_free_space *info, u64 offset, u64 bytes, | 308 | static void bitmap_set_bits(struct btrfs_block_group_cache *block_group, |
305 | u64 sectorsize) | 309 | struct btrfs_free_space *info, u64 offset, |
310 | u64 bytes) | ||
306 | { | 311 | { |
307 | unsigned long start, end; | 312 | unsigned long start, end; |
308 | unsigned long i; | 313 | unsigned long i; |
309 | 314 | ||
310 | start = offset_to_bit(info->offset, sectorsize, offset); | 315 | start = offset_to_bit(info->offset, block_group->sectorsize, offset); |
311 | end = start + bytes_to_bits(bytes, sectorsize); | 316 | end = start + bytes_to_bits(bytes, block_group->sectorsize); |
312 | BUG_ON(end > BITS_PER_BITMAP); | 317 | BUG_ON(end > BITS_PER_BITMAP); |
313 | 318 | ||
314 | for (i = start; i < end; i++) | 319 | for (i = start; i < end; i++) |
315 | set_bit(i, info->bitmap); | 320 | set_bit(i, info->bitmap); |
316 | 321 | ||
317 | info->bytes += bytes; | 322 | info->bytes += bytes; |
323 | block_group->free_space += bytes; | ||
318 | } | 324 | } |
319 | 325 | ||
320 | static int search_bitmap(struct btrfs_block_group_cache *block_group, | 326 | static int search_bitmap(struct btrfs_block_group_cache *block_group, |
@@ -414,13 +420,12 @@ again: | |||
414 | (u64)(BITS_PER_BITMAP * block_group->sectorsize) - 1; | 420 | (u64)(BITS_PER_BITMAP * block_group->sectorsize) - 1; |
415 | 421 | ||
416 | if (*offset > bitmap_info->offset && *offset + *bytes > end) { | 422 | if (*offset > bitmap_info->offset && *offset + *bytes > end) { |
417 | bitmap_clear_bits(bitmap_info, *offset, | 423 | bitmap_clear_bits(block_group, bitmap_info, *offset, |
418 | end - *offset + 1, block_group->sectorsize); | 424 | end - *offset + 1); |
419 | *bytes -= end - *offset + 1; | 425 | *bytes -= end - *offset + 1; |
420 | *offset = end + 1; | 426 | *offset = end + 1; |
421 | } else if (*offset >= bitmap_info->offset && *offset + *bytes <= end) { | 427 | } else if (*offset >= bitmap_info->offset && *offset + *bytes <= end) { |
422 | bitmap_clear_bits(bitmap_info, *offset, | 428 | bitmap_clear_bits(block_group, bitmap_info, *offset, *bytes); |
423 | *bytes, block_group->sectorsize); | ||
424 | *bytes = 0; | 429 | *bytes = 0; |
425 | } | 430 | } |
426 | 431 | ||
@@ -495,14 +500,13 @@ again: | |||
495 | (u64)(BITS_PER_BITMAP * block_group->sectorsize); | 500 | (u64)(BITS_PER_BITMAP * block_group->sectorsize); |
496 | 501 | ||
497 | if (offset >= bitmap_info->offset && offset + bytes > end) { | 502 | if (offset >= bitmap_info->offset && offset + bytes > end) { |
498 | bitmap_set_bits(bitmap_info, offset, end - offset, | 503 | bitmap_set_bits(block_group, bitmap_info, offset, |
499 | block_group->sectorsize); | 504 | end - offset); |
500 | bytes -= end - offset; | 505 | bytes -= end - offset; |
501 | offset = end; | 506 | offset = end; |
502 | added = 0; | 507 | added = 0; |
503 | } else if (offset >= bitmap_info->offset && offset + bytes <= end) { | 508 | } else if (offset >= bitmap_info->offset && offset + bytes <= end) { |
504 | bitmap_set_bits(bitmap_info, offset, bytes, | 509 | bitmap_set_bits(block_group, bitmap_info, offset, bytes); |
505 | block_group->sectorsize); | ||
506 | bytes = 0; | 510 | bytes = 0; |
507 | } else { | 511 | } else { |
508 | BUG(); | 512 | BUG(); |
@@ -870,8 +874,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | |||
870 | 874 | ||
871 | ret = offset; | 875 | ret = offset; |
872 | if (entry->bitmap) { | 876 | if (entry->bitmap) { |
873 | bitmap_clear_bits(entry, offset, bytes, | 877 | bitmap_clear_bits(block_group, entry, offset, bytes); |
874 | block_group->sectorsize); | ||
875 | if (!entry->bytes) { | 878 | if (!entry->bytes) { |
876 | unlink_free_space(block_group, entry); | 879 | unlink_free_space(block_group, entry); |
877 | kfree(entry->bitmap); | 880 | kfree(entry->bitmap); |
@@ -891,6 +894,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | |||
891 | 894 | ||
892 | out: | 895 | out: |
893 | spin_unlock(&block_group->tree_lock); | 896 | spin_unlock(&block_group->tree_lock); |
897 | |||
894 | return ret; | 898 | return ret; |
895 | } | 899 | } |
896 | 900 | ||
@@ -967,7 +971,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, | |||
967 | goto out; | 971 | goto out; |
968 | 972 | ||
969 | ret = search_start; | 973 | ret = search_start; |
970 | bitmap_clear_bits(entry, ret, bytes, block_group->sectorsize); | 974 | bitmap_clear_bits(block_group, entry, ret, bytes); |
971 | out: | 975 | out: |
972 | spin_unlock(&cluster->lock); | 976 | spin_unlock(&cluster->lock); |
973 | spin_unlock(&block_group->tree_lock); | 977 | spin_unlock(&block_group->tree_lock); |