aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 7cb61ab887a..41c9549b32a 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 */
754static void __split_bio(struct mapped_device *md, struct bio *bio) 754static 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 */
791static int dm_request(struct request_queue *q, struct bio *bio) 791static 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
834out_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}