aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c35
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
2396static void md_safemode_timeout(unsigned long data);
2397
2396static ssize_t 2398static ssize_t
2397safe_delay_show(mddev_t *mddev, char *page) 2399safe_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 /*