Skip to content

Commit

Permalink
Btrfs: reserve space for block groups
Browse files Browse the repository at this point in the history
This changes our delayed refs calculations to include the space needed
to write back dirty block groups.

Signed-off-by: Chris Mason <clm@fb.com>
  • Loading branch information
Josef Bacik authored and Chris Mason committed Apr 10, 2015
1 parent 28f75a0 commit cb723e4
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 3 deletions.
12 changes: 9 additions & 3 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2657,7 +2657,8 @@ int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans,
struct btrfs_block_rsv *global_rsv;
u64 num_heads = trans->transaction->delayed_refs.num_heads_ready;
u64 csum_bytes = trans->transaction->delayed_refs.pending_csums;
u64 num_bytes;
u64 num_dirty_bgs = trans->transaction->num_dirty_bgs;
u64 num_bytes, num_dirty_bgs_bytes;
int ret = 0;

num_bytes = btrfs_calc_trans_metadata_size(root, 1);
Expand All @@ -2666,17 +2667,21 @@ int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans,
num_bytes += (num_heads - 1) * root->nodesize;
num_bytes <<= 1;
num_bytes += btrfs_csum_bytes_to_leaves(root, csum_bytes) * root->nodesize;
num_dirty_bgs_bytes = btrfs_calc_trans_metadata_size(root,
num_dirty_bgs);
global_rsv = &root->fs_info->global_block_rsv;

/*
* If we can't allocate any more chunks lets make sure we have _lots_ of
* wiggle room since running delayed refs can create more delayed refs.
*/
if (global_rsv->space_info->full)
if (global_rsv->space_info->full) {
num_dirty_bgs_bytes <<= 1;
num_bytes <<= 1;
}

spin_lock(&global_rsv->lock);
if (global_rsv->reserved <= num_bytes)
if (global_rsv->reserved <= num_bytes + num_dirty_bgs_bytes)
ret = 1;
spin_unlock(&global_rsv->lock);
return ret;
Expand Down Expand Up @@ -5408,6 +5413,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
if (list_empty(&cache->dirty_list)) {
list_add_tail(&cache->dirty_list,
&trans->transaction->dirty_bgs);
trans->transaction->num_dirty_bgs++;
btrfs_get_block_group(cache);
}
spin_unlock(&trans->transaction->dirty_bgs_lock);
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ static noinline int join_transaction(struct btrfs_root *root, unsigned int type)
INIT_LIST_HEAD(&cur_trans->switch_commits);
INIT_LIST_HEAD(&cur_trans->pending_ordered);
INIT_LIST_HEAD(&cur_trans->dirty_bgs);
cur_trans->num_dirty_bgs = 0;
spin_lock_init(&cur_trans->dirty_bgs_lock);
list_add_tail(&cur_trans->list, &fs_info->trans_list);
extent_io_tree_init(&cur_trans->dirty_pages,
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct btrfs_transaction {
struct list_head pending_ordered;
struct list_head switch_commits;
struct list_head dirty_bgs;
u64 num_dirty_bgs;
spinlock_t dirty_bgs_lock;
struct btrfs_delayed_ref_root delayed_refs;
int aborted;
Expand Down

0 comments on commit cb723e4

Please sign in to comment.