diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2010-11-09 01:57:39 -0500 |
---|---|---|
committer | Li Zefan <lizf@cn.fujitsu.com> | 2011-01-26 12:04:57 -0500 |
commit | f333adb5d64bc1c4d6099072fc341c3c8f84e0cf (patch) | |
tree | abf1c214113a9c2dec3d42a9e0ee14e1863fe0a1 /fs/btrfs/free-space-cache.c | |
parent | 120d66eec0dcb966fbd03f743598b2ff2513436b (diff) |
btrfs: Check mergeable free space when removing a cluster
After returing extents from a cluster to the block group, some
extents in the block group may be mergeable.
Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r-- | fs/btrfs/free-space-cache.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index cf67dc3b7bf8..a5501edc3c9f 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -987,11 +987,18 @@ tree_search_offset(struct btrfs_block_group_cache *block_group, | |||
987 | return entry; | 987 | return entry; |
988 | } | 988 | } |
989 | 989 | ||
990 | static void unlink_free_space(struct btrfs_block_group_cache *block_group, | 990 | static inline void |
991 | struct btrfs_free_space *info) | 991 | __unlink_free_space(struct btrfs_block_group_cache *block_group, |
992 | struct btrfs_free_space *info) | ||
992 | { | 993 | { |
993 | rb_erase(&info->offset_index, &block_group->free_space_offset); | 994 | rb_erase(&info->offset_index, &block_group->free_space_offset); |
994 | block_group->free_extents--; | 995 | block_group->free_extents--; |
996 | } | ||
997 | |||
998 | static void unlink_free_space(struct btrfs_block_group_cache *block_group, | ||
999 | struct btrfs_free_space *info) | ||
1000 | { | ||
1001 | __unlink_free_space(block_group, info); | ||
995 | block_group->free_space -= info->bytes; | 1002 | block_group->free_space -= info->bytes; |
996 | } | 1003 | } |
997 | 1004 | ||
@@ -1364,7 +1371,7 @@ out: | |||
1364 | } | 1371 | } |
1365 | 1372 | ||
1366 | bool try_merge_free_space(struct btrfs_block_group_cache *block_group, | 1373 | bool try_merge_free_space(struct btrfs_block_group_cache *block_group, |
1367 | struct btrfs_free_space *info) | 1374 | struct btrfs_free_space *info, bool update_stat) |
1368 | { | 1375 | { |
1369 | struct btrfs_free_space *left_info; | 1376 | struct btrfs_free_space *left_info; |
1370 | struct btrfs_free_space *right_info; | 1377 | struct btrfs_free_space *right_info; |
@@ -1385,7 +1392,10 @@ bool try_merge_free_space(struct btrfs_block_group_cache *block_group, | |||
1385 | left_info = tree_search_offset(block_group, offset - 1, 0, 0); | 1392 | left_info = tree_search_offset(block_group, offset - 1, 0, 0); |
1386 | 1393 | ||
1387 | if (right_info && !right_info->bitmap) { | 1394 | if (right_info && !right_info->bitmap) { |
1388 | unlink_free_space(block_group, right_info); | 1395 | if (update_stat) |
1396 | unlink_free_space(block_group, right_info); | ||
1397 | else | ||
1398 | __unlink_free_space(block_group, right_info); | ||
1389 | info->bytes += right_info->bytes; | 1399 | info->bytes += right_info->bytes; |
1390 | kfree(right_info); | 1400 | kfree(right_info); |
1391 | merged = true; | 1401 | merged = true; |
@@ -1393,7 +1403,10 @@ bool try_merge_free_space(struct btrfs_block_group_cache *block_group, | |||
1393 | 1403 | ||
1394 | if (left_info && !left_info->bitmap && | 1404 | if (left_info && !left_info->bitmap && |
1395 | left_info->offset + left_info->bytes == offset) { | 1405 | left_info->offset + left_info->bytes == offset) { |
1396 | unlink_free_space(block_group, left_info); | 1406 | if (update_stat) |
1407 | unlink_free_space(block_group, left_info); | ||
1408 | else | ||
1409 | __unlink_free_space(block_group, left_info); | ||
1397 | info->offset = left_info->offset; | 1410 | info->offset = left_info->offset; |
1398 | info->bytes += left_info->bytes; | 1411 | info->bytes += left_info->bytes; |
1399 | kfree(left_info); | 1412 | kfree(left_info); |
@@ -1418,7 +1431,7 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, | |||
1418 | 1431 | ||
1419 | spin_lock(&block_group->tree_lock); | 1432 | spin_lock(&block_group->tree_lock); |
1420 | 1433 | ||
1421 | if (try_merge_free_space(block_group, info)) | 1434 | if (try_merge_free_space(block_group, info, true)) |
1422 | goto link; | 1435 | goto link; |
1423 | 1436 | ||
1424 | /* | 1437 | /* |
@@ -1636,6 +1649,7 @@ __btrfs_return_cluster_to_free_space( | |||
1636 | node = rb_next(&entry->offset_index); | 1649 | node = rb_next(&entry->offset_index); |
1637 | rb_erase(&entry->offset_index, &cluster->root); | 1650 | rb_erase(&entry->offset_index, &cluster->root); |
1638 | BUG_ON(entry->bitmap); | 1651 | BUG_ON(entry->bitmap); |
1652 | try_merge_free_space(block_group, entry, false); | ||
1639 | tree_insert_offset(&block_group->free_space_offset, | 1653 | tree_insert_offset(&block_group->free_space_offset, |
1640 | entry->offset, &entry->offset_index, 0); | 1654 | entry->offset, &entry->offset_index, 0); |
1641 | } | 1655 | } |