aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2010-11-09 01:57:39 -0500
committerLi Zefan <lizf@cn.fujitsu.com>2011-01-26 12:04:57 -0500
commitf333adb5d64bc1c4d6099072fc341c3c8f84e0cf (patch)
treeabf1c214113a9c2dec3d42a9e0ee14e1863fe0a1 /fs
parent120d66eec0dcb966fbd03f743598b2ff2513436b (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')
-rw-r--r--fs/btrfs/free-space-cache.c26
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
990static void unlink_free_space(struct btrfs_block_group_cache *block_group, 990static 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
998static 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
1366bool try_merge_free_space(struct btrfs_block_group_cache *block_group, 1373bool 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 }