summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-31 16:29:02 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit492bb6deee3416ad792dcd8584ebd95c463af1a6 (patch)
tree753b2df0461b91b93eae0484e2049a728930631d /fs/btrfs/volumes.c
parent3ce7e67a069b919be774a341b82fc20978b7f69d (diff)
Btrfs: Hold a reference on bios during submit_bio, add some extra bio checks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 18db4cbe279..0de51e37e78 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -180,7 +180,11 @@ loop:
pending = pending->bi_next;
cur->bi_next = NULL;
atomic_dec(&device->dev_root->fs_info->nr_async_submits);
+
+ BUG_ON(atomic_read(&cur->bi_cnt) == 0);
+ bio_get(cur);
submit_bio(cur->bi_rw, cur);
+ bio_put(cur);
num_run++;
/*
@@ -188,10 +192,11 @@ loop:
* is now congested. Back off and let other work structs
* run instead
*/
- if (pending && num_run && bdi_write_congested(bdi)) {
+ if (pending && bdi_write_congested(bdi)) {
struct bio *old_head;
spin_lock(&device->io_lock);
+
old_head = device->pending_bios;
device->pending_bios = pending;
if (device->pending_bio_tail)
@@ -2125,7 +2130,9 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device,
/* don't bother with additional async steps for reads, right now */
if (!(rw & (1 << BIO_RW))) {
+ bio_get(bio);
submit_bio(rw, bio);
+ bio_put(bio);
return 0;
}
@@ -2136,6 +2143,7 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device,
* on a queue for later
*/
atomic_inc(&root->fs_info->nr_async_submits);
+ WARN_ON(bio->bi_next);
bio->bi_next = NULL;
bio->bi_rw |= rw;