Commit 4c8edbc7 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: update may_commit_transaction to use the delayed refs rsv

Any space used in the delayed_refs_rsv will be freed up by a transaction
commit, so instead of just counting the pinned space we also need to
account for any space in the delayed_refs_rsv when deciding if it will
make a different to commit the transaction to satisfy our space
reservation.  If we have enough bytes to satisfy our reservation ticket
then we are good to go, otherwise subtract out what space we would gain
back by committing the transaction and compare that against the pinned
space to make our decision.
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent ba2c4d4e
...@@ -4843,8 +4843,10 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info, ...@@ -4843,8 +4843,10 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info,
{ {
struct reserve_ticket *ticket = NULL; struct reserve_ticket *ticket = NULL;
struct btrfs_block_rsv *delayed_rsv = &fs_info->delayed_block_rsv; struct btrfs_block_rsv *delayed_rsv = &fs_info->delayed_block_rsv;
struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv;
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
u64 bytes; u64 bytes_needed;
u64 reclaim_bytes = 0;
trans = (struct btrfs_trans_handle *)current->journal_info; trans = (struct btrfs_trans_handle *)current->journal_info;
if (trans) if (trans)
...@@ -4857,15 +4859,15 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info, ...@@ -4857,15 +4859,15 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info,
else if (!list_empty(&space_info->tickets)) else if (!list_empty(&space_info->tickets))
ticket = list_first_entry(&space_info->tickets, ticket = list_first_entry(&space_info->tickets,
struct reserve_ticket, list); struct reserve_ticket, list);
bytes = (ticket) ? ticket->bytes : 0; bytes_needed = (ticket) ? ticket->bytes : 0;
spin_unlock(&space_info->lock); spin_unlock(&space_info->lock);
if (!bytes) if (!bytes_needed)
return 0; return 0;
/* See if there is enough pinned space to make this reservation */ /* See if there is enough pinned space to make this reservation */
if (__percpu_counter_compare(&space_info->total_bytes_pinned, if (__percpu_counter_compare(&space_info->total_bytes_pinned,
bytes, bytes_needed,
BTRFS_TOTAL_BYTES_PINNED_BATCH) >= 0) BTRFS_TOTAL_BYTES_PINNED_BATCH) >= 0)
goto commit; goto commit;
...@@ -4877,14 +4879,18 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info, ...@@ -4877,14 +4879,18 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info,
return -ENOSPC; return -ENOSPC;
spin_lock(&delayed_rsv->lock); spin_lock(&delayed_rsv->lock);
if (delayed_rsv->size > bytes) reclaim_bytes += delayed_rsv->reserved;
bytes = 0;
else
bytes -= delayed_rsv->size;
spin_unlock(&delayed_rsv->lock); spin_unlock(&delayed_rsv->lock);
spin_lock(&delayed_refs_rsv->lock);
reclaim_bytes += delayed_refs_rsv->reserved;
spin_unlock(&delayed_refs_rsv->lock);
if (reclaim_bytes >= bytes_needed)
goto commit;
bytes_needed -= reclaim_bytes;
if (__percpu_counter_compare(&space_info->total_bytes_pinned, if (__percpu_counter_compare(&space_info->total_bytes_pinned,
bytes, bytes_needed,
BTRFS_TOTAL_BYTES_PINNED_BATCH) < 0) { BTRFS_TOTAL_BYTES_PINNED_BATCH) < 0) {
return -ENOSPC; return -ENOSPC;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment