Btrfs: Hold a reference on bios during submit_bio, add some extra bio checks
authorChris Mason <chris.mason@oracle.com>
Thu, 31 Jul 2008 20:29:02 +0000 (16:29 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:04:05 +0000 (11:04 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/volumes.c

index 18db4cbe27941ac3d7779c2c2a4d2504975c2940..0de51e37e7896771cdf4615cc5ca499f3a1b3022 100644 (file)
@@ -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;