aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-06-18 22:42:55 -0400
committerChris Mason <clm@fb.com>2014-06-19 17:20:56 -0400
commit8408c716d7a4ddd5954ce33f53a7d3cd2876cf65 (patch)
tree870ecde1af3c547ed7e067a86d4fa93740581b0d /fs/btrfs/volumes.c
parentc55f13964008bfea7c5bee268f28b699cbad7f00 (diff)
Btrfs: fix wrong error handle when the device is missing or is not writeable
The original bio might be submitted, so we shoud increase bi_remaining to account for it when we deal with the error that the device is missing or is not writeable, or we would skip the endio handle. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 4ca3c92a54b3..c83b24251e53 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5359,6 +5359,15 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
5359 return 0; 5359 return 0;
5360} 5360}
5361 5361
5362static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int err)
5363{
5364 if (likely(bbio->flags & BTRFS_BIO_ORIG_BIO_SUBMITTED))
5365 bio_endio_nodec(bio, err);
5366 else
5367 bio_endio(bio, err);
5368 kfree(bbio);
5369}
5370
5362static void btrfs_end_bio(struct bio *bio, int err) 5371static void btrfs_end_bio(struct bio *bio, int err)
5363{ 5372{
5364 struct btrfs_bio *bbio = bio->bi_private; 5373 struct btrfs_bio *bbio = bio->bi_private;
@@ -5416,11 +5425,7 @@ static void btrfs_end_bio(struct bio *bio, int err)
5416 err = 0; 5425 err = 0;
5417 } 5426 }
5418 5427
5419 if (likely(bbio->flags & BTRFS_BIO_ORIG_BIO_SUBMITTED)) 5428 btrfs_end_bbio(bbio, bio, err);
5420 bio_endio_nodec(bio, err);
5421 else
5422 bio_endio(bio, err);
5423 kfree(bbio);
5424 } else if (!is_orig_bio) { 5429 } else if (!is_orig_bio) {
5425 bio_put(bio); 5430 bio_put(bio);
5426 } 5431 }
@@ -5583,12 +5588,15 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
5583{ 5588{
5584 atomic_inc(&bbio->error); 5589 atomic_inc(&bbio->error);
5585 if (atomic_dec_and_test(&bbio->stripes_pending)) { 5590 if (atomic_dec_and_test(&bbio->stripes_pending)) {
5591 /* Shoud be the original bio. */
5592 WARN_ON(bio != bbio->orig_bio);
5593
5586 bio->bi_private = bbio->private; 5594 bio->bi_private = bbio->private;
5587 bio->bi_end_io = bbio->end_io; 5595 bio->bi_end_io = bbio->end_io;
5588 btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; 5596 btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
5589 bio->bi_iter.bi_sector = logical >> 9; 5597 bio->bi_iter.bi_sector = logical >> 9;
5590 kfree(bbio); 5598
5591 bio_endio(bio, -EIO); 5599 btrfs_end_bbio(bbio, bio, -EIO);
5592 } 5600 }
5593} 5601}
5594 5602