Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

NeilBrown and committed by
Song Liu
33f2c35a c84a1372

+18
+13
drivers/md/md.c
··· 1237 1237 mddev->new_layout = mddev->layout; 1238 1238 mddev->new_chunk_sectors = mddev->chunk_sectors; 1239 1239 } 1240 + if (mddev->level == 0) 1241 + mddev->layout = -1; 1240 1242 1241 1243 if (sb->state & (1<<MD_SB_CLEAN)) 1242 1244 mddev->recovery_cp = MaxSector; ··· 1654 1652 rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset; 1655 1653 } 1656 1654 1655 + if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT) && 1656 + sb->level != 0) 1657 + return -EINVAL; 1658 + 1657 1659 if (!refdev) { 1658 1660 ret = 1; 1659 1661 } else { ··· 1767 1761 mddev->new_layout = mddev->layout; 1768 1762 mddev->new_chunk_sectors = mddev->chunk_sectors; 1769 1763 } 1764 + 1765 + if (mddev->level == 0 && 1766 + !(le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT)) 1767 + mddev->layout = -1; 1770 1768 1771 1769 if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) 1772 1770 set_bit(MD_HAS_JOURNAL, &mddev->flags); ··· 6908 6898 mddev->external = 0; 6909 6899 6910 6900 mddev->layout = info->layout; 6901 + if (mddev->level == 0) 6902 + /* Cannot trust RAID0 layout info here */ 6903 + mddev->layout = -1; 6911 6904 mddev->chunk_sectors = info->chunk_size >> 9; 6912 6905 6913 6906 if (mddev->persistent) {
+3
drivers/md/raid0.c
··· 145 145 146 146 if (conf->nr_strip_zones == 1) { 147 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 151 } else if (default_layout == RAID0_ORIG_LAYOUT || 149 152 default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { 150 153 conf->layout = default_layout;
+2
include/uapi/linux/raid/md_p.h
··· 329 329 #define MD_FEATURE_JOURNAL 512 /* support write cache */ 330 330 #define MD_FEATURE_PPL 1024 /* support PPL */ 331 331 #define MD_FEATURE_MULTIPLE_PPLS 2048 /* support for multiple PPLs */ 332 + #define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful for RAID0 */ 332 333 #define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ 333 334 |MD_FEATURE_RECOVERY_OFFSET \ 334 335 |MD_FEATURE_RESHAPE_ACTIVE \ ··· 342 341 |MD_FEATURE_JOURNAL \ 343 342 |MD_FEATURE_PPL \ 344 343 |MD_FEATURE_MULTIPLE_PPLS \ 344 + |MD_FEATURE_RAID0_LAYOUT \ 345 345 ) 346 346 347 347 struct r5l_payload_header {