From f89f064adc7f603ef39b9d6d0233f401faf97243 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 7 Aug 2010 21:17:00 +1000 Subject: [PATCH] --- yaml --- r: 208382 b: refs/heads/master c: 51e9ac77035a3dfcb6fc0a88a0d80b6f99b5edb1 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/md/raid10.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 2af00ac2d5ca..0bca2e41a01e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 69e51b449d383e97b1b9f890f8378c96e9e17346 +refs/heads/master: 51e9ac77035a3dfcb6fc0a88a0d80b6f99b5edb1 diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 42e64e4e5e25..d1d689126346 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -825,11 +825,29 @@ static int make_request(mddev_t *mddev, struct bio * bio) */ bp = bio_split(bio, chunk_sects - (bio->bi_sector & (chunk_sects - 1)) ); + + /* Each of these 'make_request' calls will call 'wait_barrier'. + * If the first succeeds but the second blocks due to the resync + * thread raising the barrier, we will deadlock because the + * IO to the underlying device will be queued in generic_make_request + * and will never complete, so will never reduce nr_pending. + * So increment nr_waiting here so no new raise_barriers will + * succeed, and so the second wait_barrier cannot block. + */ + spin_lock_irq(&conf->resync_lock); + conf->nr_waiting++; + spin_unlock_irq(&conf->resync_lock); + if (make_request(mddev, &bp->bio1)) generic_make_request(&bp->bio1); if (make_request(mddev, &bp->bio2)) generic_make_request(&bp->bio2); + spin_lock_irq(&conf->resync_lock); + conf->nr_waiting--; + wake_up(&conf->wait_barrier); + spin_unlock_irq(&conf->resync_lock); + bio_pair_release(bp); return 0; bad_map: