Re: [PATCH 15/23] btrfs: use ticketing for data space reservations

David Sterba
2020-08-13T16:52:49Z

On Tue, Jul 21, 2020 at 10:22:26AM -0400, Josef Bacik wrote:
> +static void priority_reclaim_data_space(struct btrfs_fs_info *fs_info,
> + struct btrfs_space_info *space_info,
> + struct reserve_ticket *ticket,
> + const enum btrfs_flush_state *states,
> + int states_nr)
> +{
> + int flush_state = 0;
> + int commit_cycles = 2;
> +
> + while (!space_info->full) {
> + flush_space(fs_info, space_info, U64_MAX, ALLOC_CHUNK_FORCE);
> + spin_lock(&space_info->lock);
> + if (ticket->bytes == 0) {
> + spin_unlock(&space_info->lock);
> + return;
> + }
> + spin_unlock(&space_info->lock);
> + }
> +again:
> + while (flush_state < states_nr) {
> + u64 flush_bytes = U64_MAX;
> +
> + if (!commit_cycles) {
> + if (states[flush_state] == FLUSH_DELALLOC_WAIT) {
> + flush_state++;
> + continue;
> + }
> + if (states[flush_state] == COMMIT_TRANS)
> + flush_bytes = ticket->bytes;
> + }
> +
> + flush_space(fs_info, space_info, flush_bytes,
> + states[flush_state]);
> + spin_lock(&space_info->lock);
> + if (ticket->bytes == 0) {
> + spin_unlock(&space_info->lock);
> + return;
> + }
> + spin_unlock(&space_info->lock);
> + flush_state++;
> + }

Actually, the whole logic in this loop could use some human readable
description. There are 2 overlapping loops, one is over the states and
the other are commit cycles, with some state-conditional changes.

> + if (commit_cycles) {
> + commit_cycles--;
> + flush_state = 0;
> + goto again;
> + }
> +}