Merge branch 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[muen/linux.git] / fs / btrfs / disk-io.c
index aa59871885da6d5623891c0e2de0599dd2727cda..295795aebe0b42330cc1147e02340eb2c59f1d7b 100644 (file)
@@ -703,7 +703,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
        return -EIO;    /* we fixed nothing */
 }
 
-static void end_workqueue_bio(struct bio *bio, int err)
+static void end_workqueue_bio(struct bio *bio)
 {
        struct btrfs_end_io_wq *end_io_wq = bio->bi_private;
        struct btrfs_fs_info *fs_info;
@@ -711,7 +711,7 @@ static void end_workqueue_bio(struct bio *bio, int err)
        btrfs_work_func_t func;
 
        fs_info = end_io_wq->info;
-       end_io_wq->error = err;
+       end_io_wq->error = bio->bi_error;
 
        if (bio->bi_rw & REQ_WRITE) {
                if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) {
@@ -808,7 +808,8 @@ static void run_one_async_done(struct btrfs_work *work)
 
        /* If an error occured we just want to clean up the bio and move on */
        if (async->error) {
-               bio_endio(async->bio, async->error);
+               async->bio->bi_error = async->error;
+               bio_endio(async->bio);
                return;
        }
 
@@ -908,8 +909,10 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
         * submission context.  Just jump into btrfs_map_bio
         */
        ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
-       if (ret)
-               bio_endio(bio, ret);
+       if (ret) {
+               bio->bi_error = ret;
+               bio_endio(bio);
+       }
        return ret;
 }
 
@@ -960,10 +963,13 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                                          __btree_submit_bio_done);
        }
 
-       if (ret) {
+       if (ret)
+               goto out_w_error;
+       return 0;
+
 out_w_error:
-               bio_endio(bio, ret);
-       }
+       bio->bi_error = ret;
+       bio_endio(bio);
        return ret;
 }
 
@@ -1736,16 +1742,15 @@ static void end_workqueue_fn(struct btrfs_work *work)
 {
        struct bio *bio;
        struct btrfs_end_io_wq *end_io_wq;
-       int error;
 
        end_io_wq = container_of(work, struct btrfs_end_io_wq, work);
        bio = end_io_wq->bio;
 
-       error = end_io_wq->error;
+       bio->bi_error = end_io_wq->error;
        bio->bi_private = end_io_wq->private;
        bio->bi_end_io = end_io_wq->end_io;
        kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
-       bio_endio(bio, error);
+       bio_endio(bio);
 }
 
 static int cleaner_kthread(void *arg)
@@ -3325,10 +3330,8 @@ static int write_dev_supers(struct btrfs_device *device,
  * endio for the write_dev_flush, this will wake anyone waiting
  * for the barrier when it is done
  */
-static void btrfs_end_empty_barrier(struct bio *bio, int err)
+static void btrfs_end_empty_barrier(struct bio *bio)
 {
-       if (err)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
        if (bio->bi_private)
                complete(bio->bi_private);
        bio_put(bio);
@@ -3356,8 +3359,8 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
 
                wait_for_completion(&device->flush_wait);
 
-               if (!bio_flagged(bio, BIO_UPTODATE)) {
-                       ret = -EIO;
+               if (bio->bi_error) {
+                       ret = bio->bi_error;
                        btrfs_dev_stat_inc_and_print(device,
                                BTRFS_DEV_STAT_FLUSH_ERRS);
                }