diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 7cb61ab887a2..41c9549b32ad 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -751,15 +751,13 @@ static void __clone_and_map(struct clone_info *ci) | |||
751 | /* | 751 | /* |
752 | * Split the bio into several clones. | 752 | * Split the bio into several clones. |
753 | */ | 753 | */ |
754 | static void __split_bio(struct mapped_device *md, struct bio *bio) | 754 | static int __split_bio(struct mapped_device *md, struct bio *bio) |
755 | { | 755 | { |
756 | struct clone_info ci; | 756 | struct clone_info ci; |
757 | 757 | ||
758 | ci.map = dm_get_table(md); | 758 | ci.map = dm_get_table(md); |
759 | if (!ci.map) { | 759 | if (unlikely(!ci.map)) |
760 | bio_io_error(bio); | 760 | return -EIO; |
761 | return; | ||
762 | } | ||
763 | 761 | ||
764 | ci.md = md; | 762 | ci.md = md; |
765 | ci.bio = bio; | 763 | ci.bio = bio; |
@@ -779,6 +777,8 @@ static void __split_bio(struct mapped_device *md, struct bio *bio) | |||
779 | /* drop the extra reference count */ | 777 | /* drop the extra reference count */ |
780 | dec_pending(ci.io, 0); | 778 | dec_pending(ci.io, 0); |
781 | dm_table_put(ci.map); | 779 | dm_table_put(ci.map); |
780 | |||
781 | return 0; | ||
782 | } | 782 | } |
783 | /*----------------------------------------------------------------- | 783 | /*----------------------------------------------------------------- |
784 | * CRUD END | 784 | * CRUD END |
@@ -790,7 +790,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio) | |||
790 | */ | 790 | */ |
791 | static int dm_request(struct request_queue *q, struct bio *bio) | 791 | static int dm_request(struct request_queue *q, struct bio *bio) |
792 | { | 792 | { |
793 | int r; | 793 | int r = -EIO; |
794 | int rw = bio_data_dir(bio); | 794 | int rw = bio_data_dir(bio); |
795 | struct mapped_device *md = q->queuedata; | 795 | struct mapped_device *md = q->queuedata; |
796 | 796 | ||
@@ -815,18 +815,11 @@ static int dm_request(struct request_queue *q, struct bio *bio) | |||
815 | while (test_bit(DMF_BLOCK_IO, &md->flags)) { | 815 | while (test_bit(DMF_BLOCK_IO, &md->flags)) { |
816 | up_read(&md->io_lock); | 816 | up_read(&md->io_lock); |
817 | 817 | ||
818 | if (bio_rw(bio) == READA) { | 818 | if (bio_rw(bio) != READA) |
819 | bio_io_error(bio); | 819 | r = queue_io(md, bio); |
820 | return 0; | ||
821 | } | ||
822 | |||
823 | r = queue_io(md, bio); | ||
824 | if (r < 0) { | ||
825 | bio_io_error(bio); | ||
826 | return 0; | ||
827 | 820 | ||
828 | } else if (r == 0) | 821 | if (r <= 0) |
829 | return 0; /* deferred successfully */ | 822 | goto out_req; |
830 | 823 | ||
831 | /* | 824 | /* |
832 | * We're in a while loop, because someone could suspend | 825 | * We're in a while loop, because someone could suspend |
@@ -835,8 +828,13 @@ static int dm_request(struct request_queue *q, struct bio *bio) | |||
835 | down_read(&md->io_lock); | 828 | down_read(&md->io_lock); |
836 | } | 829 | } |
837 | 830 | ||
838 | __split_bio(md, bio); | 831 | r = __split_bio(md, bio); |
839 | up_read(&md->io_lock); | 832 | up_read(&md->io_lock); |
833 | |||
834 | out_req: | ||
835 | if (r < 0) | ||
836 | bio_io_error(bio); | ||
837 | |||
840 | return 0; | 838 | return 0; |
841 | } | 839 | } |
842 | 840 | ||
@@ -1235,7 +1233,8 @@ static void __flush_deferred_io(struct mapped_device *md, struct bio *c) | |||
1235 | while (c) { | 1233 | while (c) { |
1236 | n = c->bi_next; | 1234 | n = c->bi_next; |
1237 | c->bi_next = NULL; | 1235 | c->bi_next = NULL; |
1238 | __split_bio(md, c); | 1236 | if (__split_bio(md, c)) |
1237 | bio_io_error(c); | ||
1239 | c = n; | 1238 | c = n; |
1240 | } | 1239 | } |
1241 | } | 1240 | } |