diff options
author | Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com> | 2016-07-25 03:51:39 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2016-08-25 06:58:25 -0400 |
commit | 4824f1f412f75e9f84b9cecbde828e8f4699f82d (patch) | |
tree | ba667aafa943e5db7858aadca331d4d08ba0feee | |
parent | dcb40c196fc85c6dfb28456480e5a882e26f567d (diff) |
btrfs: divide btrfs_update_reserved_bytes() into two functions
This patch divides btrfs_update_reserved_bytes() into
btrfs_add_reserved_bytes() and btrfs_free_reserved_bytes(), and
next patch will extend btrfs_add_reserved_bytes()to fix some
false ENOSPC error, please see later patch for detailed info.
Signed-off-by: Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 97 |
1 files changed, 57 insertions, 40 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d10872748c43..f1121db65878 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -104,9 +104,10 @@ static int find_next_key(struct btrfs_path *path, int level, | |||
104 | struct btrfs_key *key); | 104 | struct btrfs_key *key); |
105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, | 105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, |
106 | int dump_block_groups); | 106 | int dump_block_groups); |
107 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 107 | static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache, |
108 | u64 num_bytes, int reserve, | 108 | u64 num_bytes, int reserve, int delalloc); |
109 | int delalloc); | 109 | static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, |
110 | u64 num_bytes, int delalloc); | ||
110 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, | 111 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, |
111 | u64 num_bytes); | 112 | u64 num_bytes); |
112 | int btrfs_pin_extent(struct btrfs_root *root, | 113 | int btrfs_pin_extent(struct btrfs_root *root, |
@@ -6497,19 +6498,14 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) | |||
6497 | } | 6498 | } |
6498 | 6499 | ||
6499 | /** | 6500 | /** |
6500 | * btrfs_update_reserved_bytes - update the block_group and space info counters | 6501 | * btrfs_add_reserved_bytes - update the block_group and space info counters |
6501 | * @cache: The cache we are manipulating | 6502 | * @cache: The cache we are manipulating |
6502 | * @num_bytes: The number of bytes in question | 6503 | * @num_bytes: The number of bytes in question |
6503 | * @reserve: One of the reservation enums | 6504 | * @reserve: One of the reservation enums |
6504 | * @delalloc: The blocks are allocated for the delalloc write | 6505 | * @delalloc: The blocks are allocated for the delalloc write |
6505 | * | 6506 | * |
6506 | * This is called by the allocator when it reserves space, or by somebody who is | 6507 | * This is called by the allocator when it reserves space. Metadata |
6507 | * freeing space that was never actually used on disk. For example if you | 6508 | * reservations should be called with RESERVE_ALLOC so we do the proper |
6508 | * reserve some space for a new leaf in transaction A and before transaction A | ||
6509 | * commits you free that leaf, you call this with reserve set to 0 in order to | ||
6510 | * clear the reservation. | ||
6511 | * | ||
6512 | * Metadata reservations should be called with RESERVE_ALLOC so we do the proper | ||
6513 | * ENOSPC accounting. For data we handle the reservation through clearing the | 6509 | * ENOSPC accounting. For data we handle the reservation through clearing the |
6514 | * delalloc bits in the io_tree. We have to do this since we could end up | 6510 | * delalloc bits in the io_tree. We have to do this since we could end up |
6515 | * allocating less disk space for the amount of data we have reserved in the | 6511 | * allocating less disk space for the amount of data we have reserved in the |
@@ -6519,44 +6515,65 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) | |||
6519 | * make the reservation and return -EAGAIN, otherwise this function always | 6515 | * make the reservation and return -EAGAIN, otherwise this function always |
6520 | * succeeds. | 6516 | * succeeds. |
6521 | */ | 6517 | */ |
6522 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 6518 | static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache, |
6523 | u64 num_bytes, int reserve, int delalloc) | 6519 | u64 num_bytes, int reserve, int delalloc) |
6524 | { | 6520 | { |
6525 | struct btrfs_space_info *space_info = cache->space_info; | 6521 | struct btrfs_space_info *space_info = cache->space_info; |
6526 | int ret = 0; | 6522 | int ret = 0; |
6527 | 6523 | ||
6528 | spin_lock(&space_info->lock); | 6524 | spin_lock(&space_info->lock); |
6529 | spin_lock(&cache->lock); | 6525 | spin_lock(&cache->lock); |
6530 | if (reserve != RESERVE_FREE) { | 6526 | if (cache->ro) { |
6531 | if (cache->ro) { | 6527 | ret = -EAGAIN; |
6532 | ret = -EAGAIN; | ||
6533 | } else { | ||
6534 | cache->reserved += num_bytes; | ||
6535 | space_info->bytes_reserved += num_bytes; | ||
6536 | if (reserve == RESERVE_ALLOC) { | ||
6537 | trace_btrfs_space_reservation(cache->fs_info, | ||
6538 | "space_info", space_info->flags, | ||
6539 | num_bytes, 0); | ||
6540 | space_info->bytes_may_use -= num_bytes; | ||
6541 | } | ||
6542 | |||
6543 | if (delalloc) | ||
6544 | cache->delalloc_bytes += num_bytes; | ||
6545 | } | ||
6546 | } else { | 6528 | } else { |
6547 | if (cache->ro) | 6529 | cache->reserved += num_bytes; |
6548 | space_info->bytes_readonly += num_bytes; | 6530 | space_info->bytes_reserved += num_bytes; |
6549 | cache->reserved -= num_bytes; | 6531 | if (reserve == RESERVE_ALLOC) { |
6550 | space_info->bytes_reserved -= num_bytes; | 6532 | trace_btrfs_space_reservation(cache->fs_info, |
6533 | "space_info", space_info->flags, | ||
6534 | num_bytes, 0); | ||
6535 | space_info->bytes_may_use -= num_bytes; | ||
6536 | } | ||
6551 | 6537 | ||
6552 | if (delalloc) | 6538 | if (delalloc) |
6553 | cache->delalloc_bytes -= num_bytes; | 6539 | cache->delalloc_bytes += num_bytes; |
6554 | } | 6540 | } |
6555 | spin_unlock(&cache->lock); | 6541 | spin_unlock(&cache->lock); |
6556 | spin_unlock(&space_info->lock); | 6542 | spin_unlock(&space_info->lock); |
6557 | return ret; | 6543 | return ret; |
6558 | } | 6544 | } |
6559 | 6545 | ||
6546 | /** | ||
6547 | * btrfs_free_reserved_bytes - update the block_group and space info counters | ||
6548 | * @cache: The cache we are manipulating | ||
6549 | * @num_bytes: The number of bytes in question | ||
6550 | * @delalloc: The blocks are allocated for the delalloc write | ||
6551 | * | ||
6552 | * This is called by somebody who is freeing space that was never actually used | ||
6553 | * on disk. For example if you reserve some space for a new leaf in transaction | ||
6554 | * A and before transaction A commits you free that leaf, you call this with | ||
6555 | * reserve set to 0 in order to clear the reservation. | ||
6556 | */ | ||
6557 | |||
6558 | static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, | ||
6559 | u64 num_bytes, int delalloc) | ||
6560 | { | ||
6561 | struct btrfs_space_info *space_info = cache->space_info; | ||
6562 | int ret = 0; | ||
6563 | |||
6564 | spin_lock(&space_info->lock); | ||
6565 | spin_lock(&cache->lock); | ||
6566 | if (cache->ro) | ||
6567 | space_info->bytes_readonly += num_bytes; | ||
6568 | cache->reserved -= num_bytes; | ||
6569 | space_info->bytes_reserved -= num_bytes; | ||
6570 | |||
6571 | if (delalloc) | ||
6572 | cache->delalloc_bytes -= num_bytes; | ||
6573 | spin_unlock(&cache->lock); | ||
6574 | spin_unlock(&space_info->lock); | ||
6575 | return ret; | ||
6576 | } | ||
6560 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | 6577 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, |
6561 | struct btrfs_root *root) | 6578 | struct btrfs_root *root) |
6562 | { | 6579 | { |
@@ -7191,7 +7208,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
7191 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); | 7208 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); |
7192 | 7209 | ||
7193 | btrfs_add_free_space(cache, buf->start, buf->len); | 7210 | btrfs_add_free_space(cache, buf->start, buf->len); |
7194 | btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE, 0); | 7211 | btrfs_free_reserved_bytes(cache, buf->len, 0); |
7195 | btrfs_put_block_group(cache); | 7212 | btrfs_put_block_group(cache); |
7196 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); | 7213 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); |
7197 | pin = 0; | 7214 | pin = 0; |
@@ -7763,8 +7780,8 @@ checks: | |||
7763 | search_start - offset); | 7780 | search_start - offset); |
7764 | BUG_ON(offset > search_start); | 7781 | BUG_ON(offset > search_start); |
7765 | 7782 | ||
7766 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, | 7783 | ret = btrfs_add_reserved_bytes(block_group, num_bytes, |
7767 | alloc_type, delalloc); | 7784 | alloc_type, delalloc); |
7768 | if (ret == -EAGAIN) { | 7785 | if (ret == -EAGAIN) { |
7769 | btrfs_add_free_space(block_group, offset, num_bytes); | 7786 | btrfs_add_free_space(block_group, offset, num_bytes); |
7770 | goto loop; | 7787 | goto loop; |
@@ -7995,7 +8012,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root, | |||
7995 | if (btrfs_test_opt(root->fs_info, DISCARD)) | 8012 | if (btrfs_test_opt(root->fs_info, DISCARD)) |
7996 | ret = btrfs_discard_extent(root, start, len, NULL); | 8013 | ret = btrfs_discard_extent(root, start, len, NULL); |
7997 | btrfs_add_free_space(cache, start, len); | 8014 | btrfs_add_free_space(cache, start, len); |
7998 | btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc); | 8015 | btrfs_free_reserved_bytes(cache, len, delalloc); |
7999 | trace_btrfs_reserved_extent_free(root, start, len); | 8016 | trace_btrfs_reserved_extent_free(root, start, len); |
8000 | } | 8017 | } |
8001 | 8018 | ||
@@ -8223,8 +8240,8 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
8223 | if (!block_group) | 8240 | if (!block_group) |
8224 | return -EINVAL; | 8241 | return -EINVAL; |
8225 | 8242 | ||
8226 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, | 8243 | ret = btrfs_add_reserved_bytes(block_group, ins->offset, |
8227 | RESERVE_ALLOC_NO_ACCOUNT, 0); | 8244 | RESERVE_ALLOC_NO_ACCOUNT, 0); |
8228 | BUG_ON(ret); /* logic error */ | 8245 | BUG_ON(ret); /* logic error */ |
8229 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, | 8246 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, |
8230 | 0, owner, offset, ins, 1); | 8247 | 0, owner, offset, ins, 1); |