mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
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 commit28270e25c6("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:28270e25c6("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>
This commit is contained in:
parent
8ceaad6cd6
commit
2155d0c0a7
|
|
@ -276,10 +276,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
|
|||
struct btrfs_block_rsv *target = NULL;
|
||||
|
||||
/*
|
||||
* If we are a delayed block reserve then push to the global rsv,
|
||||
* otherwise dump into the global delayed reserve if it is not full.
|
||||
* If we are a delayed refs block reserve then push to the global
|
||||
* reserve, otherwise dump into the global delayed refs reserve if it is
|
||||
* not full.
|
||||
*/
|
||||
if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS)
|
||||
if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS)
|
||||
target = global_rsv;
|
||||
else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv))
|
||||
target = delayed_rsv;
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
|
|||
|
||||
h->type = type;
|
||||
INIT_LIST_HEAD(&h->new_bgs);
|
||||
btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS);
|
||||
btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS);
|
||||
|
||||
smp_mb();
|
||||
if (cur_trans->state >= TRANS_STATE_COMMIT_START &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user