aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid10.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 42e64e4e5e25..d1d689126346 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -825,11 +825,29 @@ static int make_request(mddev_t *mddev, struct bio * bio)
825 */ 825 */
826 bp = bio_split(bio, 826 bp = bio_split(bio,
827 chunk_sects - (bio->bi_sector & (chunk_sects - 1)) ); 827 chunk_sects - (bio->bi_sector & (chunk_sects - 1)) );
828
829 /* Each of these 'make_request' calls will call 'wait_barrier'.
830 * If the first succeeds but the second blocks due to the resync
831 * thread raising the barrier, we will deadlock because the
832 * IO to the underlying device will be queued in generic_make_request
833 * and will never complete, so will never reduce nr_pending.
834 * So increment nr_waiting here so no new raise_barriers will
835 * succeed, and so the second wait_barrier cannot block.
836 */
837 spin_lock_irq(&conf->resync_lock);
838 conf->nr_waiting++;
839 spin_unlock_irq(&conf->resync_lock);
840
828 if (make_request(mddev, &bp->bio1)) 841 if (make_request(mddev, &bp->bio1))
829 generic_make_request(&bp->bio1); 842 generic_make_request(&bp->bio1);
830 if (make_request(mddev, &bp->bio2)) 843 if (make_request(mddev, &bp->bio2))
831 generic_make_request(&bp->bio2); 844 generic_make_request(&bp->bio2);
832 845
846 spin_lock_irq(&conf->resync_lock);
847 conf->nr_waiting--;
848 wake_up(&conf->wait_barrier);
849 spin_unlock_irq(&conf->resync_lock);
850
833 bio_pair_release(bp); 851 bio_pair_release(bp);
834 return 0; 852 return 0;
835 bad_map: 853 bad_map: