Skip to content

Commit 4d20c1d

Browse files
fdmananakdave
authored andcommitted
btrfs: remove pointless loop from btrfs_update_block_group()
When an extent is allocated or freed, we call btrfs_update_block_group() to update its block group and space info. An extent always belongs to a single block group, it can never span multiple block groups, so the loop we have at btrfs_update_block_group() is pointless, as it always has a single iteration. The loop was added in the very early days, 2007, when the block group code was added in commit 9078a3e ("Btrfs: start of block group code"), but even back then it seemed pointless. So remove the loop and assert the block group containing the start offset of the extent also contains the whole extent. Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 4ebe8d4 commit 4d20c1d

File tree

1 file changed

+67
-80
lines changed

1 file changed

+67
-80
lines changed

fs/btrfs/block-group.c

Lines changed: 67 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3542,12 +3542,11 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
35423542
u64 bytenr, u64 num_bytes, bool alloc)
35433543
{
35443544
struct btrfs_fs_info *info = trans->fs_info;
3545-
struct btrfs_block_group *cache = NULL;
3546-
u64 total = num_bytes;
3545+
struct btrfs_space_info *space_info;
3546+
struct btrfs_block_group *cache;
35473547
u64 old_val;
3548-
u64 byte_in_group;
3548+
bool reclaim = false;
35493549
int factor;
3550-
int ret = 0;
35513550

35523551
/* Block accounting for super block */
35533552
spin_lock(&info->delalloc_root_lock);
@@ -3559,97 +3558,85 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
35593558
btrfs_set_super_bytes_used(info->super_copy, old_val);
35603559
spin_unlock(&info->delalloc_root_lock);
35613560

3562-
while (total) {
3563-
struct btrfs_space_info *space_info;
3564-
bool reclaim = false;
3565-
3566-
cache = btrfs_lookup_block_group(info, bytenr);
3567-
if (!cache) {
3568-
ret = -ENOENT;
3569-
break;
3570-
}
3571-
space_info = cache->space_info;
3572-
factor = btrfs_bg_type_to_factor(cache->flags);
3561+
cache = btrfs_lookup_block_group(info, bytenr);
3562+
if (!cache)
3563+
return -ENOENT;
35733564

3574-
/*
3575-
* If this block group has free space cache written out, we
3576-
* need to make sure to load it if we are removing space. This
3577-
* is because we need the unpinning stage to actually add the
3578-
* space back to the block group, otherwise we will leak space.
3579-
*/
3580-
if (!alloc && !btrfs_block_group_done(cache))
3581-
btrfs_cache_block_group(cache, true);
3565+
/* An extent can not span multiple block groups. */
3566+
ASSERT(bytenr + num_bytes <= cache->start + cache->length);
35823567

3583-
byte_in_group = bytenr - cache->start;
3584-
WARN_ON(byte_in_group > cache->length);
3568+
space_info = cache->space_info;
3569+
factor = btrfs_bg_type_to_factor(cache->flags);
35853570

3586-
spin_lock(&space_info->lock);
3587-
spin_lock(&cache->lock);
3571+
/*
3572+
* If this block group has free space cache written out, we need to make
3573+
* sure to load it if we are removing space. This is because we need
3574+
* the unpinning stage to actually add the space back to the block group,
3575+
* otherwise we will leak space.
3576+
*/
3577+
if (!alloc && !btrfs_block_group_done(cache))
3578+
btrfs_cache_block_group(cache, true);
35883579

3589-
if (btrfs_test_opt(info, SPACE_CACHE) &&
3590-
cache->disk_cache_state < BTRFS_DC_CLEAR)
3591-
cache->disk_cache_state = BTRFS_DC_CLEAR;
3580+
spin_lock(&space_info->lock);
3581+
spin_lock(&cache->lock);
35923582

3593-
old_val = cache->used;
3594-
num_bytes = min(total, cache->length - byte_in_group);
3595-
if (alloc) {
3596-
old_val += num_bytes;
3597-
cache->used = old_val;
3598-
cache->reserved -= num_bytes;
3599-
space_info->bytes_reserved -= num_bytes;
3600-
space_info->bytes_used += num_bytes;
3601-
space_info->disk_used += num_bytes * factor;
3602-
spin_unlock(&cache->lock);
3603-
spin_unlock(&space_info->lock);
3604-
} else {
3605-
old_val -= num_bytes;
3606-
cache->used = old_val;
3607-
cache->pinned += num_bytes;
3608-
btrfs_space_info_update_bytes_pinned(info, space_info,
3609-
num_bytes);
3610-
space_info->bytes_used -= num_bytes;
3611-
space_info->disk_used -= num_bytes * factor;
3583+
if (btrfs_test_opt(info, SPACE_CACHE) &&
3584+
cache->disk_cache_state < BTRFS_DC_CLEAR)
3585+
cache->disk_cache_state = BTRFS_DC_CLEAR;
36123586

3613-
reclaim = should_reclaim_block_group(cache, num_bytes);
3587+
old_val = cache->used;
3588+
if (alloc) {
3589+
old_val += num_bytes;
3590+
cache->used = old_val;
3591+
cache->reserved -= num_bytes;
3592+
space_info->bytes_reserved -= num_bytes;
3593+
space_info->bytes_used += num_bytes;
3594+
space_info->disk_used += num_bytes * factor;
3595+
spin_unlock(&cache->lock);
3596+
spin_unlock(&space_info->lock);
3597+
} else {
3598+
old_val -= num_bytes;
3599+
cache->used = old_val;
3600+
cache->pinned += num_bytes;
3601+
btrfs_space_info_update_bytes_pinned(info, space_info, num_bytes);
3602+
space_info->bytes_used -= num_bytes;
3603+
space_info->disk_used -= num_bytes * factor;
36143604

3615-
spin_unlock(&cache->lock);
3616-
spin_unlock(&space_info->lock);
3605+
reclaim = should_reclaim_block_group(cache, num_bytes);
36173606

3618-
set_extent_bit(&trans->transaction->pinned_extents,
3619-
bytenr, bytenr + num_bytes - 1,
3620-
EXTENT_DIRTY, NULL);
3621-
}
3607+
spin_unlock(&cache->lock);
3608+
spin_unlock(&space_info->lock);
36223609

3623-
spin_lock(&trans->transaction->dirty_bgs_lock);
3624-
if (list_empty(&cache->dirty_list)) {
3625-
list_add_tail(&cache->dirty_list,
3626-
&trans->transaction->dirty_bgs);
3627-
trans->delayed_ref_updates++;
3628-
btrfs_get_block_group(cache);
3629-
}
3630-
spin_unlock(&trans->transaction->dirty_bgs_lock);
3610+
set_extent_bit(&trans->transaction->pinned_extents, bytenr,
3611+
bytenr + num_bytes - 1, EXTENT_DIRTY, NULL);
3612+
}
36313613

3632-
/*
3633-
* No longer have used bytes in this block group, queue it for
3634-
* deletion. We do this after adding the block group to the
3635-
* dirty list to avoid races between cleaner kthread and space
3636-
* cache writeout.
3637-
*/
3638-
if (!alloc && old_val == 0) {
3639-
if (!btrfs_test_opt(info, DISCARD_ASYNC))
3640-
btrfs_mark_bg_unused(cache);
3641-
} else if (!alloc && reclaim) {
3642-
btrfs_mark_bg_to_reclaim(cache);
3643-
}
3614+
spin_lock(&trans->transaction->dirty_bgs_lock);
3615+
if (list_empty(&cache->dirty_list)) {
3616+
list_add_tail(&cache->dirty_list, &trans->transaction->dirty_bgs);
3617+
trans->delayed_ref_updates++;
3618+
btrfs_get_block_group(cache);
3619+
}
3620+
spin_unlock(&trans->transaction->dirty_bgs_lock);
36443621

3645-
btrfs_put_block_group(cache);
3646-
total -= num_bytes;
3647-
bytenr += num_bytes;
3622+
/*
3623+
* No longer have used bytes in this block group, queue it for deletion.
3624+
* We do this after adding the block group to the dirty list to avoid
3625+
* races between cleaner kthread and space cache writeout.
3626+
*/
3627+
if (!alloc && old_val == 0) {
3628+
if (!btrfs_test_opt(info, DISCARD_ASYNC))
3629+
btrfs_mark_bg_unused(cache);
3630+
} else if (!alloc && reclaim) {
3631+
btrfs_mark_bg_to_reclaim(cache);
36483632
}
36493633

3634+
btrfs_put_block_group(cache);
3635+
36503636
/* Modified block groups are accounted for in the delayed_refs_rsv. */
36513637
btrfs_update_delayed_refs_rsv(trans);
3652-
return ret;
3638+
3639+
return 0;
36533640
}
36543641

36553642
/*

0 commit comments

Comments
 (0)