Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6837051 authored by Chris Mason's avatar Chris Mason
Browse files

Btrfs: Catch missed bios in the async bio submission thread



The async bio submission thread was missing some bios that were
added after it had decided there was no work left to do.

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 89f135d8
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -349,6 +349,7 @@ int btrfs_requeue_work(struct btrfs_work *work)
{
	struct btrfs_worker_thread *worker = work->worker;
	unsigned long flags;
	int wake = 0;

	if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
		goto out;
@@ -367,10 +368,16 @@ int btrfs_requeue_work(struct btrfs_work *work)
			       &worker->workers->worker_list);
		spin_unlock_irqrestore(&worker->workers->lock, flags);
	}
	if (!worker->working) {
		wake = 1;
		worker->working = 1;
	}

	spin_unlock_irqrestore(&worker->lock, flags);

	if (wake)
		wake_up_process(worker->task);
out:

	return 0;
}

@@ -397,6 +404,7 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
	}

	spin_lock_irqsave(&worker->lock, flags);

	atomic_inc(&worker->num_pending);
	check_busy_worker(worker);
	list_add_tail(&work->list, &worker->pending);
+9 −2
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
loop:
	spin_lock(&device->io_lock);

loop_lock:
	/* take all the bios off the list at once and process them
	 * later on (without the lock held).  But, remember the
	 * tail and other pointers so the bios can be properly reinserted
@@ -203,7 +204,7 @@ loop:
		 * is now congested.  Back off and let other work structs
		 * run instead
		 */
		if (pending && bdi_write_congested(bdi) &&
		if (pending && bdi_write_congested(bdi) && num_run > 16 &&
		    fs_info->fs_devices->open_devices > 1) {
			struct bio *old_head;

@@ -215,7 +216,8 @@ loop:
				tail->bi_next = old_head;
			else
				device->pending_bio_tail = tail;
			device->running_pending = 0;

			device->running_pending = 1;

			spin_unlock(&device->io_lock);
			btrfs_requeue_work(&device->work);
@@ -224,6 +226,11 @@ loop:
	}
	if (again)
		goto loop;

	spin_lock(&device->io_lock);
	if (device->pending_bios)
		goto loop_lock;
	spin_unlock(&device->io_lock);
done:
	return 0;
}