Commit 33f2c35a authored by NeilBrown's avatar NeilBrown Committed by Song Liu
Browse files

md: add feature flag MD_FEATURE_RAID0_LAYOUT



Due to a bug introduced in Linux 3.14 we cannot determine the
correctly layout for a multi-zone RAID0 array - there are two
possibilities.

It is possible to tell the kernel which to chose using a module
parameter, but this can be clumsy to use.  It would be best if
the choice were recorded in the metadata.
So add a feature flag for this purpose.
If it is set, then the 'layout' field of the superblock is used
to determine which layout to use.

If this flag is not set, then mddev->layout gets set to -1,
which causes the module parameter to be required.

Acked-by: default avatarGuoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
parent c84a1372
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -1237,6 +1237,8 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev)
			mddev->new_layout = mddev->layout;
			mddev->new_layout = mddev->layout;
			mddev->new_chunk_sectors = mddev->chunk_sectors;
			mddev->new_chunk_sectors = mddev->chunk_sectors;
		}
		}
		if (mddev->level == 0)
			mddev->layout = -1;


		if (sb->state & (1<<MD_SB_CLEAN))
		if (sb->state & (1<<MD_SB_CLEAN))
			mddev->recovery_cp = MaxSector;
			mddev->recovery_cp = MaxSector;
@@ -1652,6 +1654,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
		rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset;
		rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset;
	}
	}


	if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT) &&
	    sb->level != 0)
		return -EINVAL;

	if (!refdev) {
	if (!refdev) {
		ret = 1;
		ret = 1;
	} else {
	} else {
@@ -1762,6 +1768,10 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
			mddev->new_chunk_sectors = mddev->chunk_sectors;
			mddev->new_chunk_sectors = mddev->chunk_sectors;
		}
		}


		if (mddev->level == 0 &&
		    !(le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT))
			mddev->layout = -1;

		if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL)
		if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL)
			set_bit(MD_HAS_JOURNAL, &mddev->flags);
			set_bit(MD_HAS_JOURNAL, &mddev->flags);


@@ -6898,6 +6908,9 @@ static int set_array_info(struct mddev *mddev, mdu_array_info_t *info)
	mddev->external	     = 0;
	mddev->external	     = 0;


	mddev->layout        = info->layout;
	mddev->layout        = info->layout;
	if (mddev->level == 0)
		/* Cannot trust RAID0 layout info here */
		mddev->layout = -1;
	mddev->chunk_sectors = info->chunk_size >> 9;
	mddev->chunk_sectors = info->chunk_size >> 9;


	if (mddev->persistent) {
	if (mddev->persistent) {
+3 −0
Original line number Original line Diff line number Diff line
@@ -145,6 +145,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)


	if (conf->nr_strip_zones == 1) {
	if (conf->nr_strip_zones == 1) {
		conf->layout = RAID0_ORIG_LAYOUT;
		conf->layout = RAID0_ORIG_LAYOUT;
	} else if (mddev->layout == RAID0_ORIG_LAYOUT ||
		   mddev->layout == RAID0_ALT_MULTIZONE_LAYOUT) {
		conf->layout = mddev->layout;
	} else if (default_layout == RAID0_ORIG_LAYOUT ||
	} else if (default_layout == RAID0_ORIG_LAYOUT ||
		   default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {
		   default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {
		conf->layout = default_layout;
		conf->layout = default_layout;
+2 −0
Original line number Original line Diff line number Diff line
@@ -329,6 +329,7 @@ struct mdp_superblock_1 {
#define	MD_FEATURE_JOURNAL		512 /* support write cache */
#define	MD_FEATURE_JOURNAL		512 /* support write cache */
#define	MD_FEATURE_PPL			1024 /* support PPL */
#define	MD_FEATURE_PPL			1024 /* support PPL */
#define	MD_FEATURE_MULTIPLE_PPLS	2048 /* support for multiple PPLs */
#define	MD_FEATURE_MULTIPLE_PPLS	2048 /* support for multiple PPLs */
#define	MD_FEATURE_RAID0_LAYOUT		4096 /* layout is meaningful for RAID0 */
#define	MD_FEATURE_ALL			(MD_FEATURE_BITMAP_OFFSET	\
#define	MD_FEATURE_ALL			(MD_FEATURE_BITMAP_OFFSET	\
					|MD_FEATURE_RECOVERY_OFFSET	\
					|MD_FEATURE_RECOVERY_OFFSET	\
					|MD_FEATURE_RESHAPE_ACTIVE	\
					|MD_FEATURE_RESHAPE_ACTIVE	\
@@ -341,6 +342,7 @@ struct mdp_superblock_1 {
					|MD_FEATURE_JOURNAL		\
					|MD_FEATURE_JOURNAL		\
					|MD_FEATURE_PPL			\
					|MD_FEATURE_PPL			\
					|MD_FEATURE_MULTIPLE_PPLS	\
					|MD_FEATURE_MULTIPLE_PPLS	\
					|MD_FEATURE_RAID0_LAYOUT	\
					)
					)


struct r5l_payload_header {
struct r5l_payload_header {