Re: [PATCH 2/2] md: Fix forward incompatibility from configurable logical block size
"Yu Kuai" <[email protected]>
| Newsgroups | gmane.linux.raid,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi, 在 2025/12/19 17:21, [email protected] 写道: > From: Li Nan <[email protected]> > > Commit 62ed1b582246 ("md: allow configuring logical block size") used > reserved pad to add 'logical_block_size' to metadata. RAID rejects > non-zero reserved pad, so arrays fail when rolling back to old kernels > after booting new ones. > > Set 'logical_block_size' only for newly created arrays to support rollback > to old kernels. Importantly new arrays still won't work on old kernels to > prevent data loss issue from LBS changes. > > For arrays created on old kernels which confirmed not to rollback, > configure LBS by echo 'enable' to md/logical_block_size. > > Fixes: 62ed1b582246 ("md: allow configuring logical block size") > Reported-by: BugReports <[email protected]> > Closes: https://lore.kernel.org/linux-raid/[email protected]/T/#t > Signed-off-by: Li Nan <[email protected]> > --- > drivers/md/md.c | 44 ++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 40 insertions(+), 4 deletions(-) > > diff --git a/drivers/md/md.c b/drivers/md/md.c > index 7c0dd94a4d25..28c9435016fe 100644 > --- a/drivers/md/md.c > +++ b/drivers/md/md.c > @@ -2014,8 +2014,14 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struc > > mddev->max_disks = (4096-256)/2; > > - if (!mddev->logical_block_size) > + if (!mddev->logical_block_size) { > mddev->logical_block_size = le32_to_cpu(sb->logical_block_size); > + if (!mddev->logical_block_size) > + pr_warn("%s: echo 'enable' to md/logical_block_size to prevent data loss issue from LBS changes.\n" > + " Note: After enable, array will not be assembled in old kernels (<= 6.18)\n", > + mdname(mddev)); Looks like this will print the same message for every rdev added to this array, please move the warning to mddev_stack_rdev_limits() as well. > + } > + > > if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) && > mddev->bitmap_info.file == NULL) { > @@ -5983,8 +5989,27 @@ lbs_store(struct mddev *mddev, const char *buf, size_t len) > if (mddev->major_version == 0) > return -EINVAL; > > - if (mddev->pers) > - return -EBUSY; > + if (mddev->pers) { > + if (mddev->logical_block_size) > + return -EBUSY; > + /* > + * To fix forward compatibility issues, LBS is not > + * configured in old kernels array (<=6.18) by default. > + * If the user confirms no rollback to old kernels, > + * enable LBS by writing "enable" — to prevent data > + * loss from LBS changes. > + */ > + if (cmd_match(buf, "enable")) { > + mddev->logical_block_size = > + queue_logical_block_size(mddev->gendisk->queue); > + set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); > + pr_info("%s: config logical block size success, array will not be assembled in old kernels (<= 6.18)\n", > + mdname(mddev)); Instead of a new string "enabled", I'll prefer to echo the exact lbs. > + return len; > + } else { > + return -EBUSY; > + } > + } > > err = kstrtouint(buf, 10, &lbs); > if (err < 0) > @@ -6165,7 +6190,18 @@ int mddev_stack_rdev_limits(struct mddev *mddev, struct queue_limits *lim, > mdname(mddev)); > return -EINVAL; > } > - mddev->logical_block_size = lim->logical_block_size; > + > + /* > + * Fix forward compatibility issue. Only set LBS by default for > + * new array, mddev->events == 0 indicates the array was just > + * created. When assembling an array, read LBS from the superblock > + * instead — LBS is 0 in superblocks created by old kernels. > + */ > + if (!mddev->events && mddev->major_version == 1) { > + pr_info("%s: array will not be assembled in old kernels that lack configurable lbs support (<= 6.18)\n", > + mdname(mddev)); > + mddev->logical_block_size = lim->logical_block_size; > + } > > return 0; > } -- Thansk, Kuai