Commit 42a72cb7 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: run btrfs_try_granting_tickets if a priority ticket fails

With normal tickets we could have a large reservation at the front of
the list that is unable to be satisfied, but a smaller ticket later on
that can be satisfied.  The way we handle this is to run
btrfs_try_granting_tickets() in maybe_fail_all_tickets().

However no such protection exists for priority tickets.  Fix this by
handling it in handle_reserve_ticket().  If we've returned after
attempting to flush space in a priority related way, we'll still be on
the priority list and need to be removed.

We rely on the flushing to free up space and wake the ticket, but if
there is not enough space to reclaim _but_ there's enough space in the
space_info to handle subsequent reservations then we would have gotten
an ENOSPC erroneously.

Address this by catching where we are still on the list, meaning we were
a priority ticket, and removing ourselves and then running
btrfs_try_granting_tickets().  This will handle this particular corner
case.
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Tested-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 666daa9f
...@@ -1164,11 +1164,17 @@ static int handle_reserve_ticket(struct btrfs_fs_info *fs_info, ...@@ -1164,11 +1164,17 @@ static int handle_reserve_ticket(struct btrfs_fs_info *fs_info,
ret = ticket->error; ret = ticket->error;
if (ticket->bytes || ticket->error) { if (ticket->bytes || ticket->error) {
/* /*
* Need to delete here for priority tickets. For regular tickets * We were a priority ticket, so we need to delete ourselves
* either the async reclaim job deletes the ticket from the list * from the list. Because we could have other priority tickets
* or we delete it ourselves at wait_reserve_ticket(). * behind us that require less space, run
* btrfs_try_granting_tickets() to see if their reservations can
* now be made.
*/ */
remove_ticket(space_info, ticket); if (!list_empty(&ticket->list)) {
remove_ticket(space_info, ticket);
btrfs_try_granting_tickets(fs_info, space_info);
}
if (!ret) if (!ret)
ret = -ENOSPC; ret = -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