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.c107
1 files changed, 80 insertions, 27 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5d1b6762f108..ca8527fe77eb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1713,6 +1713,8 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
1713 } 1713 }
1714 if (sb->devflags & WriteMostly1) 1714 if (sb->devflags & WriteMostly1)
1715 set_bit(WriteMostly, &rdev->flags); 1715 set_bit(WriteMostly, &rdev->flags);
1716 if (le32_to_cpu(sb->feature_map) & MD_FEATURE_REPLACEMENT)
1717 set_bit(Replacement, &rdev->flags);
1716 } else /* MULTIPATH are always insync */ 1718 } else /* MULTIPATH are always insync */
1717 set_bit(In_sync, &rdev->flags); 1719 set_bit(In_sync, &rdev->flags);
1718 1720
@@ -1766,6 +1768,9 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
1766 sb->recovery_offset = 1768 sb->recovery_offset =
1767 cpu_to_le64(rdev->recovery_offset); 1769 cpu_to_le64(rdev->recovery_offset);
1768 } 1770 }
1771 if (test_bit(Replacement, &rdev->flags))
1772 sb->feature_map |=
1773 cpu_to_le32(MD_FEATURE_REPLACEMENT);
1769 1774
1770 if (mddev->reshape_position != MaxSector) { 1775 if (mddev->reshape_position != MaxSector) {
1771 sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE); 1776 sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE);
@@ -2559,6 +2564,15 @@ state_show(struct md_rdev *rdev, char *page)
2559 len += sprintf(page+len, "%swrite_error", sep); 2564 len += sprintf(page+len, "%swrite_error", sep);
2560 sep = ","; 2565 sep = ",";
2561 } 2566 }
2567 if (test_bit(WantReplacement, &rdev->flags)) {
2568 len += sprintf(page+len, "%swant_replacement", sep);
2569 sep = ",";
2570 }
2571 if (test_bit(Replacement, &rdev->flags)) {
2572 len += sprintf(page+len, "%sreplacement", sep);
2573 sep = ",";
2574 }
2575
2562 return len+sprintf(page+len, "\n"); 2576 return len+sprintf(page+len, "\n");
2563} 2577}
2564 2578
@@ -2627,6 +2641,42 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
2627 } else if (cmd_match(buf, "-write_error")) { 2641 } else if (cmd_match(buf, "-write_error")) {
2628 clear_bit(WriteErrorSeen, &rdev->flags); 2642 clear_bit(WriteErrorSeen, &rdev->flags);
2629 err = 0; 2643 err = 0;
2644 } else if (cmd_match(buf, "want_replacement")) {
2645 /* Any non-spare device that is not a replacement can
2646 * become want_replacement at any time, but we then need to
2647 * check if recovery is needed.
2648 */
2649 if (rdev->raid_disk >= 0 &&
2650 !test_bit(Replacement, &rdev->flags))
2651 set_bit(WantReplacement, &rdev->flags);
2652 set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
2653 md_wakeup_thread(rdev->mddev->thread);
2654 err = 0;
2655 } else if (cmd_match(buf, "-want_replacement")) {
2656 /* Clearing 'want_replacement' is always allowed.
2657 * Once replacements starts it is too late though.
2658 */
2659 err = 0;
2660 clear_bit(WantReplacement, &rdev->flags);
2661 } else if (cmd_match(buf, "replacement")) {
2662 /* Can only set a device as a replacement when array has not
2663 * yet been started. Once running, replacement is automatic
2664 * from spares, or by assigning 'slot'.
2665 */
2666 if (rdev->mddev->pers)
2667 err = -EBUSY;
2668 else {
2669 set_bit(Replacement, &rdev->flags);
2670 err = 0;
2671 }
2672 } else if (cmd_match(buf, "-replacement")) {
2673 /* Similarly, can only clear Replacement before start */
2674 if (rdev->mddev->pers)
2675 err = -EBUSY;
2676 else {
2677 clear_bit(Replacement, &rdev->flags);
2678 err = 0;
2679 }
2630 } 2680 }
2631 if (!err) 2681 if (!err)
2632 sysfs_notify_dirent_safe(rdev->sysfs_state); 2682 sysfs_notify_dirent_safe(rdev->sysfs_state);
@@ -2688,7 +2738,7 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
2688 if (rdev->mddev->pers->hot_remove_disk == NULL) 2738 if (rdev->mddev->pers->hot_remove_disk == NULL)
2689 return -EINVAL; 2739 return -EINVAL;
2690 err = rdev->mddev->pers-> 2740 err = rdev->mddev->pers->
2691 hot_remove_disk(rdev->mddev, rdev->raid_disk); 2741 hot_remove_disk(rdev->mddev, rdev);
2692 if (err) 2742 if (err)
2693 return err; 2743 return err;
2694 sysfs_unlink_rdev(rdev->mddev, rdev); 2744 sysfs_unlink_rdev(rdev->mddev, rdev);
@@ -2696,7 +2746,6 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
2696 set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); 2746 set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
2697 md_wakeup_thread(rdev->mddev->thread); 2747 md_wakeup_thread(rdev->mddev->thread);
2698 } else if (rdev->mddev->pers) { 2748 } else if (rdev->mddev->pers) {
2699 struct md_rdev *rdev2;
2700 /* Activating a spare .. or possibly reactivating 2749 /* Activating a spare .. or possibly reactivating
2701 * if we ever get bitmaps working here. 2750 * if we ever get bitmaps working here.
2702 */ 2751 */
@@ -2710,10 +2759,6 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
2710 if (rdev->mddev->pers->hot_add_disk == NULL) 2759 if (rdev->mddev->pers->hot_add_disk == NULL)
2711 return -EINVAL; 2760 return -EINVAL;
2712 2761
2713 list_for_each_entry(rdev2, &rdev->mddev->disks, same_set)
2714 if (rdev2->raid_disk == slot)
2715 return -EEXIST;
2716
2717 if (slot >= rdev->mddev->raid_disks && 2762 if (slot >= rdev->mddev->raid_disks &&
2718 slot >= rdev->mddev->raid_disks + rdev->mddev->delta_disks) 2763 slot >= rdev->mddev->raid_disks + rdev->mddev->delta_disks)
2719 return -ENOSPC; 2764 return -ENOSPC;
@@ -6053,8 +6098,15 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
6053 struct mddev *mddev = NULL; 6098 struct mddev *mddev = NULL;
6054 int ro; 6099 int ro;
6055 6100
6056 if (!capable(CAP_SYS_ADMIN)) 6101 switch (cmd) {
6057 return -EACCES; 6102 case RAID_VERSION:
6103 case GET_ARRAY_INFO:
6104 case GET_DISK_INFO:
6105 break;
6106 default:
6107 if (!capable(CAP_SYS_ADMIN))
6108 return -EACCES;
6109 }
6058 6110
6059 /* 6111 /*
6060 * Commands dealing with the RAID driver but not any 6112 * Commands dealing with the RAID driver but not any
@@ -6714,8 +6766,11 @@ static int md_seq_show(struct seq_file *seq, void *v)
6714 if (test_bit(Faulty, &rdev->flags)) { 6766 if (test_bit(Faulty, &rdev->flags)) {
6715 seq_printf(seq, "(F)"); 6767 seq_printf(seq, "(F)");
6716 continue; 6768 continue;
6717 } else if (rdev->raid_disk < 0) 6769 }
6770 if (rdev->raid_disk < 0)
6718 seq_printf(seq, "(S)"); /* spare */ 6771 seq_printf(seq, "(S)"); /* spare */
6772 if (test_bit(Replacement, &rdev->flags))
6773 seq_printf(seq, "(R)");
6719 sectors += rdev->sectors; 6774 sectors += rdev->sectors;
6720 } 6775 }
6721 6776
@@ -7337,29 +7392,27 @@ static int remove_and_add_spares(struct mddev *mddev)
7337 ! test_bit(In_sync, &rdev->flags)) && 7392 ! test_bit(In_sync, &rdev->flags)) &&
7338 atomic_read(&rdev->nr_pending)==0) { 7393 atomic_read(&rdev->nr_pending)==0) {
7339 if (mddev->pers->hot_remove_disk( 7394 if (mddev->pers->hot_remove_disk(
7340 mddev, rdev->raid_disk)==0) { 7395 mddev, rdev) == 0) {
7341 sysfs_unlink_rdev(mddev, rdev); 7396 sysfs_unlink_rdev(mddev, rdev);
7342 rdev->raid_disk = -1; 7397 rdev->raid_disk = -1;
7343 } 7398 }
7344 } 7399 }
7345 7400
7346 if (mddev->degraded) { 7401 list_for_each_entry(rdev, &mddev->disks, same_set) {
7347 list_for_each_entry(rdev, &mddev->disks, same_set) { 7402 if (rdev->raid_disk >= 0 &&
7348 if (rdev->raid_disk >= 0 && 7403 !test_bit(In_sync, &rdev->flags) &&
7349 !test_bit(In_sync, &rdev->flags) && 7404 !test_bit(Faulty, &rdev->flags))
7350 !test_bit(Faulty, &rdev->flags)) 7405 spares++;
7406 if (rdev->raid_disk < 0
7407 && !test_bit(Faulty, &rdev->flags)) {
7408 rdev->recovery_offset = 0;
7409 if (mddev->pers->
7410 hot_add_disk(mddev, rdev) == 0) {
7411 if (sysfs_link_rdev(mddev, rdev))
7412 /* failure here is OK */;
7351 spares++; 7413 spares++;
7352 if (rdev->raid_disk < 0 7414 md_new_event(mddev);
7353 && !test_bit(Faulty, &rdev->flags)) { 7415 set_bit(MD_CHANGE_DEVS, &mddev->flags);
7354 rdev->recovery_offset = 0;
7355 if (mddev->pers->
7356 hot_add_disk(mddev, rdev) == 0) {
7357 if (sysfs_link_rdev(mddev, rdev))
7358 /* failure here is OK */;
7359 spares++;
7360 md_new_event(mddev);
7361 set_bit(MD_CHANGE_DEVS, &mddev->flags);
7362 }
7363 } 7416 }
7364 } 7417 }
7365 } 7418 }
@@ -7474,7 +7527,7 @@ void md_check_recovery(struct mddev *mddev)
7474 test_bit(Faulty, &rdev->flags) && 7527 test_bit(Faulty, &rdev->flags) &&
7475 atomic_read(&rdev->nr_pending)==0) { 7528 atomic_read(&rdev->nr_pending)==0) {
7476 if (mddev->pers->hot_remove_disk( 7529 if (mddev->pers->hot_remove_disk(
7477 mddev, rdev->raid_disk)==0) { 7530 mddev, rdev) == 0) {
7478 sysfs_unlink_rdev(mddev, rdev); 7531 sysfs_unlink_rdev(mddev, rdev);
7479 rdev->raid_disk = -1; 7532 rdev->raid_disk = -1;
7480 } 7533 }