diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a9aadb2ad525..a8c0de888a9d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -703,7 +703,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror) | |||
703 | return -EIO; /* we fixed nothing */ | 703 | return -EIO; /* we fixed nothing */ |
704 | } | 704 | } |
705 | 705 | ||
706 | static void end_workqueue_bio(struct bio *bio, int err) | 706 | static void end_workqueue_bio(struct bio *bio) |
707 | { | 707 | { |
708 | struct btrfs_end_io_wq *end_io_wq = bio->bi_private; | 708 | struct btrfs_end_io_wq *end_io_wq = bio->bi_private; |
709 | struct btrfs_fs_info *fs_info; | 709 | struct btrfs_fs_info *fs_info; |
@@ -711,7 +711,7 @@ static void end_workqueue_bio(struct bio *bio, int err) | |||
711 | btrfs_work_func_t func; | 711 | btrfs_work_func_t func; |
712 | 712 | ||
713 | fs_info = end_io_wq->info; | 713 | fs_info = end_io_wq->info; |
714 | end_io_wq->error = err; | 714 | end_io_wq->error = bio->bi_error; |
715 | 715 | ||
716 | if (bio->bi_rw & REQ_WRITE) { | 716 | if (bio->bi_rw & REQ_WRITE) { |
717 | if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) { | 717 | if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) { |
@@ -808,7 +808,8 @@ static void run_one_async_done(struct btrfs_work *work) | |||
808 | 808 | ||
809 | /* If an error occured we just want to clean up the bio and move on */ | 809 | /* If an error occured we just want to clean up the bio and move on */ |
810 | if (async->error) { | 810 | if (async->error) { |
811 | bio_endio(async->bio, async->error); | 811 | async->bio->bi_error = async->error; |
812 | bio_endio(async->bio); | ||
812 | return; | 813 | return; |
813 | } | 814 | } |
814 | 815 | ||
@@ -908,8 +909,10 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | |||
908 | * submission context. Just jump into btrfs_map_bio | 909 | * submission context. Just jump into btrfs_map_bio |
909 | */ | 910 | */ |
910 | ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1); | 911 | ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1); |
911 | if (ret) | 912 | if (ret) { |
912 | bio_endio(bio, ret); | 913 | bio->bi_error = ret; |
914 | bio_endio(bio); | ||
915 | } | ||
913 | return ret; | 916 | return ret; |
914 | } | 917 | } |
915 | 918 | ||
@@ -960,10 +963,13 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
960 | __btree_submit_bio_done); | 963 | __btree_submit_bio_done); |
961 | } | 964 | } |
962 | 965 | ||
963 | if (ret) { | 966 | if (ret) |
967 | goto out_w_error; | ||
968 | return 0; | ||
969 | |||
964 | out_w_error: | 970 | out_w_error: |
965 | bio_endio(bio, ret); | 971 | bio->bi_error = ret; |
966 | } | 972 | bio_endio(bio); |
967 | return ret; | 973 | return ret; |
968 | } | 974 | } |
969 | 975 | ||
@@ -1735,16 +1741,15 @@ static void end_workqueue_fn(struct btrfs_work *work) | |||
1735 | { | 1741 | { |
1736 | struct bio *bio; | 1742 | struct bio *bio; |
1737 | struct btrfs_end_io_wq *end_io_wq; | 1743 | struct btrfs_end_io_wq *end_io_wq; |
1738 | int error; | ||
1739 | 1744 | ||
1740 | end_io_wq = container_of(work, struct btrfs_end_io_wq, work); | 1745 | end_io_wq = container_of(work, struct btrfs_end_io_wq, work); |
1741 | bio = end_io_wq->bio; | 1746 | bio = end_io_wq->bio; |
1742 | 1747 | ||
1743 | error = end_io_wq->error; | 1748 | bio->bi_error = end_io_wq->error; |
1744 | bio->bi_private = end_io_wq->private; | 1749 | bio->bi_private = end_io_wq->private; |
1745 | bio->bi_end_io = end_io_wq->end_io; | 1750 | bio->bi_end_io = end_io_wq->end_io; |
1746 | kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq); | 1751 | kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq); |
1747 | bio_endio(bio, error); | 1752 | bio_endio(bio); |
1748 | } | 1753 | } |
1749 | 1754 | ||
1750 | static int cleaner_kthread(void *arg) | 1755 | static int cleaner_kthread(void *arg) |
@@ -3323,10 +3328,8 @@ static int write_dev_supers(struct btrfs_device *device, | |||
3323 | * endio for the write_dev_flush, this will wake anyone waiting | 3328 | * endio for the write_dev_flush, this will wake anyone waiting |
3324 | * for the barrier when it is done | 3329 | * for the barrier when it is done |
3325 | */ | 3330 | */ |
3326 | static void btrfs_end_empty_barrier(struct bio *bio, int err) | 3331 | static void btrfs_end_empty_barrier(struct bio *bio) |
3327 | { | 3332 | { |
3328 | if (err) | ||
3329 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
3330 | if (bio->bi_private) | 3333 | if (bio->bi_private) |
3331 | complete(bio->bi_private); | 3334 | complete(bio->bi_private); |
3332 | bio_put(bio); | 3335 | bio_put(bio); |
@@ -3354,8 +3357,8 @@ static int write_dev_flush(struct btrfs_device *device, int wait) | |||
3354 | 3357 | ||
3355 | wait_for_completion(&device->flush_wait); | 3358 | wait_for_completion(&device->flush_wait); |
3356 | 3359 | ||
3357 | if (!bio_flagged(bio, BIO_UPTODATE)) { | 3360 | if (bio->bi_error) { |
3358 | ret = -EIO; | 3361 | ret = bio->bi_error; |
3359 | btrfs_dev_stat_inc_and_print(device, | 3362 | btrfs_dev_stat_inc_and_print(device, |
3360 | BTRFS_DEV_STAT_FLUSH_ERRS); | 3363 | BTRFS_DEV_STAT_FLUSH_ERRS); |
3361 | } | 3364 | } |