diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 18:38:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 18:38:19 -0400 |
commit | 3d30701b58970425e1d45994d6cb82f828924fdd (patch) | |
tree | 8b14cf462628bebf8548c1b8c205a674564052d1 /drivers/md/raid10.c | |
parent | 8cbd84f2dd4e52a8771b191030c374ba3e56d291 (diff) | |
parent | fd8aa2c1811bf60ccb2d5de0579c6f62aec1772d (diff) |
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md: (24 commits)
md: clean up do_md_stop
md: fix another deadlock with removing sysfs attributes.
md: move revalidate_disk() back outside open_mutex
md/raid10: fix deadlock with unaligned read during resync
md/bitmap: separate out loading a bitmap from initialising the structures.
md/bitmap: prepare for storing write-intent-bitmap via dm-dirty-log.
md/bitmap: optimise scanning of empty bitmaps.
md/bitmap: clean up plugging calls.
md/bitmap: reduce dependence on sysfs.
md/bitmap: white space clean up and similar.
md/raid5: export raid5 unplugging interface.
md/plug: optionally use plugger to unplug an array during resync/recovery.
md/raid5: add simple plugging infrastructure.
md/raid5: export is_congested test
raid5: Don't set read-ahead when there is no queue
md: add support for raising dm events.
md: export various start/stop interfaces
md: split out md_rdev_init
md: be more careful setting MD_CHANGE_CLEAN
md/raid5: ensure we create a unique name for kmem_cache when mddev has no gendisk
...
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 62ecb6650fd0..a88aeb5198c7 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: |