Skip to content

Commit 2341ccd

Browse files
josefbacikkdave
authored andcommitted
btrfs: rework wake_all_tickets
Now that we no longer partially fill tickets we need to rework wake_all_tickets to call btrfs_try_to_wakeup_tickets() in order to see if any subsequent tickets are able to be satisfied. If our tickets_id changes we know something happened and we can keep flushing. Also if we find a ticket that is smaller than the first ticket in our queue then we want to retry the flushing loop again in case may_commit_transaction() decides we could satisfy the ticket by committing the transaction. Rename this to maybe_fail_all_tickets() while we're at it, to better reflect what the function is actually doing. Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 18fa228 commit 2341ccd

File tree

1 file changed

+49
-7
lines changed

1 file changed

+49
-7
lines changed

fs/btrfs/space-info.c

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -679,19 +679,61 @@ static inline int need_do_async_reclaim(struct btrfs_fs_info *fs_info,
679679
!test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state));
680680
}
681681

682-
static bool wake_all_tickets(struct list_head *head)
682+
/*
683+
* maybe_fail_all_tickets - we've exhausted our flushing, start failing tickets
684+
* @fs_info - fs_info for this fs
685+
* @space_info - the space info we were flushing
686+
*
687+
* We call this when we've exhausted our flushing ability and haven't made
688+
* progress in satisfying tickets. The reservation code handles tickets in
689+
* order, so if there is a large ticket first and then smaller ones we could
690+
* very well satisfy the smaller tickets. This will attempt to wake up any
691+
* tickets in the list to catch this case.
692+
*
693+
* This function returns true if it was able to make progress by clearing out
694+
* other tickets, or if it stumbles across a ticket that was smaller than the
695+
* first ticket.
696+
*/
697+
static bool maybe_fail_all_tickets(struct btrfs_fs_info *fs_info,
698+
struct btrfs_space_info *space_info)
683699
{
684700
struct reserve_ticket *ticket;
701+
u64 tickets_id = space_info->tickets_id;
702+
u64 first_ticket_bytes = 0;
703+
704+
while (!list_empty(&space_info->tickets) &&
705+
tickets_id == space_info->tickets_id) {
706+
ticket = list_first_entry(&space_info->tickets,
707+
struct reserve_ticket, list);
708+
709+
/*
710+
* may_commit_transaction will avoid committing the transaction
711+
* if it doesn't feel like the space reclaimed by the commit
712+
* would result in the ticket succeeding. However if we have a
713+
* smaller ticket in the queue it may be small enough to be
714+
* satisified by committing the transaction, so if any
715+
* subsequent ticket is smaller than the first ticket go ahead
716+
* and send us back for another loop through the enospc flushing
717+
* code.
718+
*/
719+
if (first_ticket_bytes == 0)
720+
first_ticket_bytes = ticket->bytes;
721+
else if (first_ticket_bytes > ticket->bytes)
722+
return true;
685723

686-
while (!list_empty(head)) {
687-
ticket = list_first_entry(head, struct reserve_ticket, list);
688724
list_del_init(&ticket->list);
689725
ticket->error = -ENOSPC;
690726
wake_up(&ticket->wait);
691-
if (ticket->bytes != ticket->orig_bytes)
692-
return true;
727+
728+
/*
729+
* We're just throwing tickets away, so more flushing may not
730+
* trip over btrfs_try_granting_tickets, so we need to call it
731+
* here to see if we can make progress with the next ticket in
732+
* the list.
733+
*/
734+
btrfs_try_granting_tickets(fs_info, space_info);
693735
}
694-
return false;
736+
return (tickets_id != space_info->tickets_id);
695737
}
696738

697739
/*
@@ -759,7 +801,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
759801
if (flush_state > COMMIT_TRANS) {
760802
commit_cycles++;
761803
if (commit_cycles > 2) {
762-
if (wake_all_tickets(&space_info->tickets)) {
804+
if (maybe_fail_all_tickets(fs_info, space_info)) {
763805
flush_state = FLUSH_DELAYED_ITEMS_NR;
764806
commit_cycles--;
765807
} else {

0 commit comments

Comments
 (0)