diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/md/md.c | 57 |
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 | } |
| 2376 | EXPORT_SYMBOL(md_update_sb); | 2376 | EXPORT_SYMBOL(md_update_sb); |
| 2377 | 2377 | ||
| 2378 | static 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); |
