From e556604c2121338ad532222b524baff8e03d3e84 Mon Sep 17 00:00:00 2001 From: Wu Guanghao Date: Tue, 11 Mar 2025 03:11:55 +0000 Subject: [PATCH] super1: Clear extra flags when initializing metadata When adding a disk to a RAID1 array, the metadata is read from the existing member disks for sync. However, only the bad_blocks flag are copied, the bad_blocks records are not copied, so the bad_blocks records are all zeros. The kernel function super_1_load() detects bad_blocks flag and reads the bad_blocks record, then sets the bad block using badblocks_set(). After the kernel commit 1726c7746783 (badblocks: improve badblocks_set() for multiple ranges handling) if the length of a bad_blocks record is 0, it will return a failure. Therefore the device addition will fail. So when adding a new disk, some flags cannot be sync and need to be clead. Signed-off-by: Wu Guanghao --- super1.c | 3 +++ tests/05r1-add-badblocks | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/05r1-add-badblocks diff --git a/super1.c b/super1.c index 6354bea..e9aa216 100644 --- a/super1.c +++ b/super1.c @@ -1952,6 +1952,9 @@ static int write_init_super1(struct supertype *st) long bm_offset; int raid0_need_layout = 0; + /* Clear extra flags */ + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT); + 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); diff --git a/tests/05r1-add-badblocks b/tests/05r1-add-badblocks new file mode 100644 index 0000000..6192327 --- /dev/null +++ b/tests/05r1-add-badblocks @@ -0,0 +1,24 @@ +# +# create a raid1 with a drive and set badblocks for the drive. +# add a new drive does not cause an error. +# + +# create raid1 +mdadm -CR $md0 -l1 -n2 -e1.0 $dev1 missing +testdev $md0 1 $mdsize1a 64 +sleep 3 + +# set badblocks for the drive +dev1_name=$(basename $dev1) +echo "100 100" > /sys/block/md0/md/dev-$dev1_name/bad_blocks +echo "write_error" > /sys/block/md0/md/dev-$dev1_name/state + +# write badblocks to metadata +dd if=/dev/zero of=$md0 bs=512 count=200 oflag=direct + +# re-add and recovery +mdadm $md0 -a $dev2 +check recovery + +mdadm -S $md0 + -- 2.33.0