Commit 8408c716 authored by Miao Xie's avatar Miao Xie Committed by Chris Mason

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: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent c55f1396
...@@ -5359,6 +5359,15 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, ...@@ -5359,6 +5359,15 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
return 0; return 0;
} }
static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int err)
{
if (likely(bbio->flags & BTRFS_BIO_ORIG_BIO_SUBMITTED))
bio_endio_nodec(bio, err);
else
bio_endio(bio, err);
kfree(bbio);
}
static void btrfs_end_bio(struct bio *bio, int err) static void btrfs_end_bio(struct bio *bio, int err)
{ {
struct btrfs_bio *bbio = bio->bi_private; struct btrfs_bio *bbio = bio->bi_private;
...@@ -5416,11 +5425,7 @@ static void btrfs_end_bio(struct bio *bio, int err) ...@@ -5416,11 +5425,7 @@ static void btrfs_end_bio(struct bio *bio, int err)
err = 0; err = 0;
} }
if (likely(bbio->flags & BTRFS_BIO_ORIG_BIO_SUBMITTED)) btrfs_end_bbio(bbio, bio, err);
bio_endio_nodec(bio, err);
else
bio_endio(bio, err);
kfree(bbio);
} else if (!is_orig_bio) { } else if (!is_orig_bio) {
bio_put(bio); bio_put(bio);
} }
...@@ -5583,12 +5588,15 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical) ...@@ -5583,12 +5588,15 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
{ {
atomic_inc(&bbio->error); atomic_inc(&bbio->error);
if (atomic_dec_and_test(&bbio->stripes_pending)) { if (atomic_dec_and_test(&bbio->stripes_pending)) {
/* Shoud be the original bio. */
WARN_ON(bio != bbio->orig_bio);
bio->bi_private = bbio->private; bio->bi_private = bbio->private;
bio->bi_end_io = bbio->end_io; bio->bi_end_io = bbio->end_io;
btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
bio->bi_iter.bi_sector = logical >> 9; bio->bi_iter.bi_sector = logical >> 9;
kfree(bbio);
bio_endio(bio, -EIO); btrfs_end_bbio(bbio, bio, -EIO);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment