Skip to content

Commit 6440361

Browse files
josefbacikkdave
authored andcommitted
btrfs: rework btrfs_check_space_for_delayed_refs
Now with the delayed_refs_rsv we can now know exactly how much pending delayed refs space we need. This means we can drastically simplify btrfs_check_space_for_delayed_refs by simply checking how much space we have reserved for the global rsv (which acts as a spill over buffer) and the delayed refs rsv. If our total size is beyond that amount then we know it's time to commit the transaction and stop any more delayed refs from being generated. With the introduction of dealyed_refs_rsv infrastructure, namely btrfs_update_delayed_refs_rsv we now know exactly how much pending delayed refs space is required. Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 413df72 commit 6440361

File tree

4 files changed

+22
-34
lines changed

4 files changed

+22
-34
lines changed

fs/btrfs/ctree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2651,7 +2651,7 @@ static inline u64 btrfs_calc_trunc_metadata_size(struct btrfs_fs_info *fs_info,
26512651
}
26522652

26532653
int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans);
2654-
int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans);
2654+
bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info);
26552655
void btrfs_dec_block_group_reservations(struct btrfs_fs_info *fs_info,
26562656
const u64 start);
26572657
void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg);

fs/btrfs/extent-tree.c

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,40 +2839,28 @@ u64 btrfs_csum_bytes_to_leaves(struct btrfs_fs_info *fs_info, u64 csum_bytes)
28392839
return num_csums;
28402840
}
28412841

2842-
int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans)
2842+
bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info)
28432843
{
2844-
struct btrfs_fs_info *fs_info = trans->fs_info;
2845-
struct btrfs_block_rsv *global_rsv;
2846-
u64 num_heads = trans->transaction->delayed_refs.num_heads_ready;
2847-
u64 csum_bytes = trans->transaction->delayed_refs.pending_csums;
2848-
unsigned int num_dirty_bgs = trans->transaction->num_dirty_bgs;
2849-
u64 num_bytes, num_dirty_bgs_bytes;
2850-
int ret = 0;
2844+
struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv;
2845+
struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
2846+
bool ret = false;
2847+
u64 reserved;
28512848

2852-
num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
2853-
num_heads = heads_to_leaves(fs_info, num_heads);
2854-
if (num_heads > 1)
2855-
num_bytes += (num_heads - 1) * fs_info->nodesize;
2856-
num_bytes <<= 1;
2857-
num_bytes += btrfs_csum_bytes_to_leaves(fs_info, csum_bytes) *
2858-
fs_info->nodesize;
2859-
num_dirty_bgs_bytes = btrfs_calc_trans_metadata_size(fs_info,
2860-
num_dirty_bgs);
2861-
global_rsv = &fs_info->global_block_rsv;
2849+
spin_lock(&global_rsv->lock);
2850+
reserved = global_rsv->reserved;
2851+
spin_unlock(&global_rsv->lock);
28622852

28632853
/*
2864-
* If we can't allocate any more chunks lets make sure we have _lots_ of
2865-
* wiggle room since running delayed refs can create more delayed refs.
2854+
* Since the global reserve is just kind of magic we don't really want
2855+
* to rely on it to save our bacon, so if our size is more than the
2856+
* delayed_refs_rsv and the global rsv then it's time to think about
2857+
* bailing.
28662858
*/
2867-
if (global_rsv->space_info->full) {
2868-
num_dirty_bgs_bytes <<= 1;
2869-
num_bytes <<= 1;
2870-
}
2871-
2872-
spin_lock(&global_rsv->lock);
2873-
if (global_rsv->reserved <= num_bytes + num_dirty_bgs_bytes)
2874-
ret = 1;
2875-
spin_unlock(&global_rsv->lock);
2859+
spin_lock(&delayed_refs_rsv->lock);
2860+
reserved += delayed_refs_rsv->reserved;
2861+
if (delayed_refs_rsv->size >= reserved)
2862+
ret = true;
2863+
spin_unlock(&delayed_refs_rsv->lock);
28762864
return ret;
28772865
}
28782866

@@ -2891,7 +2879,7 @@ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans)
28912879
if (val >= NSEC_PER_SEC / 2)
28922880
return 2;
28932881

2894-
return btrfs_check_space_for_delayed_refs(trans);
2882+
return btrfs_check_space_for_delayed_refs(trans->fs_info);
28952883
}
28962884

28972885
struct async_delayed_refs {

fs/btrfs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5331,8 +5331,8 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root,
53315331
* Try to steal from the global reserve if there is space for
53325332
* it.
53335333
*/
5334-
if (!btrfs_check_space_for_delayed_refs(trans) &&
5335-
!btrfs_block_rsv_migrate(global_rsv, rsv, rsv->size, false))
5334+
if (!btrfs_check_space_for_delayed_refs(fs_info) &&
5335+
!btrfs_block_rsv_migrate(global_rsv, rsv, rsv->size, 0))
53365336
return trans;
53375337

53385338
/* If not, commit and try again. */

fs/btrfs/transaction.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ static int should_end_transaction(struct btrfs_trans_handle *trans)
789789
{
790790
struct btrfs_fs_info *fs_info = trans->fs_info;
791791

792-
if (btrfs_check_space_for_delayed_refs(trans))
792+
if (btrfs_check_space_for_delayed_refs(fs_info))
793793
return 1;
794794

795795
return !!btrfs_block_rsv_check(&fs_info->global_block_rsv, 5);

0 commit comments

Comments
 (0)