diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 229 |
1 files changed, 177 insertions, 52 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7b3089b5c2df..f619c3cb13b7 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -36,8 +36,6 @@ | |||
36 | static int update_block_group(struct btrfs_trans_handle *trans, | 36 | static int update_block_group(struct btrfs_trans_handle *trans, |
37 | struct btrfs_root *root, | 37 | struct btrfs_root *root, |
38 | u64 bytenr, u64 num_bytes, int alloc); | 38 | u64 bytenr, u64 num_bytes, int alloc); |
39 | static int update_reserved_bytes(struct btrfs_block_group_cache *cache, | ||
40 | u64 num_bytes, int reserve, int sinfo); | ||
41 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | 39 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, |
42 | struct btrfs_root *root, | 40 | struct btrfs_root *root, |
43 | u64 bytenr, u64 num_bytes, u64 parent, | 41 | u64 bytenr, u64 num_bytes, u64 parent, |
@@ -442,7 +440,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
442 | * allocate blocks for the tree root we can't do the fast caching since | 440 | * allocate blocks for the tree root we can't do the fast caching since |
443 | * we likely hold important locks. | 441 | * we likely hold important locks. |
444 | */ | 442 | */ |
445 | if (!trans->transaction->in_commit && | 443 | if (trans && (!trans->transaction->in_commit) && |
446 | (root && root != root->fs_info->tree_root)) { | 444 | (root && root != root->fs_info->tree_root)) { |
447 | spin_lock(&cache->lock); | 445 | spin_lock(&cache->lock); |
448 | if (cache->cached != BTRFS_CACHE_NO) { | 446 | if (cache->cached != BTRFS_CACHE_NO) { |
@@ -471,7 +469,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
471 | if (load_cache_only) | 469 | if (load_cache_only) |
472 | return 0; | 470 | return 0; |
473 | 471 | ||
474 | caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_KERNEL); | 472 | caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); |
475 | BUG_ON(!caching_ctl); | 473 | BUG_ON(!caching_ctl); |
476 | 474 | ||
477 | INIT_LIST_HEAD(&caching_ctl->list); | 475 | INIT_LIST_HEAD(&caching_ctl->list); |
@@ -1740,39 +1738,45 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, | |||
1740 | return ret; | 1738 | return ret; |
1741 | } | 1739 | } |
1742 | 1740 | ||
1743 | static void btrfs_issue_discard(struct block_device *bdev, | 1741 | static int btrfs_issue_discard(struct block_device *bdev, |
1744 | u64 start, u64 len) | 1742 | u64 start, u64 len) |
1745 | { | 1743 | { |
1746 | blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, 0); | 1744 | return blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_NOFS, 0); |
1747 | } | 1745 | } |
1748 | 1746 | ||
1749 | static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | 1747 | static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, |
1750 | u64 num_bytes) | 1748 | u64 num_bytes, u64 *actual_bytes) |
1751 | { | 1749 | { |
1752 | int ret; | 1750 | int ret; |
1753 | u64 map_length = num_bytes; | 1751 | u64 discarded_bytes = 0; |
1754 | struct btrfs_multi_bio *multi = NULL; | 1752 | struct btrfs_multi_bio *multi = NULL; |
1755 | 1753 | ||
1756 | if (!btrfs_test_opt(root, DISCARD)) | ||
1757 | return 0; | ||
1758 | 1754 | ||
1759 | /* Tell the block device(s) that the sectors can be discarded */ | 1755 | /* Tell the block device(s) that the sectors can be discarded */ |
1760 | ret = btrfs_map_block(&root->fs_info->mapping_tree, READ, | 1756 | ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD, |
1761 | bytenr, &map_length, &multi, 0); | 1757 | bytenr, &num_bytes, &multi, 0); |
1762 | if (!ret) { | 1758 | if (!ret) { |
1763 | struct btrfs_bio_stripe *stripe = multi->stripes; | 1759 | struct btrfs_bio_stripe *stripe = multi->stripes; |
1764 | int i; | 1760 | int i; |
1765 | 1761 | ||
1766 | if (map_length > num_bytes) | ||
1767 | map_length = num_bytes; | ||
1768 | 1762 | ||
1769 | for (i = 0; i < multi->num_stripes; i++, stripe++) { | 1763 | for (i = 0; i < multi->num_stripes; i++, stripe++) { |
1770 | btrfs_issue_discard(stripe->dev->bdev, | 1764 | ret = btrfs_issue_discard(stripe->dev->bdev, |
1771 | stripe->physical, | 1765 | stripe->physical, |
1772 | map_length); | 1766 | stripe->length); |
1767 | if (!ret) | ||
1768 | discarded_bytes += stripe->length; | ||
1769 | else if (ret != -EOPNOTSUPP) | ||
1770 | break; | ||
1773 | } | 1771 | } |
1774 | kfree(multi); | 1772 | kfree(multi); |
1775 | } | 1773 | } |
1774 | if (discarded_bytes && ret == -EOPNOTSUPP) | ||
1775 | ret = 0; | ||
1776 | |||
1777 | if (actual_bytes) | ||
1778 | *actual_bytes = discarded_bytes; | ||
1779 | |||
1776 | 1780 | ||
1777 | return ret; | 1781 | return ret; |
1778 | } | 1782 | } |
@@ -3996,6 +4000,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
3996 | struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; | 4000 | struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; |
3997 | u64 to_reserve; | 4001 | u64 to_reserve; |
3998 | int nr_extents; | 4002 | int nr_extents; |
4003 | int reserved_extents; | ||
3999 | int ret; | 4004 | int ret; |
4000 | 4005 | ||
4001 | if (btrfs_transaction_in_commit(root->fs_info)) | 4006 | if (btrfs_transaction_in_commit(root->fs_info)) |
@@ -4003,25 +4008,24 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4003 | 4008 | ||
4004 | num_bytes = ALIGN(num_bytes, root->sectorsize); | 4009 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
4005 | 4010 | ||
4006 | spin_lock(&BTRFS_I(inode)->accounting_lock); | ||
4007 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1; | 4011 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1; |
4008 | if (nr_extents > BTRFS_I(inode)->reserved_extents) { | 4012 | reserved_extents = atomic_read(&BTRFS_I(inode)->reserved_extents); |
4009 | nr_extents -= BTRFS_I(inode)->reserved_extents; | 4013 | |
4014 | if (nr_extents > reserved_extents) { | ||
4015 | nr_extents -= reserved_extents; | ||
4010 | to_reserve = calc_trans_metadata_size(root, nr_extents); | 4016 | to_reserve = calc_trans_metadata_size(root, nr_extents); |
4011 | } else { | 4017 | } else { |
4012 | nr_extents = 0; | 4018 | nr_extents = 0; |
4013 | to_reserve = 0; | 4019 | to_reserve = 0; |
4014 | } | 4020 | } |
4015 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 4021 | |
4016 | to_reserve += calc_csum_metadata_size(inode, num_bytes); | 4022 | to_reserve += calc_csum_metadata_size(inode, num_bytes); |
4017 | ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1); | 4023 | ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1); |
4018 | if (ret) | 4024 | if (ret) |
4019 | return ret; | 4025 | return ret; |
4020 | 4026 | ||
4021 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 4027 | atomic_add(nr_extents, &BTRFS_I(inode)->reserved_extents); |
4022 | BTRFS_I(inode)->reserved_extents += nr_extents; | ||
4023 | atomic_inc(&BTRFS_I(inode)->outstanding_extents); | 4028 | atomic_inc(&BTRFS_I(inode)->outstanding_extents); |
4024 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
4025 | 4029 | ||
4026 | block_rsv_add_bytes(block_rsv, to_reserve, 1); | 4030 | block_rsv_add_bytes(block_rsv, to_reserve, 1); |
4027 | 4031 | ||
@@ -4036,20 +4040,30 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) | |||
4036 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4040 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4037 | u64 to_free; | 4041 | u64 to_free; |
4038 | int nr_extents; | 4042 | int nr_extents; |
4043 | int reserved_extents; | ||
4039 | 4044 | ||
4040 | num_bytes = ALIGN(num_bytes, root->sectorsize); | 4045 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
4041 | atomic_dec(&BTRFS_I(inode)->outstanding_extents); | 4046 | atomic_dec(&BTRFS_I(inode)->outstanding_extents); |
4042 | WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0); | 4047 | WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0); |
4043 | 4048 | ||
4044 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 4049 | reserved_extents = atomic_read(&BTRFS_I(inode)->reserved_extents); |
4045 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents); | 4050 | do { |
4046 | if (nr_extents < BTRFS_I(inode)->reserved_extents) { | 4051 | int old, new; |
4047 | nr_extents = BTRFS_I(inode)->reserved_extents - nr_extents; | 4052 | |
4048 | BTRFS_I(inode)->reserved_extents -= nr_extents; | 4053 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents); |
4049 | } else { | 4054 | if (nr_extents >= reserved_extents) { |
4050 | nr_extents = 0; | 4055 | nr_extents = 0; |
4051 | } | 4056 | break; |
4052 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 4057 | } |
4058 | old = reserved_extents; | ||
4059 | nr_extents = reserved_extents - nr_extents; | ||
4060 | new = reserved_extents - nr_extents; | ||
4061 | old = atomic_cmpxchg(&BTRFS_I(inode)->reserved_extents, | ||
4062 | reserved_extents, new); | ||
4063 | if (likely(old == reserved_extents)) | ||
4064 | break; | ||
4065 | reserved_extents = old; | ||
4066 | } while (1); | ||
4053 | 4067 | ||
4054 | to_free = calc_csum_metadata_size(inode, num_bytes); | 4068 | to_free = calc_csum_metadata_size(inode, num_bytes); |
4055 | if (nr_extents > 0) | 4069 | if (nr_extents > 0) |
@@ -4223,8 +4237,8 @@ int btrfs_pin_extent(struct btrfs_root *root, | |||
4223 | * update size of reserved extents. this function may return -EAGAIN | 4237 | * update size of reserved extents. this function may return -EAGAIN |
4224 | * if 'reserve' is true or 'sinfo' is false. | 4238 | * if 'reserve' is true or 'sinfo' is false. |
4225 | */ | 4239 | */ |
4226 | static int update_reserved_bytes(struct btrfs_block_group_cache *cache, | 4240 | int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, |
4227 | u64 num_bytes, int reserve, int sinfo) | 4241 | u64 num_bytes, int reserve, int sinfo) |
4228 | { | 4242 | { |
4229 | int ret = 0; | 4243 | int ret = 0; |
4230 | if (sinfo) { | 4244 | if (sinfo) { |
@@ -4363,7 +4377,9 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
4363 | if (ret) | 4377 | if (ret) |
4364 | break; | 4378 | break; |
4365 | 4379 | ||
4366 | ret = btrfs_discard_extent(root, start, end + 1 - start); | 4380 | if (btrfs_test_opt(root, DISCARD)) |
4381 | ret = btrfs_discard_extent(root, start, | ||
4382 | end + 1 - start, NULL); | ||
4367 | 4383 | ||
4368 | clear_extent_dirty(unpin, start, end, GFP_NOFS); | 4384 | clear_extent_dirty(unpin, start, end, GFP_NOFS); |
4369 | unpin_extent_range(root, start, end); | 4385 | unpin_extent_range(root, start, end); |
@@ -4704,10 +4720,10 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
4704 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); | 4720 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); |
4705 | 4721 | ||
4706 | btrfs_add_free_space(cache, buf->start, buf->len); | 4722 | btrfs_add_free_space(cache, buf->start, buf->len); |
4707 | ret = update_reserved_bytes(cache, buf->len, 0, 0); | 4723 | ret = btrfs_update_reserved_bytes(cache, buf->len, 0, 0); |
4708 | if (ret == -EAGAIN) { | 4724 | if (ret == -EAGAIN) { |
4709 | /* block group became read-only */ | 4725 | /* block group became read-only */ |
4710 | update_reserved_bytes(cache, buf->len, 0, 1); | 4726 | btrfs_update_reserved_bytes(cache, buf->len, 0, 1); |
4711 | goto out; | 4727 | goto out; |
4712 | } | 4728 | } |
4713 | 4729 | ||
@@ -4744,6 +4760,11 @@ pin: | |||
4744 | } | 4760 | } |
4745 | } | 4761 | } |
4746 | out: | 4762 | out: |
4763 | /* | ||
4764 | * Deleting the buffer, clear the corrupt flag since it doesn't matter | ||
4765 | * anymore. | ||
4766 | */ | ||
4767 | clear_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags); | ||
4747 | btrfs_put_block_group(cache); | 4768 | btrfs_put_block_group(cache); |
4748 | } | 4769 | } |
4749 | 4770 | ||
@@ -5191,7 +5212,7 @@ checks: | |||
5191 | search_start - offset); | 5212 | search_start - offset); |
5192 | BUG_ON(offset > search_start); | 5213 | BUG_ON(offset > search_start); |
5193 | 5214 | ||
5194 | ret = update_reserved_bytes(block_group, num_bytes, 1, | 5215 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, 1, |
5195 | (data & BTRFS_BLOCK_GROUP_DATA)); | 5216 | (data & BTRFS_BLOCK_GROUP_DATA)); |
5196 | if (ret == -EAGAIN) { | 5217 | if (ret == -EAGAIN) { |
5197 | btrfs_add_free_space(block_group, offset, num_bytes); | 5218 | btrfs_add_free_space(block_group, offset, num_bytes); |
@@ -5397,6 +5418,8 @@ again: | |||
5397 | dump_space_info(sinfo, num_bytes, 1); | 5418 | dump_space_info(sinfo, num_bytes, 1); |
5398 | } | 5419 | } |
5399 | 5420 | ||
5421 | trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); | ||
5422 | |||
5400 | return ret; | 5423 | return ret; |
5401 | } | 5424 | } |
5402 | 5425 | ||
@@ -5412,12 +5435,15 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len) | |||
5412 | return -ENOSPC; | 5435 | return -ENOSPC; |
5413 | } | 5436 | } |
5414 | 5437 | ||
5415 | ret = btrfs_discard_extent(root, start, len); | 5438 | if (btrfs_test_opt(root, DISCARD)) |
5439 | ret = btrfs_discard_extent(root, start, len, NULL); | ||
5416 | 5440 | ||
5417 | btrfs_add_free_space(cache, start, len); | 5441 | btrfs_add_free_space(cache, start, len); |
5418 | update_reserved_bytes(cache, len, 0, 1); | 5442 | btrfs_update_reserved_bytes(cache, len, 0, 1); |
5419 | btrfs_put_block_group(cache); | 5443 | btrfs_put_block_group(cache); |
5420 | 5444 | ||
5445 | trace_btrfs_reserved_extent_free(root, start, len); | ||
5446 | |||
5421 | return ret; | 5447 | return ret; |
5422 | } | 5448 | } |
5423 | 5449 | ||
@@ -5444,7 +5470,8 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
5444 | size = sizeof(*extent_item) + btrfs_extent_inline_ref_size(type); | 5470 | size = sizeof(*extent_item) + btrfs_extent_inline_ref_size(type); |
5445 | 5471 | ||
5446 | path = btrfs_alloc_path(); | 5472 | path = btrfs_alloc_path(); |
5447 | BUG_ON(!path); | 5473 | if (!path) |
5474 | return -ENOMEM; | ||
5448 | 5475 | ||
5449 | path->leave_spinning = 1; | 5476 | path->leave_spinning = 1; |
5450 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, | 5477 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, |
@@ -5614,7 +5641,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
5614 | put_caching_control(caching_ctl); | 5641 | put_caching_control(caching_ctl); |
5615 | } | 5642 | } |
5616 | 5643 | ||
5617 | ret = update_reserved_bytes(block_group, ins->offset, 1, 1); | 5644 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, 1, 1); |
5618 | BUG_ON(ret); | 5645 | BUG_ON(ret); |
5619 | btrfs_put_block_group(block_group); | 5646 | btrfs_put_block_group(block_group); |
5620 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, | 5647 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, |
@@ -6047,6 +6074,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
6047 | if (reada && level == 1) | 6074 | if (reada && level == 1) |
6048 | reada_walk_down(trans, root, wc, path); | 6075 | reada_walk_down(trans, root, wc, path); |
6049 | next = read_tree_block(root, bytenr, blocksize, generation); | 6076 | next = read_tree_block(root, bytenr, blocksize, generation); |
6077 | if (!next) | ||
6078 | return -EIO; | ||
6050 | btrfs_tree_lock(next); | 6079 | btrfs_tree_lock(next); |
6051 | btrfs_set_lock_blocking(next); | 6080 | btrfs_set_lock_blocking(next); |
6052 | } | 6081 | } |
@@ -6438,10 +6467,14 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
6438 | BUG_ON(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID); | 6467 | BUG_ON(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID); |
6439 | 6468 | ||
6440 | path = btrfs_alloc_path(); | 6469 | path = btrfs_alloc_path(); |
6441 | BUG_ON(!path); | 6470 | if (!path) |
6471 | return -ENOMEM; | ||
6442 | 6472 | ||
6443 | wc = kzalloc(sizeof(*wc), GFP_NOFS); | 6473 | wc = kzalloc(sizeof(*wc), GFP_NOFS); |
6444 | BUG_ON(!wc); | 6474 | if (!wc) { |
6475 | btrfs_free_path(path); | ||
6476 | return -ENOMEM; | ||
6477 | } | ||
6445 | 6478 | ||
6446 | btrfs_assert_tree_locked(parent); | 6479 | btrfs_assert_tree_locked(parent); |
6447 | parent_level = btrfs_header_level(parent); | 6480 | parent_level = btrfs_header_level(parent); |
@@ -6899,7 +6932,11 @@ static noinline int get_new_locations(struct inode *reloc_inode, | |||
6899 | } | 6932 | } |
6900 | 6933 | ||
6901 | path = btrfs_alloc_path(); | 6934 | path = btrfs_alloc_path(); |
6902 | BUG_ON(!path); | 6935 | if (!path) { |
6936 | if (exts != *extents) | ||
6937 | kfree(exts); | ||
6938 | return -ENOMEM; | ||
6939 | } | ||
6903 | 6940 | ||
6904 | cur_pos = extent_key->objectid - offset; | 6941 | cur_pos = extent_key->objectid - offset; |
6905 | last_byte = extent_key->objectid + extent_key->offset; | 6942 | last_byte = extent_key->objectid + extent_key->offset; |
@@ -6941,6 +6978,10 @@ static noinline int get_new_locations(struct inode *reloc_inode, | |||
6941 | struct disk_extent *old = exts; | 6978 | struct disk_extent *old = exts; |
6942 | max *= 2; | 6979 | max *= 2; |
6943 | exts = kzalloc(sizeof(*exts) * max, GFP_NOFS); | 6980 | exts = kzalloc(sizeof(*exts) * max, GFP_NOFS); |
6981 | if (!exts) { | ||
6982 | ret = -ENOMEM; | ||
6983 | goto out; | ||
6984 | } | ||
6944 | memcpy(exts, old, sizeof(*exts) * nr); | 6985 | memcpy(exts, old, sizeof(*exts) * nr); |
6945 | if (old != *extents) | 6986 | if (old != *extents) |
6946 | kfree(old); | 6987 | kfree(old); |
@@ -7423,7 +7464,8 @@ static noinline int replace_extents_in_leaf(struct btrfs_trans_handle *trans, | |||
7423 | int ret; | 7464 | int ret; |
7424 | 7465 | ||
7425 | new_extent = kmalloc(sizeof(*new_extent), GFP_NOFS); | 7466 | new_extent = kmalloc(sizeof(*new_extent), GFP_NOFS); |
7426 | BUG_ON(!new_extent); | 7467 | if (!new_extent) |
7468 | return -ENOMEM; | ||
7427 | 7469 | ||
7428 | ref = btrfs_lookup_leaf_ref(root, leaf->start); | 7470 | ref = btrfs_lookup_leaf_ref(root, leaf->start); |
7429 | BUG_ON(!ref); | 7471 | BUG_ON(!ref); |
@@ -7609,7 +7651,8 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root) | |||
7609 | 7651 | ||
7610 | reloc_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | 7652 | reloc_root = btrfs_read_fs_root_no_name(root->fs_info, &location); |
7611 | BUG_ON(!reloc_root); | 7653 | BUG_ON(!reloc_root); |
7612 | btrfs_orphan_cleanup(reloc_root); | 7654 | ret = btrfs_orphan_cleanup(reloc_root); |
7655 | BUG_ON(ret); | ||
7613 | return 0; | 7656 | return 0; |
7614 | } | 7657 | } |
7615 | 7658 | ||
@@ -7627,7 +7670,8 @@ static noinline int init_reloc_tree(struct btrfs_trans_handle *trans, | |||
7627 | return 0; | 7670 | return 0; |
7628 | 7671 | ||
7629 | root_item = kmalloc(sizeof(*root_item), GFP_NOFS); | 7672 | root_item = kmalloc(sizeof(*root_item), GFP_NOFS); |
7630 | BUG_ON(!root_item); | 7673 | if (!root_item) |
7674 | return -ENOMEM; | ||
7631 | 7675 | ||
7632 | ret = btrfs_copy_root(trans, root, root->commit_root, | 7676 | ret = btrfs_copy_root(trans, root, root->commit_root, |
7633 | &eb, BTRFS_TREE_RELOC_OBJECTID); | 7677 | &eb, BTRFS_TREE_RELOC_OBJECTID); |
@@ -7653,7 +7697,7 @@ static noinline int init_reloc_tree(struct btrfs_trans_handle *trans, | |||
7653 | 7697 | ||
7654 | reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root, | 7698 | reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root, |
7655 | &root_key); | 7699 | &root_key); |
7656 | BUG_ON(!reloc_root); | 7700 | BUG_ON(IS_ERR(reloc_root)); |
7657 | reloc_root->last_trans = trans->transid; | 7701 | reloc_root->last_trans = trans->transid; |
7658 | reloc_root->commit_root = NULL; | 7702 | reloc_root->commit_root = NULL; |
7659 | reloc_root->ref_tree = &root->fs_info->reloc_ref_tree; | 7703 | reloc_root->ref_tree = &root->fs_info->reloc_ref_tree; |
@@ -7906,6 +7950,10 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, | |||
7906 | 7950 | ||
7907 | eb = read_tree_block(found_root, block_start, | 7951 | eb = read_tree_block(found_root, block_start, |
7908 | block_size, 0); | 7952 | block_size, 0); |
7953 | if (!eb) { | ||
7954 | ret = -EIO; | ||
7955 | goto out; | ||
7956 | } | ||
7909 | btrfs_tree_lock(eb); | 7957 | btrfs_tree_lock(eb); |
7910 | BUG_ON(level != btrfs_header_level(eb)); | 7958 | BUG_ON(level != btrfs_header_level(eb)); |
7911 | 7959 | ||
@@ -8621,6 +8669,12 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
8621 | BUG_ON(!block_group); | 8669 | BUG_ON(!block_group); |
8622 | BUG_ON(!block_group->ro); | 8670 | BUG_ON(!block_group->ro); |
8623 | 8671 | ||
8672 | /* | ||
8673 | * Free the reserved super bytes from this block group before | ||
8674 | * remove it. | ||
8675 | */ | ||
8676 | free_excluded_extents(root, block_group); | ||
8677 | |||
8624 | memcpy(&key, &block_group->key, sizeof(key)); | 8678 | memcpy(&key, &block_group->key, sizeof(key)); |
8625 | if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP | | 8679 | if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP | |
8626 | BTRFS_BLOCK_GROUP_RAID1 | | 8680 | BTRFS_BLOCK_GROUP_RAID1 | |
@@ -8724,13 +8778,84 @@ out: | |||
8724 | return ret; | 8778 | return ret; |
8725 | } | 8779 | } |
8726 | 8780 | ||
8781 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info) | ||
8782 | { | ||
8783 | struct btrfs_space_info *space_info; | ||
8784 | int ret; | ||
8785 | |||
8786 | ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, | ||
8787 | &space_info); | ||
8788 | if (ret) | ||
8789 | return ret; | ||
8790 | |||
8791 | ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, | ||
8792 | &space_info); | ||
8793 | if (ret) | ||
8794 | return ret; | ||
8795 | |||
8796 | ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, | ||
8797 | &space_info); | ||
8798 | if (ret) | ||
8799 | return ret; | ||
8800 | |||
8801 | return ret; | ||
8802 | } | ||
8803 | |||
8727 | int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) | 8804 | int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) |
8728 | { | 8805 | { |
8729 | return unpin_extent_range(root, start, end); | 8806 | return unpin_extent_range(root, start, end); |
8730 | } | 8807 | } |
8731 | 8808 | ||
8732 | int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, | 8809 | int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, |
8733 | u64 num_bytes) | 8810 | u64 num_bytes, u64 *actual_bytes) |
8811 | { | ||
8812 | return btrfs_discard_extent(root, bytenr, num_bytes, actual_bytes); | ||
8813 | } | ||
8814 | |||
8815 | int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) | ||
8734 | { | 8816 | { |
8735 | return btrfs_discard_extent(root, bytenr, num_bytes); | 8817 | struct btrfs_fs_info *fs_info = root->fs_info; |
8818 | struct btrfs_block_group_cache *cache = NULL; | ||
8819 | u64 group_trimmed; | ||
8820 | u64 start; | ||
8821 | u64 end; | ||
8822 | u64 trimmed = 0; | ||
8823 | int ret = 0; | ||
8824 | |||
8825 | cache = btrfs_lookup_block_group(fs_info, range->start); | ||
8826 | |||
8827 | while (cache) { | ||
8828 | if (cache->key.objectid >= (range->start + range->len)) { | ||
8829 | btrfs_put_block_group(cache); | ||
8830 | break; | ||
8831 | } | ||
8832 | |||
8833 | start = max(range->start, cache->key.objectid); | ||
8834 | end = min(range->start + range->len, | ||
8835 | cache->key.objectid + cache->key.offset); | ||
8836 | |||
8837 | if (end - start >= range->minlen) { | ||
8838 | if (!block_group_cache_done(cache)) { | ||
8839 | ret = cache_block_group(cache, NULL, root, 0); | ||
8840 | if (!ret) | ||
8841 | wait_block_group_cache_done(cache); | ||
8842 | } | ||
8843 | ret = btrfs_trim_block_group(cache, | ||
8844 | &group_trimmed, | ||
8845 | start, | ||
8846 | end, | ||
8847 | range->minlen); | ||
8848 | |||
8849 | trimmed += group_trimmed; | ||
8850 | if (ret) { | ||
8851 | btrfs_put_block_group(cache); | ||
8852 | break; | ||
8853 | } | ||
8854 | } | ||
8855 | |||
8856 | cache = next_block_group(fs_info->tree_root, cache); | ||
8857 | } | ||
8858 | |||
8859 | range->len = trimmed; | ||
8860 | return ret; | ||
8736 | } | 8861 | } |