diff options
author | Omar Sandoval <osandov@fb.com> | 2015-09-29 23:50:37 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-12-17 15:16:47 -0500 |
commit | 1e144fb8f4a4d6d6d88c58f87e4366e3cd02ab72 (patch) | |
tree | a6174c53f81b3f81c8944c23d835af6ac020dfc3 | |
parent | 7c55ee0c4afba4434d973117234577ae6ff77a1c (diff) |
Btrfs: wire up the free space tree to the extent tree
The free space tree is updated in tandem with the extent tree. There are
only a handful of places where we need to hook in:
1. Block group creation
2. Block group deletion
3. Delayed refs (extent creation and deletion)
4. Block group caching
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e07280c3d4f4..a4a4f593ec71 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "raid56.h" | 33 | #include "raid56.h" |
34 | #include "locking.h" | 34 | #include "locking.h" |
35 | #include "free-space-cache.h" | 35 | #include "free-space-cache.h" |
36 | #include "free-space-tree.h" | ||
36 | #include "math.h" | 37 | #include "math.h" |
37 | #include "sysfs.h" | 38 | #include "sysfs.h" |
38 | #include "qgroup.h" | 39 | #include "qgroup.h" |
@@ -518,7 +519,10 @@ static noinline void caching_thread(struct btrfs_work *work) | |||
518 | mutex_lock(&caching_ctl->mutex); | 519 | mutex_lock(&caching_ctl->mutex); |
519 | down_read(&fs_info->commit_root_sem); | 520 | down_read(&fs_info->commit_root_sem); |
520 | 521 | ||
521 | ret = load_extent_tree_free(caching_ctl); | 522 | if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) |
523 | ret = load_free_space_tree(caching_ctl); | ||
524 | else | ||
525 | ret = load_extent_tree_free(caching_ctl); | ||
522 | 526 | ||
523 | spin_lock(&block_group->lock); | 527 | spin_lock(&block_group->lock); |
524 | block_group->caching_ctl = NULL; | 528 | block_group->caching_ctl = NULL; |
@@ -624,8 +628,8 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
624 | } | 628 | } |
625 | } else { | 629 | } else { |
626 | /* | 630 | /* |
627 | * We are not going to do the fast caching, set cached to the | 631 | * We're either using the free space tree or no caching at all. |
628 | * appropriate value and wakeup any waiters. | 632 | * Set cached to the appropriate value and wakeup any waiters. |
629 | */ | 633 | */ |
630 | spin_lock(&cache->lock); | 634 | spin_lock(&cache->lock); |
631 | if (load_cache_only) { | 635 | if (load_cache_only) { |
@@ -6479,6 +6483,13 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
6479 | } | 6483 | } |
6480 | } | 6484 | } |
6481 | 6485 | ||
6486 | ret = add_to_free_space_tree(trans, root->fs_info, bytenr, | ||
6487 | num_bytes); | ||
6488 | if (ret) { | ||
6489 | btrfs_abort_transaction(trans, extent_root, ret); | ||
6490 | goto out; | ||
6491 | } | ||
6492 | |||
6482 | ret = update_block_group(trans, root, bytenr, num_bytes, 0); | 6493 | ret = update_block_group(trans, root, bytenr, num_bytes, 0); |
6483 | if (ret) { | 6494 | if (ret) { |
6484 | btrfs_abort_transaction(trans, extent_root, ret); | 6495 | btrfs_abort_transaction(trans, extent_root, ret); |
@@ -7422,6 +7433,11 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
7422 | btrfs_mark_buffer_dirty(path->nodes[0]); | 7433 | btrfs_mark_buffer_dirty(path->nodes[0]); |
7423 | btrfs_free_path(path); | 7434 | btrfs_free_path(path); |
7424 | 7435 | ||
7436 | ret = remove_from_free_space_tree(trans, fs_info, ins->objectid, | ||
7437 | ins->offset); | ||
7438 | if (ret) | ||
7439 | return ret; | ||
7440 | |||
7425 | ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); | 7441 | ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); |
7426 | if (ret) { /* -ENOENT, logic error */ | 7442 | if (ret) { /* -ENOENT, logic error */ |
7427 | btrfs_err(fs_info, "update block group failed for %llu %llu", | 7443 | btrfs_err(fs_info, "update block group failed for %llu %llu", |
@@ -7503,6 +7519,11 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
7503 | btrfs_mark_buffer_dirty(leaf); | 7519 | btrfs_mark_buffer_dirty(leaf); |
7504 | btrfs_free_path(path); | 7520 | btrfs_free_path(path); |
7505 | 7521 | ||
7522 | ret = remove_from_free_space_tree(trans, fs_info, ins->objectid, | ||
7523 | num_bytes); | ||
7524 | if (ret) | ||
7525 | return ret; | ||
7526 | |||
7506 | ret = update_block_group(trans, root, ins->objectid, root->nodesize, | 7527 | ret = update_block_group(trans, root, ins->objectid, root->nodesize, |
7507 | 1); | 7528 | 1); |
7508 | if (ret) { /* -ENOENT, logic error */ | 7529 | if (ret) { /* -ENOENT, logic error */ |
@@ -9370,6 +9391,8 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) | |||
9370 | cache->full_stripe_len = btrfs_full_stripe_len(root, | 9391 | cache->full_stripe_len = btrfs_full_stripe_len(root, |
9371 | &root->fs_info->mapping_tree, | 9392 | &root->fs_info->mapping_tree, |
9372 | start); | 9393 | start); |
9394 | set_free_space_tree_thresholds(cache); | ||
9395 | |||
9373 | atomic_set(&cache->count, 1); | 9396 | atomic_set(&cache->count, 1); |
9374 | spin_lock_init(&cache->lock); | 9397 | spin_lock_init(&cache->lock); |
9375 | init_rwsem(&cache->data_rwsem); | 9398 | init_rwsem(&cache->data_rwsem); |
@@ -9592,6 +9615,8 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, | |||
9592 | key.objectid, key.offset); | 9615 | key.objectid, key.offset); |
9593 | if (ret) | 9616 | if (ret) |
9594 | btrfs_abort_transaction(trans, extent_root, ret); | 9617 | btrfs_abort_transaction(trans, extent_root, ret); |
9618 | add_block_group_free_space(trans, root->fs_info, block_group); | ||
9619 | /* already aborted the transaction if it failed. */ | ||
9595 | next: | 9620 | next: |
9596 | list_del_init(&block_group->bg_list); | 9621 | list_del_init(&block_group->bg_list); |
9597 | } | 9622 | } |
@@ -9622,6 +9647,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
9622 | cache->flags = type; | 9647 | cache->flags = type; |
9623 | cache->last_byte_to_unpin = (u64)-1; | 9648 | cache->last_byte_to_unpin = (u64)-1; |
9624 | cache->cached = BTRFS_CACHE_FINISHED; | 9649 | cache->cached = BTRFS_CACHE_FINISHED; |
9650 | cache->needs_free_space = 1; | ||
9625 | ret = exclude_super_stripes(root, cache); | 9651 | ret = exclude_super_stripes(root, cache); |
9626 | if (ret) { | 9652 | if (ret) { |
9627 | /* | 9653 | /* |
@@ -9984,6 +10010,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
9984 | 10010 | ||
9985 | unlock_chunks(root); | 10011 | unlock_chunks(root); |
9986 | 10012 | ||
10013 | ret = remove_block_group_free_space(trans, root->fs_info, block_group); | ||
10014 | if (ret) | ||
10015 | goto out; | ||
10016 | |||
9987 | btrfs_put_block_group(block_group); | 10017 | btrfs_put_block_group(block_group); |
9988 | btrfs_put_block_group(block_group); | 10018 | btrfs_put_block_group(block_group); |
9989 | 10019 | ||