diff --git a/[refs] b/[refs] index d55dcbe4a886..188a9cf97966 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3ce7e67a069b919be774a341b82fc20978b7f69d +refs/heads/master: 492bb6deee3416ad792dcd8584ebd95c463af1a6 diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 18db4cbe2794..0de51e37e789 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -180,7 +180,11 @@ int run_scheduled_bios(struct btrfs_device *device) 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 @@ int run_scheduled_bios(struct btrfs_device *device) * 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;