diff options
author | Neil Brown <neilb@notabene.brown> | 2008-06-27 18:31:41 -0400 |
---|---|---|
committer | Neil Brown <neilb@notabene.brown> | 2008-06-27 18:31:41 -0400 |
commit | 72a23c211e4587859d5bf61ac4962d76e593fb02 (patch) | |
tree | b35b554d7eb9c4b3a2cbc4d9378d362e5e56e44f /drivers/md/md.c | |
parent | 0fd62b861eac7d2dea9b7e939953b20f37186ea1 (diff) |
Make sure all changes to md/sync_action are notified.
When the 'resync' thread starts or stops, when we explicitly
set sync_action, or when we determine that there is definitely nothing
to do, we notify sync_action.
To stop "sync_action" from occasionally showing the wrong value,
we introduce a new flags - MD_RECOVERY_RECOVER - to say that a
recovery is probably needed or happening, and we make sure
that we set MD_RECOVERY_RUNNING before clearing MD_RECOVERY_NEEDED.
Signed-off-by: Neil Brown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 34 |
1 files changed, 28 insertions, 6 deletions
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 | } |