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.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ca011d1d1de7..429e95e9a942 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2375,6 +2375,36 @@ repeat:
2375} 2375}
2376EXPORT_SYMBOL(md_update_sb); 2376EXPORT_SYMBOL(md_update_sb);
2377 2377
2378static int add_bound_rdev(struct md_rdev *rdev)
2379{
2380 struct mddev *mddev = rdev->mddev;
2381 int err = 0;
2382
2383 if (!mddev->pers->hot_remove_disk) {
2384 /* If there is hot_add_disk but no hot_remove_disk
2385 * then added disks for geometry changes,
2386 * and should be added immediately.
2387 */
2388 super_types[mddev->major_version].
2389 validate_super(mddev, rdev);
2390 err = mddev->pers->hot_add_disk(mddev, rdev);
2391 if (err) {
2392 unbind_rdev_from_array(rdev);
2393 export_rdev(rdev);
2394 return err;
2395 }
2396 }
2397 sysfs_notify_dirent_safe(rdev->sysfs_state);
2398
2399 set_bit(MD_CHANGE_DEVS, &mddev->flags);
2400 if (mddev->degraded)
2401 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
2402 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
2403 md_new_event(mddev);
2404 md_wakeup_thread(mddev->thread);
2405 return 0;
2406}
2407
2378/* words written to sysfs files may, or may not, be \n terminated. 2408/* words written to sysfs files may, or may not, be \n terminated.
2379 * We want to accept with case. For this we use cmd_match. 2409 * We want to accept with case. For this we use cmd_match.
2380 */ 2410 */
@@ -2564,6 +2594,12 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
2564 clear_bit(Replacement, &rdev->flags); 2594 clear_bit(Replacement, &rdev->flags);
2565 err = 0; 2595 err = 0;
2566 } 2596 }
2597 } else if (cmd_match(buf, "re-add")) {
2598 if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1)) {
2599 clear_bit(Faulty, &rdev->flags);
2600 err = add_bound_rdev(rdev);
2601 } else
2602 err = -EBUSY;
2567 } 2603 }
2568 if (!err) 2604 if (!err)
2569 sysfs_notify_dirent_safe(rdev->sysfs_state); 2605 sysfs_notify_dirent_safe(rdev->sysfs_state);
@@ -5875,29 +5911,10 @@ static int add_new_disk(struct mddev *mddev, mdu_disk_info_t *info)
5875 5911
5876 rdev->raid_disk = -1; 5912 rdev->raid_disk = -1;
5877 err = bind_rdev_to_array(rdev, mddev); 5913 err = bind_rdev_to_array(rdev, mddev);
5878 if (!err && !mddev->pers->hot_remove_disk) {
5879 /* If there is hot_add_disk but no hot_remove_disk
5880 * then added disks for geometry changes,
5881 * and should be added immediately.
5882 */
5883 super_types[mddev->major_version].
5884 validate_super(mddev, rdev);
5885 err = mddev->pers->hot_add_disk(mddev, rdev);
5886 if (err)
5887 unbind_rdev_from_array(rdev);
5888 }
5889 if (err) 5914 if (err)
5890 export_rdev(rdev); 5915 export_rdev(rdev);
5891 else 5916 else
5892 sysfs_notify_dirent_safe(rdev->sysfs_state); 5917 err = add_bound_rdev(rdev);
5893
5894 set_bit(MD_CHANGE_DEVS, &mddev->flags);
5895 if (mddev->degraded)
5896 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
5897 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
5898 if (!err)
5899 md_new_event(mddev);
5900 md_wakeup_thread(mddev->thread);
5901 if (mddev_is_clustered(mddev) && 5918 if (mddev_is_clustered(mddev) &&
5902 (info->state & (1 << MD_DISK_CLUSTER_ADD))) 5919 (info->state & (1 << MD_DISK_CLUSTER_ADD)))
5903 md_cluster_ops->add_new_disk_finish(mddev); 5920 md_cluster_ops->add_new_disk_finish(mddev);