summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2019-09-09 02:52:29 -0400
committerSong Liu <songliubraving@fb.com>2019-09-13 16:10:06 -0400
commit33f2c35a54dfd75ad0e7e86918dcbe4de799a56c (patch)
treebb6125970eda98dfc945d1060cfe91ea676f4f7e
parentc84a1372df929033cb1a0441fb57bd3932f39ac9 (diff)
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: Guoqing Jiang <guoqing.jiang@cloud.ionos.com> Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Song Liu <songliubraving@fb.com>
-rw-r--r--drivers/md/md.c13
-rw-r--r--drivers/md/raid0.c3
-rw-r--r--include/uapi/linux/raid/md_p.h2
3 files changed, 18 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 73d5a1b04022..1be7abeb24fd 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1237,6 +1237,8 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev)
1237 mddev->new_layout = mddev->layout; 1237 mddev->new_layout = mddev->layout;
1238 mddev->new_chunk_sectors = mddev->chunk_sectors; 1238 mddev->new_chunk_sectors = mddev->chunk_sectors;
1239 } 1239 }
1240 if (mddev->level == 0)
1241 mddev->layout = -1;
1240 1242
1241 if (sb->state & (1<<MD_SB_CLEAN)) 1243 if (sb->state & (1<<MD_SB_CLEAN))
1242 mddev->recovery_cp = MaxSector; 1244 mddev->recovery_cp = MaxSector;
@@ -1652,6 +1654,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
1652 rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset; 1654 rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset;
1653 } 1655 }
1654 1656
1657 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT) &&
1658 sb->level != 0)
1659 return -EINVAL;
1660
1655 if (!refdev) { 1661 if (!refdev) {
1656 ret = 1; 1662 ret = 1;
1657 } else { 1663 } else {
@@ -1762,6 +1768,10 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
1762 mddev->new_chunk_sectors = mddev->chunk_sectors; 1768 mddev->new_chunk_sectors = mddev->chunk_sectors;
1763 } 1769 }
1764 1770
1771 if (mddev->level == 0 &&
1772 !(le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT))
1773 mddev->layout = -1;
1774
1765 if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) 1775 if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL)
1766 set_bit(MD_HAS_JOURNAL, &mddev->flags); 1776 set_bit(MD_HAS_JOURNAL, &mddev->flags);
1767 1777
@@ -6898,6 +6908,9 @@ static int set_array_info(struct mddev *mddev, mdu_array_info_t *info)
6898 mddev->external = 0; 6908 mddev->external = 0;
6899 6909
6900 mddev->layout = info->layout; 6910 mddev->layout = info->layout;
6911 if (mddev->level == 0)
6912 /* Cannot trust RAID0 layout info here */
6913 mddev->layout = -1;
6901 mddev->chunk_sectors = info->chunk_size >> 9; 6914 mddev->chunk_sectors = info->chunk_size >> 9;
6902 6915
6903 if (mddev->persistent) { 6916 if (mddev->persistent) {
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index ec611abda835..f61693e59684 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -145,6 +145,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
145 145
146 if (conf->nr_strip_zones == 1) { 146 if (conf->nr_strip_zones == 1) {
147 conf->layout = RAID0_ORIG_LAYOUT; 147 conf->layout = RAID0_ORIG_LAYOUT;
148 } else if (mddev->layout == RAID0_ORIG_LAYOUT ||
149 mddev->layout == RAID0_ALT_MULTIZONE_LAYOUT) {
150 conf->layout = mddev->layout;
148 } else if (default_layout == RAID0_ORIG_LAYOUT || 151 } else if (default_layout == RAID0_ORIG_LAYOUT ||
149 default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { 152 default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {
150 conf->layout = default_layout; 153 conf->layout = default_layout;
diff --git a/include/uapi/linux/raid/md_p.h b/include/uapi/linux/raid/md_p.h
index b0d15c73f6d7..1f2d8c81f0e0 100644
--- a/include/uapi/linux/raid/md_p.h
+++ b/include/uapi/linux/raid/md_p.h
@@ -329,6 +329,7 @@ struct mdp_superblock_1 {
329#define MD_FEATURE_JOURNAL 512 /* support write cache */ 329#define MD_FEATURE_JOURNAL 512 /* support write cache */
330#define MD_FEATURE_PPL 1024 /* support PPL */ 330#define MD_FEATURE_PPL 1024 /* support PPL */
331#define MD_FEATURE_MULTIPLE_PPLS 2048 /* support for multiple PPLs */ 331#define MD_FEATURE_MULTIPLE_PPLS 2048 /* support for multiple PPLs */
332#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful for RAID0 */
332#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ 333#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \
333 |MD_FEATURE_RECOVERY_OFFSET \ 334 |MD_FEATURE_RECOVERY_OFFSET \
334 |MD_FEATURE_RESHAPE_ACTIVE \ 335 |MD_FEATURE_RESHAPE_ACTIVE \
@@ -341,6 +342,7 @@ struct mdp_superblock_1 {
341 |MD_FEATURE_JOURNAL \ 342 |MD_FEATURE_JOURNAL \
342 |MD_FEATURE_PPL \ 343 |MD_FEATURE_PPL \
343 |MD_FEATURE_MULTIPLE_PPLS \ 344 |MD_FEATURE_MULTIPLE_PPLS \
345 |MD_FEATURE_RAID0_LAYOUT \
344 ) 346 )
345 347
346struct r5l_payload_header { 348struct r5l_payload_header {