]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm/super1: Add MD_FEATURE_RAID0_LAYOUT if kernel>=5.4
authorXiao Ni <xni@redhat.com>
Tue, 17 Oct 2023 12:35:46 +0000 (20:35 +0800)
committerJes Sorensen <jes@trained-monkey.org>
Thu, 26 Oct 2023 21:48:50 +0000 (17:48 -0400)
After and include kernel v5.4, it adds one feature bit MD_FEATURE_RAID0_LAYOUT.
It must need to specify a layout for raid0 with more than one zone. But for
raid0 with one zone, in fact it also has a defalut layout.

Now for raid0 with one zone, *unknown* layout can be seen when running mdadm -D
command. It's the reason that mdadm doesn't set MD_FEATURE_RAID0_LAYOUT for
raid0 with one zone. Then in kernel space, super_1_validate sets mddev->layout
to -1 because of no MD_FEATURE_RAID0_LAYOUT. In fact, in raid0 io path, it
uses the default layout. Set raid0_need_layout to true if kernel_version<=v5.4.

Fixes: 329dfc28debb ('Create: add support for RAID0 layouts.')
Signed-off-by: Xiao Ni <xni@redhat.com>
Reviewed-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
super1.c

index 856b0208266237311bbbcc08f0dbe2909643ecd1..1da71b98d29eb3503a72df96afee849dbe20c50f 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1967,6 +1967,14 @@ fail_to_write:
        return 1;
 }
 
+static bool has_raid0_layout(struct mdp_superblock_1 *sb)
+{
+       if (sb->level == 0 && sb->layout != 0)
+               return true;
+       else
+               return false;
+}
+
 static int write_init_super1(struct supertype *st)
 {
        struct mdp_superblock_1 *sb = st->sb;
@@ -1978,12 +1986,17 @@ static int write_init_super1(struct supertype *st)
        unsigned long long sb_offset;
        unsigned long long data_offset;
        long bm_offset;
-       int raid0_need_layout = 0;
+       bool raid0_need_layout = false;
+
+       /* Since linux kernel v5.4, raid0 always has a layout */
+       if (has_raid0_layout(sb) && get_linux_version() >= 5004000)
+               raid0_need_layout = true;
 
        for (di = st->info; di; di = di->next) {
                if (di->disk.state & (1 << MD_DISK_JOURNAL))
                        sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
-               if (sb->level == 0 && sb->layout != 0) {
+               if (has_raid0_layout(sb) && !raid0_need_layout) {
+
                        struct devinfo *di2 = st->info;
                        unsigned long long s1, s2;
                        s1 = di->dev_size;
@@ -1995,7 +2008,7 @@ static int write_init_super1(struct supertype *st)
                                s2 -= di2->data_offset;
                        s2 /= __le32_to_cpu(sb->chunksize);
                        if (s1 != s2)
-                               raid0_need_layout = 1;
+                               raid0_need_layout = true;
                }
        }