diff options
-rw-r--r-- | fs/btrfs/space-info.c | 43 |
1 files changed, 16 insertions, 27 deletions
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 2aa0b2040ac3..71fdc50b5900 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -233,52 +233,41 @@ void btrfs_space_info_add_old_bytes(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 num_bytes) { - struct reserve_ticket *ticket; struct list_head *head; - u64 used; enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_NO_FLUSH; - bool check_overcommit = false; spin_lock(&space_info->lock); head = &space_info->priority_tickets; + btrfs_space_info_update_bytes_may_use(fs_info, space_info, -num_bytes); - /* - * If we are over our limit then we need to check and see if we can - * overcommit, and if we can't then we just need to free up our space - * and not satisfy any requests. - */ - used = btrfs_space_info_used(space_info, true); - if (used - num_bytes >= space_info->total_bytes) - check_overcommit = true; again: - while (!list_empty(head) && num_bytes) { - ticket = list_first_entry(head, struct reserve_ticket, - list); - /* - * We use 0 bytes because this space is already reserved, so - * adding the ticket space would be a double count. - */ - if (check_overcommit && - !can_overcommit(fs_info, space_info, 0, flush, false)) - break; - if (num_bytes >= ticket->bytes) { + while (!list_empty(head)) { + struct reserve_ticket *ticket; + u64 used = btrfs_space_info_used(space_info, true); + + ticket = list_first_entry(head, struct reserve_ticket, list); + + /* Check and see if our ticket can be satisified now. */ + if ((used + ticket->bytes <= space_info->total_bytes) || + can_overcommit(fs_info, space_info, ticket->bytes, flush, + false)) { + btrfs_space_info_update_bytes_may_use(fs_info, + space_info, + ticket->bytes); list_del_init(&ticket->list); - num_bytes -= ticket->bytes; ticket->bytes = 0; space_info->tickets_id++; wake_up(&ticket->wait); } else { - ticket->bytes -= num_bytes; - num_bytes = 0; + break; } } - if (num_bytes && head == &space_info->priority_tickets) { + if (head == &space_info->priority_tickets) { head = &space_info->tickets; flush = BTRFS_RESERVE_FLUSH_ALL; goto again; } - btrfs_space_info_update_bytes_may_use(fs_info, space_info, -num_bytes); spin_unlock(&space_info->lock); } |