aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/md.txt6
-rw-r--r--drivers/md/md.c34
-rw-r--r--include/linux/raid/md_k.h2
3 files changed, 36 insertions, 6 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt
index dca97ba4944a..c05bfb55659e 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -386,6 +386,12 @@ also have
386 'check' and 'repair' will start the appropriate process 386 'check' and 'repair' will start the appropriate process
387 providing the current state is 'idle'. 387 providing the current state is 'idle'.
388 388
389 This file responds to select/poll. Any important change in the value
390 triggers a poll event. Sometimes the value will briefly be
391 "recover" if a recovery seems to be needed, but cannot be
392 achieved. In that case, the transition to "recover" isn't
393 notified, but the transition away is.
394
389 mismatch_count 395 mismatch_count
390 When performing 'check' and 'repair', and possibly when 396 When performing 'check' and 'repair', and possibly when
391 performing 'resync', md will count the number of errors that are 397 performing 'resync', md will count the number of errors that are
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5b9d4fe4e6e4..c26dcad8a3ac 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -169,7 +169,6 @@ void md_new_event(mddev_t *mddev)
169{ 169{
170 atomic_inc(&md_event_count); 170 atomic_inc(&md_event_count);
171 wake_up(&md_event_waiters); 171 wake_up(&md_event_waiters);
172 sysfs_notify(&mddev->kobj, NULL, "sync_action");
173} 172}
174EXPORT_SYMBOL_GPL(md_new_event); 173EXPORT_SYMBOL_GPL(md_new_event);
175 174
@@ -2936,7 +2935,7 @@ action_show(mddev_t *mddev, char *page)
2936 type = "check"; 2935 type = "check";
2937 else 2936 else
2938 type = "repair"; 2937 type = "repair";
2939 } else 2938 } else if (test_bit(MD_RECOVERY_RECOVER, &mddev->recovery))
2940 type = "recover"; 2939 type = "recover";
2941 } 2940 }
2942 return sprintf(page, "%s\n", type); 2941 return sprintf(page, "%s\n", type);
@@ -2958,9 +2957,12 @@ action_store(mddev_t *mddev, const char *page, size_t len)
2958 } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || 2957 } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
2959 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) 2958 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
2960 return -EBUSY; 2959 return -EBUSY;
2961 else if (cmd_match(page, "resync") || cmd_match(page, "recover")) 2960 else if (cmd_match(page, "resync"))
2961 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
2962 else if (cmd_match(page, "recover")) {
2963 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
2962 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2964 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
2963 else if (cmd_match(page, "reshape")) { 2965 } else if (cmd_match(page, "reshape")) {
2964 int err; 2966 int err;
2965 if (mddev->pers->start_reshape == NULL) 2967 if (mddev->pers->start_reshape == NULL)
2966 return -EINVAL; 2968 return -EINVAL;
@@ -2977,6 +2979,7 @@ action_store(mddev_t *mddev, const char *page, size_t len)
2977 } 2979 }
2978 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2980 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
2979 md_wakeup_thread(mddev->thread); 2981 md_wakeup_thread(mddev->thread);
2982 sysfs_notify(&mddev->kobj, NULL, "sync_action");
2980 return len; 2983 return len;
2981} 2984}
2982 2985
@@ -3682,6 +3685,7 @@ static int do_md_run(mddev_t * mddev)
3682 mddev->changed = 1; 3685 mddev->changed = 1;
3683 md_new_event(mddev); 3686 md_new_event(mddev);
3684 sysfs_notify(&mddev->kobj, NULL, "array_state"); 3687 sysfs_notify(&mddev->kobj, NULL, "array_state");
3688 sysfs_notify(&mddev->kobj, NULL, "sync_action");
3685 kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE); 3689 kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
3686 return 0; 3690 return 0;
3687} 3691}
@@ -4252,6 +4256,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
4252 export_rdev(rdev); 4256 export_rdev(rdev);
4253 4257
4254 md_update_sb(mddev, 1); 4258 md_update_sb(mddev, 1);
4259 if (mddev->degraded)
4260 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
4255 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4261 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4256 md_wakeup_thread(mddev->thread); 4262 md_wakeup_thread(mddev->thread);
4257 return err; 4263 return err;
@@ -5105,6 +5111,8 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
5105 if (!mddev->pers->error_handler) 5111 if (!mddev->pers->error_handler)
5106 return; 5112 return;
5107 mddev->pers->error_handler(mddev,rdev); 5113 mddev->pers->error_handler(mddev,rdev);
5114 if (mddev->degraded)
5115 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
5108 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 5116 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
5109 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 5117 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
5110 md_wakeup_thread(mddev->thread); 5118 md_wakeup_thread(mddev->thread);
@@ -6055,13 +6063,18 @@ void md_check_recovery(mddev_t *mddev)
6055 mddev->recovery = 0; 6063 mddev->recovery = 0;
6056 /* flag recovery needed just to double check */ 6064 /* flag recovery needed just to double check */
6057 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 6065 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
6066 sysfs_notify(&mddev->kobj, NULL, "sync_action");
6058 md_new_event(mddev); 6067 md_new_event(mddev);
6059 goto unlock; 6068 goto unlock;
6060 } 6069 }
6070 /* Set RUNNING before clearing NEEDED to avoid
6071 * any transients in the value of "sync_action".
6072 */
6073 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
6074 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
6061 /* Clear some bits that don't mean anything, but 6075 /* Clear some bits that don't mean anything, but
6062 * might be left set 6076 * might be left set
6063 */ 6077 */
6064 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
6065 clear_bit(MD_RECOVERY_INTR, &mddev->recovery); 6078 clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
6066 clear_bit(MD_RECOVERY_DONE, &mddev->recovery); 6079 clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
6067 6080
@@ -6079,17 +6092,19 @@ void md_check_recovery(mddev_t *mddev)
6079 /* Cannot proceed */ 6092 /* Cannot proceed */
6080 goto unlock; 6093 goto unlock;
6081 set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); 6094 set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
6095 clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
6082 } else if ((spares = remove_and_add_spares(mddev))) { 6096 } else if ((spares = remove_and_add_spares(mddev))) {
6083 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); 6097 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
6084 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); 6098 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
6099 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
6085 } else if (mddev->recovery_cp < MaxSector) { 6100 } else if (mddev->recovery_cp < MaxSector) {
6086 set_bit(MD_RECOVERY_SYNC, &mddev->recovery); 6101 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
6102 clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
6087 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) 6103 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
6088 /* nothing to be done ... */ 6104 /* nothing to be done ... */
6089 goto unlock; 6105 goto unlock;
6090 6106
6091 if (mddev->pers->sync_request) { 6107 if (mddev->pers->sync_request) {
6092 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
6093 if (spares && mddev->bitmap && ! mddev->bitmap->file) { 6108 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
6094 /* We are adding a device or devices to an array 6109 /* We are adding a device or devices to an array
6095 * which has the bitmap stored on all devices. 6110 * which has the bitmap stored on all devices.
@@ -6108,9 +6123,16 @@ void md_check_recovery(mddev_t *mddev)
6108 mddev->recovery = 0; 6123 mddev->recovery = 0;
6109 } else 6124 } else
6110 md_wakeup_thread(mddev->sync_thread); 6125 md_wakeup_thread(mddev->sync_thread);
6126 sysfs_notify(&mddev->kobj, NULL, "sync_action");
6111 md_new_event(mddev); 6127 md_new_event(mddev);
6112 } 6128 }
6113 unlock: 6129 unlock:
6130 if (!mddev->sync_thread) {
6131 clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
6132 if (test_and_clear_bit(MD_RECOVERY_RECOVER,
6133 &mddev->recovery))
6134 sysfs_notify(&mddev->kobj, NULL, "sync_action");
6135 }
6114 mddev_unlock(mddev); 6136 mddev_unlock(mddev);
6115 } 6137 }
6116} 6138}
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 780e0613e6d5..62aa9c9a6ddc 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -188,6 +188,7 @@ struct mddev_s
188 * NEEDED: we might need to start a resync/recover 188 * NEEDED: we might need to start a resync/recover
189 * RUNNING: a thread is running, or about to be started 189 * RUNNING: a thread is running, or about to be started
190 * SYNC: actually doing a resync, not a recovery 190 * SYNC: actually doing a resync, not a recovery
191 * RECOVER: doing recovery, or need to try it.
191 * INTR: resync needs to be aborted for some reason 192 * INTR: resync needs to be aborted for some reason
192 * DONE: thread is done and is waiting to be reaped 193 * DONE: thread is done and is waiting to be reaped
193 * REQUEST: user-space has requested a sync (used with SYNC) 194 * REQUEST: user-space has requested a sync (used with SYNC)
@@ -198,6 +199,7 @@ struct mddev_s
198 */ 199 */
199#define MD_RECOVERY_RUNNING 0 200#define MD_RECOVERY_RUNNING 0
200#define MD_RECOVERY_SYNC 1 201#define MD_RECOVERY_SYNC 1
202#define MD_RECOVERY_RECOVER 2
201#define MD_RECOVERY_INTR 3 203#define MD_RECOVERY_INTR 3
202#define MD_RECOVERY_DONE 4 204#define MD_RECOVERY_DONE 4
203#define MD_RECOVERY_NEEDED 5 205#define MD_RECOVERY_NEEDED 5