aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.de>2015-04-14 11:45:22 -0400
committerNeilBrown <neilb@suse.de>2015-04-21 17:59:39 -0400
commita6da4ef85cef0382244fc588c901e133a2ec5109 (patch)
treeed620e13534f9d28d93cf7650d123c9bd68f70b8 /drivers/md/md.c
parent88bcfef7be513e8bf5448e0025330fdd97c4c708 (diff)
md: re-add a failed disk
This adds the capability of re-adding a failed disk by writing "re-add" to /sys/block/mdXX/md/dev-YYY/state. This facilitates adding disks which have encountered a temporary error such as a network disconnection/hiccup in an iSCSI device, or a SAN cable disconnection which has been restored. In such a situation, you do not need to remove and re-add the device. Writing re-add to the failed device's state would add it again to the array and perform the recovery of only the blocks which were written after the device failed. This works for generic md, and is not related to clustering. However, this patch is to ease re-add operations listed above in clustering environments. Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Signed-off-by: NeilBrown <neilb@suse.de>
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);