]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
md: add feature flag MD_FEATURE_RAID0_LAYOUT
authorNeilBrown <neilb@suse.de>
Wed, 18 Dec 2019 14:31:23 +0000 (07:31 -0700)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 29 Jan 2020 02:24:25 +0000 (21:24 -0500)
BugLink: https://bugs.launchpad.net/bugs/1850540
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>
(cherry picked from commit 33f2c35a54dfd75ad0e7e86918dcbe4de799a56c)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/md/md.c
drivers/md/raid0.c
include/uapi/linux/raid/md_p.h

index 81abd706f02932a3c1e85d3069ed63c443667e80..1f22f0cce3a8c2be4bf35a64e9b67caee98e9805 100644 (file)
@@ -1198,6 +1198,8 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev)
                        mddev->new_layout = mddev->layout;
                        mddev->new_chunk_sectors = mddev->chunk_sectors;
                }
+               if (mddev->level == 0)
+                       mddev->layout = -1;
 
                if (sb->state & (1<<MD_SB_CLEAN))
                        mddev->recovery_cp = MaxSector;
@@ -1614,6 +1616,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;
        }
 
+       if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RAID0_LAYOUT) &&
+           sb->level != 0)
+               return -EINVAL;
+
        if (!refdev) {
                ret = 1;
        } else {
@@ -1724,6 +1730,10 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
                        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)
                        set_bit(MD_HAS_JOURNAL, &mddev->flags);
 
@@ -6810,6 +6820,9 @@ static int set_array_info(struct mddev *mddev, mdu_array_info_t *info)
        mddev->external      = 0;
 
        mddev->layout        = info->layout;
+       if (mddev->level == 0)
+               /* Cannot trust RAID0 layout info here */
+               mddev->layout = -1;
        mddev->chunk_sectors = info->chunk_size >> 9;
 
        if (mddev->persistent) {
index 8ce8117c344eafe8edbba286751fbf8bf1689341..dcc8981879adbfec48ebc3815341e191653e73db 100644 (file)
@@ -152,6 +152,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
 
        if (conf->nr_strip_zones == 1) {
                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 ||
                   default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {
                conf->layout = default_layout;
index b0d15c73f6d758db858b9ca0489d3e4978b01323..1f2d8c81f0e0cede75dbf3fc03e3c49558d16f26 100644 (file)
@@ -329,6 +329,7 @@ struct mdp_superblock_1 {
 #define        MD_FEATURE_JOURNAL              512 /* support write cache */
 #define        MD_FEATURE_PPL                  1024 /* support PPL */
 #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       \
                                        |MD_FEATURE_RECOVERY_OFFSET     \
                                        |MD_FEATURE_RESHAPE_ACTIVE      \
@@ -341,6 +342,7 @@ struct mdp_superblock_1 {
                                        |MD_FEATURE_JOURNAL             \
                                        |MD_FEATURE_PPL                 \
                                        |MD_FEATURE_MULTIPLE_PPLS       \
+                                       |MD_FEATURE_RAID0_LAYOUT        \
                                        )
 
 struct r5l_payload_header {