aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid.c
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2016-06-27 08:44:09 -0400
committerMike Snitzer <snitzer@redhat.com>2016-07-18 15:37:30 -0400
commit2a5556c2a86f77ff6085f2cae798728cda47e2c4 (patch)
treed56b17ca2b8fd49c0945e37fcb184f6a7ab60589 /drivers/md/dm-raid.c
parent345a6cdc250d1519c5d15576965629eab6858257 (diff)
dm raid: allow resize during recovery
Resizing a RAID set during recovery can be allowed, because the MD resynchronization thread will either stop any ongoing recovery in case of shrinking below the current recovery position or carry on recovery to the new size if the set is growing. Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r--drivers/md/dm-raid.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 1ff469f14ff2..846c58d2bcf9 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -2682,6 +2682,7 @@ static void configure_discard_support(struct raid_set *rs)
2682static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) 2682static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2683{ 2683{
2684 int r; 2684 int r;
2685 bool resize = false;
2685 struct raid_type *rt; 2686 struct raid_type *rt;
2686 unsigned num_raid_params, num_raid_devs; 2687 unsigned num_raid_params, num_raid_devs;
2687 sector_t calculated_dev_sectors; 2688 sector_t calculated_dev_sectors;
@@ -2760,7 +2761,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2760 if (r) 2761 if (r)
2761 goto bad; 2762 goto bad;
2762 2763
2763 rs_setup_recovery(rs, calculated_dev_sectors); 2764 resize = calculated_dev_sectors != rs->dev[0].rdev.sectors;
2764 2765
2765 INIT_WORK(&rs->md.event_work, do_table_event); 2766 INIT_WORK(&rs->md.event_work, do_table_event);
2766 ti->private = rs; 2767 ti->private = rs;
@@ -2770,8 +2771,6 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2770 rs_config_restore(rs, &rs_layout); 2771 rs_config_restore(rs, &rs_layout);
2771 2772
2772 if (test_bit(MD_ARRAY_FIRST_USE, &rs->md.flags)) { 2773 if (test_bit(MD_ARRAY_FIRST_USE, &rs->md.flags)) {
2773 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2774 rs_set_new(rs);
2775 /* A new raid6 set has to be recovered to ensure proper parity and Q-Syndrome */ 2774 /* A new raid6 set has to be recovered to ensure proper parity and Q-Syndrome */
2776 if (rs_is_raid6(rs) && 2775 if (rs_is_raid6(rs) &&
2777 test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags)) { 2776 test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags)) {
@@ -2780,16 +2779,18 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2780 goto bad; 2779 goto bad;
2781 } 2780 }
2782 rs_setup_recovery(rs, 0); 2781 rs_setup_recovery(rs, 0);
2783 } else if (rs_is_recovering(rs) || rs_is_reshaping(rs)) { 2782 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2784 /* Have to reject size change request during recovery/reshape */ 2783 rs_set_new(rs);
2785 if (calculated_dev_sectors != rs->dev[0].rdev.sectors) { 2784 } else if (rs_is_recovering(rs)) {
2786 ti->error = rs_is_recovering(rs) ? 2785 ; /* skip setup rs */
2787 "Can't resize a recovering raid set" : 2786 } else if (rs_is_reshaping(rs)) {
2788 "Can't resize a reshaping raid set"; 2787 /* Have to reject size change request during reshape */
2788 if (resize) {
2789 ti->error = "Can't resize a reshaping raid set";
2789 r = -EPERM; 2790 r = -EPERM;
2790 goto bad; 2791 goto bad;
2791 } 2792 }
2792 /* skip setup rs */ 2793 ; /* skip setup rs */
2793 } else if (rs_takeover_requested(rs)) { 2794 } else if (rs_takeover_requested(rs)) {
2794 if (rs_is_reshaping(rs)) { 2795 if (rs_is_reshaping(rs)) {
2795 ti->error = "Can't takeover a reshaping raid set"; 2796 ti->error = "Can't takeover a reshaping raid set";
@@ -2799,8 +2800,9 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2799 2800
2800 /* 2801 /*
2801 * If a takeover is needed, userspace sets any additional 2802 * If a takeover is needed, userspace sets any additional
2802 * devices to rebuild, so just set the level to the new 2803 * devices to rebuild, so set the level to the new requested
2803 * requested one and allow the raid set to run 2804 * one, prohibit requesting recovery, allow the raid
2805 * set to run and store superblocks during resume.
2804 */ 2806 */
2805 r = rs_check_takeover(rs); 2807 r = rs_check_takeover(rs);
2806 if (r) 2808 if (r)
@@ -2812,6 +2814,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2812 2814
2813 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); 2815 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2814 set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags); 2816 set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
2817 rs_setup_recovery(rs, MaxSector);
2815 rs_set_new(rs); 2818 rs_set_new(rs);
2816 } else if (rs_reshape_requested(rs)) { 2819 } else if (rs_reshape_requested(rs)) {
2817 if (rs_is_reshaping(rs)) { 2820 if (rs_is_reshaping(rs)) {
@@ -2868,16 +2871,17 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
2868 if (rs->md.raid_disks < rs->raid_disks) 2871 if (rs->md.raid_disks < rs->raid_disks)
2869 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); 2872 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2870 2873
2871 rs_set_cur(rs);
2872 rs_setup_recovery(rs, MaxSector); 2874 rs_setup_recovery(rs, MaxSector);
2873 } else {
2874 rs_set_cur(rs); 2875 rs_set_cur(rs);
2876 } else {
2877 /* May not set recovery when a device rebuild is requested */
2875 if (test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags)) { 2878 if (test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags)) {
2876 rs_setup_recovery(rs, MaxSector); 2879 rs_setup_recovery(rs, MaxSector);
2877 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); 2880 set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2878 } else 2881 } else
2879 rs_setup_recovery(rs, test_bit(__CTR_FLAG_SYNC, &rs->ctr_flags) ? 2882 rs_setup_recovery(rs, test_bit(__CTR_FLAG_SYNC, &rs->ctr_flags) ?
2880 0 : calculated_dev_sectors); 2883 0 : (resize ? calculated_dev_sectors : MaxSector));
2884 rs_set_cur(rs);
2881 } 2885 }
2882 2886
2883 /* If constructor requested it, change data and new_data offsets */ 2887 /* If constructor requested it, change data and new_data offsets */