Commit 4824f1f4 authored by Wang Xiaoguang's avatar Wang Xiaoguang Committed by Chris Mason

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: default avatarWang Xiaoguang <wangxg.fnst@cn.fujitsu.com>
Reviewed-by: default avatarJosef Bacik <jbacik@fb.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent dcb40c19
...@@ -104,9 +104,10 @@ static int find_next_key(struct btrfs_path *path, int level, ...@@ -104,9 +104,10 @@ static int find_next_key(struct btrfs_path *path, int level,
struct btrfs_key *key); struct btrfs_key *key);
static void dump_space_info(struct btrfs_space_info *info, u64 bytes, static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
int dump_block_groups); int dump_block_groups);
static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache,
u64 num_bytes, int reserve, u64 num_bytes, int reserve, int delalloc);
int delalloc); static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache,
u64 num_bytes, int delalloc);
static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv,
u64 num_bytes); u64 num_bytes);
int btrfs_pin_extent(struct btrfs_root *root, 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,19 +6498,14 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg)
} }
/** /**
* btrfs_update_reserved_bytes - update the block_group and space info counters * btrfs_add_reserved_bytes - update the block_group and space info counters
* @cache: The cache we are manipulating * @cache: The cache we are manipulating
* @num_bytes: The number of bytes in question * @num_bytes: The number of bytes in question
* @reserve: One of the reservation enums * @reserve: One of the reservation enums
* @delalloc: The blocks are allocated for the delalloc write * @delalloc: The blocks are allocated for the delalloc write
* *
* This is called by the allocator when it reserves space, or by somebody who is * This is called by the allocator when it reserves space. Metadata
* freeing space that was never actually used on disk. For example if you * reservations should be called with RESERVE_ALLOC so we do the proper
* reserve some space for a new leaf in transaction A and before transaction A
* commits you free that leaf, you call this with reserve set to 0 in order to
* clear the reservation.
*
* Metadata reservations should be called with RESERVE_ALLOC so we do the proper
* ENOSPC accounting. For data we handle the reservation through clearing the * ENOSPC accounting. For data we handle the reservation through clearing the
* delalloc bits in the io_tree. We have to do this since we could end up * delalloc bits in the io_tree. We have to do this since we could end up
* allocating less disk space for the amount of data we have reserved in the * allocating less disk space for the amount of data we have reserved in the
...@@ -6519,7 +6515,7 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) ...@@ -6519,7 +6515,7 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg)
* make the reservation and return -EAGAIN, otherwise this function always * make the reservation and return -EAGAIN, otherwise this function always
* succeeds. * succeeds.
*/ */
static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache,
u64 num_bytes, int reserve, int delalloc) u64 num_bytes, int reserve, int delalloc)
{ {
struct btrfs_space_info *space_info = cache->space_info; struct btrfs_space_info *space_info = cache->space_info;
...@@ -6527,7 +6523,6 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, ...@@ -6527,7 +6523,6 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
spin_lock(&space_info->lock); spin_lock(&space_info->lock);
spin_lock(&cache->lock); spin_lock(&cache->lock);
if (reserve != RESERVE_FREE) {
if (cache->ro) { if (cache->ro) {
ret = -EAGAIN; ret = -EAGAIN;
} else { } else {
...@@ -6543,7 +6538,31 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, ...@@ -6543,7 +6538,31 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
if (delalloc) if (delalloc)
cache->delalloc_bytes += num_bytes; cache->delalloc_bytes += num_bytes;
} }
} else { spin_unlock(&cache->lock);
spin_unlock(&space_info->lock);
return ret;
}
/**
* btrfs_free_reserved_bytes - update the block_group and space info counters
* @cache: The cache we are manipulating
* @num_bytes: The number of bytes in question
* @delalloc: The blocks are allocated for the delalloc write
*
* This is called by somebody who is freeing space that was never actually used
* on disk. For example if you reserve some space for a new leaf in transaction
* A and before transaction A commits you free that leaf, you call this with
* reserve set to 0 in order to clear the reservation.
*/
static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache,
u64 num_bytes, int delalloc)
{
struct btrfs_space_info *space_info = cache->space_info;
int ret = 0;
spin_lock(&space_info->lock);
spin_lock(&cache->lock);
if (cache->ro) if (cache->ro)
space_info->bytes_readonly += num_bytes; space_info->bytes_readonly += num_bytes;
cache->reserved -= num_bytes; cache->reserved -= num_bytes;
...@@ -6551,12 +6570,10 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, ...@@ -6551,12 +6570,10 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
if (delalloc) if (delalloc)
cache->delalloc_bytes -= num_bytes; cache->delalloc_bytes -= num_bytes;
}
spin_unlock(&cache->lock); spin_unlock(&cache->lock);
spin_unlock(&space_info->lock); spin_unlock(&space_info->lock);
return ret; return ret;
} }
void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
struct btrfs_root *root) struct btrfs_root *root)
{ {
...@@ -7191,7 +7208,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, ...@@ -7191,7 +7208,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags));
btrfs_add_free_space(cache, buf->start, buf->len); btrfs_add_free_space(cache, buf->start, buf->len);
btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE, 0); btrfs_free_reserved_bytes(cache, buf->len, 0);
btrfs_put_block_group(cache); btrfs_put_block_group(cache);
trace_btrfs_reserved_extent_free(root, buf->start, buf->len); trace_btrfs_reserved_extent_free(root, buf->start, buf->len);
pin = 0; pin = 0;
...@@ -7763,7 +7780,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, ...@@ -7763,7 +7780,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
search_start - offset); search_start - offset);
BUG_ON(offset > search_start); BUG_ON(offset > search_start);
ret = btrfs_update_reserved_bytes(block_group, num_bytes, ret = btrfs_add_reserved_bytes(block_group, num_bytes,
alloc_type, delalloc); alloc_type, delalloc);
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
btrfs_add_free_space(block_group, offset, num_bytes); btrfs_add_free_space(block_group, offset, num_bytes);
...@@ -7995,7 +8012,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root, ...@@ -7995,7 +8012,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root,
if (btrfs_test_opt(root->fs_info, DISCARD)) if (btrfs_test_opt(root->fs_info, DISCARD))
ret = btrfs_discard_extent(root, start, len, NULL); ret = btrfs_discard_extent(root, start, len, NULL);
btrfs_add_free_space(cache, start, len); btrfs_add_free_space(cache, start, len);
btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc); btrfs_free_reserved_bytes(cache, len, delalloc);
trace_btrfs_reserved_extent_free(root, start, len); trace_btrfs_reserved_extent_free(root, start, len);
} }
...@@ -8223,7 +8240,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, ...@@ -8223,7 +8240,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
if (!block_group) if (!block_group)
return -EINVAL; return -EINVAL;
ret = btrfs_update_reserved_bytes(block_group, ins->offset, ret = btrfs_add_reserved_bytes(block_group, ins->offset,
RESERVE_ALLOC_NO_ACCOUNT, 0); RESERVE_ALLOC_NO_ACCOUNT, 0);
BUG_ON(ret); /* logic error */ BUG_ON(ret); /* logic error */
ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment