diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index c7aae66c6f9b..4790c83d78d0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2393,6 +2393,8 @@ static void analyze_sbs(mddev_t * mddev) | |||
2393 | 2393 | ||
2394 | } | 2394 | } |
2395 | 2395 | ||
2396 | static void md_safemode_timeout(unsigned long data); | ||
2397 | |||
2396 | static ssize_t | 2398 | static ssize_t |
2397 | safe_delay_show(mddev_t *mddev, char *page) | 2399 | safe_delay_show(mddev_t *mddev, char *page) |
2398 | { | 2400 | { |
@@ -2432,9 +2434,12 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) | |||
2432 | if (msec == 0) | 2434 | if (msec == 0) |
2433 | mddev->safemode_delay = 0; | 2435 | mddev->safemode_delay = 0; |
2434 | else { | 2436 | else { |
2437 | unsigned long old_delay = mddev->safemode_delay; | ||
2435 | mddev->safemode_delay = (msec*HZ)/1000; | 2438 | mddev->safemode_delay = (msec*HZ)/1000; |
2436 | if (mddev->safemode_delay == 0) | 2439 | if (mddev->safemode_delay == 0) |
2437 | mddev->safemode_delay = 1; | 2440 | mddev->safemode_delay = 1; |
2441 | if (mddev->safemode_delay < old_delay) | ||
2442 | md_safemode_timeout((unsigned long)mddev); | ||
2438 | } | 2443 | } |
2439 | return len; | 2444 | return len; |
2440 | } | 2445 | } |
@@ -3836,8 +3841,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
3836 | 3841 | ||
3837 | del_timer_sync(&mddev->safemode_timer); | 3842 | del_timer_sync(&mddev->safemode_timer); |
3838 | 3843 | ||
3839 | invalidate_partition(disk, 0); | ||
3840 | |||
3841 | switch(mode) { | 3844 | switch(mode) { |
3842 | case 1: /* readonly */ | 3845 | case 1: /* readonly */ |
3843 | err = -ENXIO; | 3846 | err = -ENXIO; |
@@ -4634,6 +4637,11 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) | |||
4634 | */ | 4637 | */ |
4635 | if (mddev->sync_thread) | 4638 | if (mddev->sync_thread) |
4636 | return -EBUSY; | 4639 | return -EBUSY; |
4640 | if (mddev->bitmap) | ||
4641 | /* Sorry, cannot grow a bitmap yet, just remove it, | ||
4642 | * grow, and re-add. | ||
4643 | */ | ||
4644 | return -EBUSY; | ||
4637 | rdev_for_each(rdev, tmp, mddev) { | 4645 | rdev_for_each(rdev, tmp, mddev) { |
4638 | sector_t avail; | 4646 | sector_t avail; |
4639 | avail = rdev->size * 2; | 4647 | avail = rdev->size * 2; |
@@ -5993,7 +6001,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5993 | } | 6001 | } |
5994 | } | 6002 | } |
5995 | 6003 | ||
5996 | if (mddev->degraded) { | 6004 | if (mddev->degraded && ! mddev->ro) { |
5997 | rdev_for_each(rdev, rtmp, mddev) { | 6005 | rdev_for_each(rdev, rtmp, mddev) { |
5998 | if (rdev->raid_disk >= 0 && | 6006 | if (rdev->raid_disk >= 0 && |
5999 | !test_bit(In_sync, &rdev->flags) && | 6007 | !test_bit(In_sync, &rdev->flags) && |
@@ -6067,6 +6075,8 @@ void md_check_recovery(mddev_t *mddev) | |||
6067 | flush_signals(current); | 6075 | flush_signals(current); |
6068 | } | 6076 | } |
6069 | 6077 | ||
6078 | if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | ||
6079 | return; | ||
6070 | if ( ! ( | 6080 | if ( ! ( |
6071 | (mddev->flags && !mddev->external) || | 6081 | (mddev->flags && !mddev->external) || |
6072 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || | 6082 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || |
@@ -6080,6 +6090,15 @@ void md_check_recovery(mddev_t *mddev) | |||
6080 | if (mddev_trylock(mddev)) { | 6090 | if (mddev_trylock(mddev)) { |
6081 | int spares = 0; | 6091 | int spares = 0; |
6082 | 6092 | ||
6093 | if (mddev->ro) { | ||
6094 | /* Only thing we do on a ro array is remove | ||
6095 | * failed devices. | ||
6096 | */ | ||
6097 | remove_and_add_spares(mddev); | ||
6098 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
6099 | goto unlock; | ||
6100 | } | ||
6101 | |||
6083 | if (!mddev->external) { | 6102 | if (!mddev->external) { |
6084 | int did_change = 0; | 6103 | int did_change = 0; |
6085 | spin_lock_irq(&mddev->write_lock); | 6104 | spin_lock_irq(&mddev->write_lock); |
@@ -6117,7 +6136,8 @@ void md_check_recovery(mddev_t *mddev) | |||
6117 | /* resync has finished, collect result */ | 6136 | /* resync has finished, collect result */ |
6118 | md_unregister_thread(mddev->sync_thread); | 6137 | md_unregister_thread(mddev->sync_thread); |
6119 | mddev->sync_thread = NULL; | 6138 | mddev->sync_thread = NULL; |
6120 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 6139 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
6140 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | ||
6121 | /* success...*/ | 6141 | /* success...*/ |
6122 | /* activate any spares */ | 6142 | /* activate any spares */ |
6123 | if (mddev->pers->spare_active(mddev)) | 6143 | if (mddev->pers->spare_active(mddev)) |
@@ -6169,6 +6189,7 @@ void md_check_recovery(mddev_t *mddev) | |||
6169 | } else if ((spares = remove_and_add_spares(mddev))) { | 6189 | } else if ((spares = remove_and_add_spares(mddev))) { |
6170 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 6190 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
6171 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 6191 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
6192 | clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); | ||
6172 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | 6193 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); |
6173 | } else if (mddev->recovery_cp < MaxSector) { | 6194 | } else if (mddev->recovery_cp < MaxSector) { |
6174 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 6195 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
@@ -6232,7 +6253,11 @@ static int md_notify_reboot(struct notifier_block *this, | |||
6232 | 6253 | ||
6233 | for_each_mddev(mddev, tmp) | 6254 | for_each_mddev(mddev, tmp) |
6234 | if (mddev_trylock(mddev)) { | 6255 | if (mddev_trylock(mddev)) { |
6235 | do_md_stop (mddev, 1, 0); | 6256 | /* Force a switch to readonly even array |
6257 | * appears to still be in use. Hence | ||
6258 | * the '100'. | ||
6259 | */ | ||
6260 | do_md_stop (mddev, 1, 100); | ||
6236 | mddev_unlock(mddev); | 6261 | mddev_unlock(mddev); |
6237 | } | 6262 | } |
6238 | /* | 6263 | /* |