diff options
Diffstat (limited to 'drivers/md/dm-raid.c')
| -rw-r--r-- | drivers/md/dm-raid.c | 44 | 
1 files changed, 29 insertions, 15 deletions
| diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index cab12b2251ba..bf4a467fc73a 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -1853,6 +1853,7 @@ static int rs_check_takeover(struct raid_set *rs)  		    ((mddev->layout == ALGORITHM_PARITY_N && mddev->new_layout == ALGORITHM_PARITY_N) ||  		     __within_range(mddev->new_layout, ALGORITHM_LEFT_ASYMMETRIC, ALGORITHM_RIGHT_SYMMETRIC)))  			return 0; +		break;  	default:  		break; @@ -1868,6 +1869,14 @@ static bool rs_takeover_requested(struct raid_set *rs)  	return rs->md.new_level != rs->md.level;  } +/* True if layout is set to reshape. */ +static bool rs_is_layout_change(struct raid_set *rs, bool use_mddev) +{ +	return (use_mddev ? rs->md.delta_disks : rs->delta_disks) || +	       rs->md.new_layout != rs->md.layout || +	       rs->md.new_chunk_sectors != rs->md.chunk_sectors; +} +  /* True if @rs is requested to reshape by ctr */  static bool rs_reshape_requested(struct raid_set *rs)  { @@ -1880,9 +1889,7 @@ static bool rs_reshape_requested(struct raid_set *rs)  	if (rs_is_raid0(rs))  		return false; -	change = mddev->new_layout != mddev->layout || -		 mddev->new_chunk_sectors != mddev->chunk_sectors || -		 rs->delta_disks; +	change = rs_is_layout_change(rs, false);  	/* Historical case to support raid1 reshape without delta disks */  	if (rs_is_raid1(rs)) { @@ -2817,7 +2824,7 @@ static sector_t _get_reshape_sectors(struct raid_set *rs)  }  /* - * + * Reshape:   * - change raid layout   * - change chunk size   * - add disks @@ -2927,6 +2934,20 @@ static int rs_setup_reshape(struct raid_set *rs)  }  /* + * If the md resync thread has updated superblock with max reshape position + * at the end of a reshape but not (yet) reset the layout configuration + * changes -> reset the latter. + */ +static void rs_reset_inconclusive_reshape(struct raid_set *rs) +{ +	if (!rs_is_reshaping(rs) && rs_is_layout_change(rs, true)) { +		rs_set_cur(rs); +		rs->md.delta_disks = 0; +		rs->md.reshape_backwards = 0; +	} +} + +/*   * Enable/disable discard support on RAID set depending on   * RAID level and discard properties of underlying RAID members.   */ @@ -3212,11 +3233,14 @@ size_check:  	if (r)  		goto bad; +	/* Catch any inconclusive reshape superblock content. */ +	rs_reset_inconclusive_reshape(rs); +  	/* Start raid set read-only and assumed clean to change in raid_resume() */  	rs->md.ro = 1;  	rs->md.in_sync = 1; -	/* Keep array frozen */ +	/* Keep array frozen until resume. */  	set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);  	/* Has to be held on running the array */ @@ -3230,7 +3254,6 @@ size_check:  	}  	r = md_start(&rs->md); -  	if (r) {  		ti->error = "Failed to start raid array";  		mddev_unlock(&rs->md); @@ -3727,15 +3750,6 @@ static void raid_io_hints(struct dm_target *ti, struct queue_limits *limits)  	blk_limits_io_min(limits, chunk_size_bytes);  	blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs)); - -	/* -	 * RAID0 and RAID10 personalities require bio splitting, -	 * RAID1/4/5/6 don't and process large discard bios properly. -	 */ -	if (rs_is_raid0(rs) || rs_is_raid10(rs)) { -		limits->discard_granularity = chunk_size_bytes; -		limits->max_discard_sectors = rs->md.chunk_sectors; -	}  }  static void raid_postsuspend(struct dm_target *ti) | 
