diff options
-rw-r--r-- | Documentation/md.txt | 6 | ||||
-rw-r--r-- | drivers/md/md.c | 34 | ||||
-rw-r--r-- | include/linux/raid/md_k.h | 2 |
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 | } |
174 | EXPORT_SYMBOL_GPL(md_new_event); | 173 | EXPORT_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 |