diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-23 18:25:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-23 18:25:01 -0700 |
commit | d2da626d6cb5df2c5d4222168c91ddf765aa4354 (patch) | |
tree | 920867db0e41b6d7f40a546265054ab53f7ce6b5 | |
parent | 721b024bd47c1e4b995e7eeb6455b714b817ad60 (diff) | |
parent | 30b8aa9172dfeaac6d77897c67ee9f9fc574cdbb (diff) | |
download | linux-d2da626d6cb5df2c5d4222168c91ddf765aa4354.tar.gz linux-d2da626d6cb5df2c5d4222168c91ddf765aa4354.tar.bz2 linux-d2da626d6cb5df2c5d4222168c91ddf765aa4354.zip |
Merge tag 'md-3.4-fixes' of git://neil.brown.name/md
Pull a few more md bug fixes from NeilBrown:
"2 are tagged for -stable, one being for a fairly serious bug that can
corrupt metadata and make it hard to recovery an array. The other is
for a more recent regression since 3.3"
* tag 'md-3.4-fixes' of git://neil.brown.name/md:
md: fix possible corruption of array metadata on shutdown.
md: don't call ->add_disk unless there is good reason.
DM RAID: Use safe version of rdev_for_each
-rw-r--r-- | drivers/md/dm-raid.c | 4 | ||||
-rw-r--r-- | drivers/md/md.c | 7 |
2 files changed, 6 insertions, 5 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index b0ba52459ed7..68965e663248 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) int ret; unsigned redundancy = 0; struct raid_dev *dev; - struct md_rdev *rdev, *freshest; + struct md_rdev *rdev, *tmp, *freshest; struct mddev *mddev = &rs->md; switch (rs->raid_type->level) { @@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) } freshest = NULL; - rdev_for_each(rdev, mddev) { + rdev_for_each_safe(rdev, tmp, mddev) { if (!rdev->meta_bdev) continue; diff --git a/drivers/md/md.c b/drivers/md/md.c index b572e1e386ce..477eb2e180c0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev) * any transients in the value of "sync_action". */ set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); - clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); /* Clear some bits that don't mean anything, but * might be left set */ clear_bit(MD_RECOVERY_INTR, &mddev->recovery); clear_bit(MD_RECOVERY_DONE, &mddev->recovery); - if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) + if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || + test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) goto unlock; /* no recovery is running. * remove any failed drives, then @@ -8140,7 +8140,8 @@ static int md_notify_reboot(struct notifier_block *this, for_each_mddev(mddev, tmp) { if (mddev_trylock(mddev)) { - __md_stop_writes(mddev); + if (mddev->pers) + __md_stop_writes(mddev); mddev->safemode = 2; mddev_unlock(mddev); } |