aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index cf44da832ca1..43f6ef8d696f 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -754,7 +754,9 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
754 struct bio_pair **bp, 754 struct bio_pair **bp,
755 int len, gfp_t gfpmask) 755 int len, gfp_t gfpmask)
756{ 756{
757 struct bio *tmp, *old_chain = *old, *new_chain = NULL, *tail = NULL; 757 struct bio *old_chain = *old;
758 struct bio *new_chain = NULL;
759 struct bio *tail;
758 int total = 0; 760 int total = 0;
759 761
760 if (*bp) { 762 if (*bp) {
@@ -763,9 +765,12 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
763 } 765 }
764 766
765 while (old_chain && (total < len)) { 767 while (old_chain && (total < len)) {
768 struct bio *tmp;
769
766 tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs); 770 tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
767 if (!tmp) 771 if (!tmp)
768 goto err_out; 772 goto err_out;
773 gfpmask &= ~__GFP_WAIT; /* can't wait after the first */
769 774
770 if (total + old_chain->bi_size > len) { 775 if (total + old_chain->bi_size > len) {
771 struct bio_pair *bp; 776 struct bio_pair *bp;
@@ -793,15 +798,12 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
793 } 798 }
794 799
795 tmp->bi_bdev = NULL; 800 tmp->bi_bdev = NULL;
796 gfpmask &= ~__GFP_WAIT;
797 tmp->bi_next = NULL; 801 tmp->bi_next = NULL;
798 802 if (new_chain)
799 if (!new_chain) {
800 new_chain = tail = tmp;
801 } else {
802 tail->bi_next = tmp; 803 tail->bi_next = tmp;
803 tail = tmp; 804 else
804 } 805 new_chain = tmp;
806 tail = tmp;
805 old_chain = old_chain->bi_next; 807 old_chain = old_chain->bi_next;
806 808
807 total += tmp->bi_size; 809 total += tmp->bi_size;
@@ -809,9 +811,6 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
809 811
810 BUG_ON(total < len); 812 BUG_ON(total < len);
811 813
812 if (tail)
813 tail->bi_next = NULL;
814
815 *old = old_chain; 814 *old = old_chain;
816 815
817 return new_chain; 816 return new_chain;