aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-02-04 09:19:41 -0500
committerChris Mason <chris.mason@oracle.com>2009-02-04 09:19:41 -0500
commita68370515356a3eddbfaf7f56418b3cf85d76c2c (patch)
tree362cfc618cc2eee50f43d91600b9e829539976c5 /fs/btrfs
parent89f135d8b53bcccafd91a075366d2704ba257cf3 (diff)
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: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/async-thread.c10
-rw-r--r--fs/btrfs/volumes.c11
2 files changed, 18 insertions, 3 deletions
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index d5f4e94f2ca..f2e80f3768e 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -349,6 +349,7 @@ int btrfs_requeue_work(struct btrfs_work *work)
349{ 349{
350 struct btrfs_worker_thread *worker = work->worker; 350 struct btrfs_worker_thread *worker = work->worker;
351 unsigned long flags; 351 unsigned long flags;
352 int wake = 0;
352 353
353 if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) 354 if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
354 goto out; 355 goto out;
@@ -367,10 +368,16 @@ int btrfs_requeue_work(struct btrfs_work *work)
367 &worker->workers->worker_list); 368 &worker->workers->worker_list);
368 spin_unlock_irqrestore(&worker->workers->lock, flags); 369 spin_unlock_irqrestore(&worker->workers->lock, flags);
369 } 370 }
371 if (!worker->working) {
372 wake = 1;
373 worker->working = 1;
374 }
370 375
371 spin_unlock_irqrestore(&worker->lock, flags); 376 spin_unlock_irqrestore(&worker->lock, flags);
372 377 if (wake)
378 wake_up_process(worker->task);
373out: 379out:
380
374 return 0; 381 return 0;
375} 382}
376 383
@@ -397,6 +404,7 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
397 } 404 }
398 405
399 spin_lock_irqsave(&worker->lock, flags); 406 spin_lock_irqsave(&worker->lock, flags);
407
400 atomic_inc(&worker->num_pending); 408 atomic_inc(&worker->num_pending);
401 check_busy_worker(worker); 409 check_busy_worker(worker);
402 list_add_tail(&work->list, &worker->pending); 410 list_add_tail(&work->list, &worker->pending);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index fd0bedb07a6..bcd14ebccae 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -154,6 +154,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
154loop: 154loop:
155 spin_lock(&device->io_lock); 155 spin_lock(&device->io_lock);
156 156
157loop_lock:
157 /* take all the bios off the list at once and process them 158 /* take all the bios off the list at once and process them
158 * later on (without the lock held). But, remember the 159 * later on (without the lock held). But, remember the
159 * tail and other pointers so the bios can be properly reinserted 160 * tail and other pointers so the bios can be properly reinserted
@@ -203,7 +204,7 @@ loop:
203 * is now congested. Back off and let other work structs 204 * is now congested. Back off and let other work structs
204 * run instead 205 * run instead
205 */ 206 */
206 if (pending && bdi_write_congested(bdi) && 207 if (pending && bdi_write_congested(bdi) && num_run > 16 &&
207 fs_info->fs_devices->open_devices > 1) { 208 fs_info->fs_devices->open_devices > 1) {
208 struct bio *old_head; 209 struct bio *old_head;
209 210
@@ -215,7 +216,8 @@ loop:
215 tail->bi_next = old_head; 216 tail->bi_next = old_head;
216 else 217 else
217 device->pending_bio_tail = tail; 218 device->pending_bio_tail = tail;
218 device->running_pending = 0; 219
220 device->running_pending = 1;
219 221
220 spin_unlock(&device->io_lock); 222 spin_unlock(&device->io_lock);
221 btrfs_requeue_work(&device->work); 223 btrfs_requeue_work(&device->work);
@@ -224,6 +226,11 @@ loop:
224 } 226 }
225 if (again) 227 if (again)
226 goto loop; 228 goto loop;
229
230 spin_lock(&device->io_lock);
231 if (device->pending_bios)
232 goto loop_lock;
233 spin_unlock(&device->io_lock);
227done: 234done:
228 return 0; 235 return 0;
229} 236}