Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

btrfs: use the correct type to initialize block reserve for delayed refs

When initializing the delayed refs block reserve for a transaction handle
we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for
delayed items and not for delayed refs. The correct type for delayed refs
is BTRFS_BLOCK_RSV_DELREFS.

On release of any excess space reserved in a local delayed refs reserve,
we also should transfer that excess space to the global block reserve
(it it's full, we return to the space info for general availability).

By initializing a transaction's local delayed refs block reserve with a
type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space
released from the delayed block reserve (fs_info->delayed_block_rsv, used
for delayed inodes and items) to be transferred to the global block
reserve instead of the global delayed refs block reserve. This was an
unintentional change in commit 28270e25c69a ("btrfs: always reserve space
for delayed refs when starting transaction"), but it's not particularly
serious as things tend to cancel out each other most of the time and it's
relatively rare to be anywhere near exhaustion of the global reserve.

Fix this by initializing a transaction's local delayed refs reserve with
a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release()
attempt to transfer unused space from such a reserve into the global block
reserve, just as we did before that commit for when the block reserve is
a delayed refs rsv.

Reported-by: Alex Lyakas <alex.lyakas@zadara.com>
Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/
Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction")
Reviewed-by: Alex Lyakas <alex.lyakas@zadara.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

Filipe Manana and committed by
David Sterba
2155d0c0 8ceaad6c

+5 -4
+4 -3
fs/btrfs/block-rsv.c
··· 276 276 struct btrfs_block_rsv *target = NULL; 277 277 278 278 /* 279 - * If we are a delayed block reserve then push to the global rsv, 280 - * otherwise dump into the global delayed reserve if it is not full. 279 + * If we are a delayed refs block reserve then push to the global 280 + * reserve, otherwise dump into the global delayed refs reserve if it is 281 + * not full. 281 282 */ 282 - if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS) 283 + if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS) 283 284 target = global_rsv; 284 285 else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv)) 285 286 target = delayed_rsv;
+1 -1
fs/btrfs/transaction.c
··· 726 726 727 727 h->type = type; 728 728 INIT_LIST_HEAD(&h->new_bgs); 729 - btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS); 729 + btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS); 730 730 731 731 smp_mb(); 732 732 if (cur_trans->state >= TRANS_STATE_COMMIT_START &&