summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
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/volumes.c
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/volumes.c')
-rw-r--r--fs/btrfs/volumes.c11
1 files changed, 9 insertions, 2 deletions
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)
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;
}