Skip to content

Commit 9e193a0

Browse files
committed
Merge tag 'md-6.19-20251231' of gitolite.kernel.org:pub/scm/linux/kernel/git/mdraid/linux into block-6.19
Pull MD fixes from Yu Kuai: "- Fix null-pointer dereference in raid5 sysfs group_thread_cnt store (Tuo Li) - Fix possible mempool corruption during raid1 raid_disks update via sysfs (FengWei Shih) - Fix logical_block_size configuration being overwritten during super_1_validate() (Li Nan) - Fix forward incompatibility with configurable logical block size: arrays assembled on new kernels could not be assembled on kernels <=6.18 due to non-zero reserved pad rejection (Li Nan) - Fix static checker warning about iterator not incremented (Li Nan)" * tag 'md-6.19-20251231' of gitolite.kernel.org:pub/scm/linux/kernel/git/mdraid/linux: md: Fix forward incompatibility from configurable logical block size md: Fix logical_block_size configuration being overwritten md: suspend array while updating raid_disks via sysfs md/raid5: fix possible null-pointer dereferences in raid5_store_group_thread_cnt() md: Fix static checker warning in analyze_sbs
2 parents 10845a1 + a4166f1 commit 9e193a0

2 files changed

Lines changed: 56 additions & 15 deletions

File tree

drivers/md/md.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,6 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struc
19991999
mddev->layout = le32_to_cpu(sb->layout);
20002000
mddev->raid_disks = le32_to_cpu(sb->raid_disks);
20012001
mddev->dev_sectors = le64_to_cpu(sb->size);
2002-
mddev->logical_block_size = le32_to_cpu(sb->logical_block_size);
20032002
mddev->events = ev1;
20042003
mddev->bitmap_info.offset = 0;
20052004
mddev->bitmap_info.space = 0;
@@ -2015,6 +2014,9 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struc
20152014

20162015
mddev->max_disks = (4096-256)/2;
20172016

2017+
if (!mddev->logical_block_size)
2018+
mddev->logical_block_size = le32_to_cpu(sb->logical_block_size);
2019+
20182020
if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) &&
20192021
mddev->bitmap_info.file == NULL) {
20202022
mddev->bitmap_info.offset =
@@ -3882,7 +3884,6 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
38823884

38833885
static int analyze_sbs(struct mddev *mddev)
38843886
{
3885-
int i;
38863887
struct md_rdev *rdev, *freshest, *tmp;
38873888

38883889
freshest = NULL;
@@ -3909,11 +3910,9 @@ static int analyze_sbs(struct mddev *mddev)
39093910
super_types[mddev->major_version].
39103911
validate_super(mddev, NULL/*freshest*/, freshest);
39113912

3912-
i = 0;
39133913
rdev_for_each_safe(rdev, tmp, mddev) {
39143914
if (mddev->max_disks &&
3915-
(rdev->desc_nr >= mddev->max_disks ||
3916-
i > mddev->max_disks)) {
3915+
rdev->desc_nr >= mddev->max_disks) {
39173916
pr_warn("md: %s: %pg: only %d devices permitted\n",
39183917
mdname(mddev), rdev->bdev,
39193918
mddev->max_disks);
@@ -4407,7 +4406,7 @@ raid_disks_store(struct mddev *mddev, const char *buf, size_t len)
44074406
if (err < 0)
44084407
return err;
44094408

4410-
err = mddev_lock(mddev);
4409+
err = mddev_suspend_and_lock(mddev);
44114410
if (err)
44124411
return err;
44134412
if (mddev->pers)
@@ -4432,7 +4431,7 @@ raid_disks_store(struct mddev *mddev, const char *buf, size_t len)
44324431
} else
44334432
mddev->raid_disks = n;
44344433
out_unlock:
4435-
mddev_unlock(mddev);
4434+
mddev_unlock_and_resume(mddev);
44364435
return err ? err : len;
44374436
}
44384437
static struct md_sysfs_entry md_raid_disks =
@@ -5981,13 +5980,33 @@ lbs_store(struct mddev *mddev, const char *buf, size_t len)
59815980
if (mddev->major_version == 0)
59825981
return -EINVAL;
59835982

5984-
if (mddev->pers)
5985-
return -EBUSY;
5986-
59875983
err = kstrtouint(buf, 10, &lbs);
59885984
if (err < 0)
59895985
return -EINVAL;
59905986

5987+
if (mddev->pers) {
5988+
unsigned int curr_lbs;
5989+
5990+
if (mddev->logical_block_size)
5991+
return -EBUSY;
5992+
/*
5993+
* To fix forward compatibility issues, LBS is not
5994+
* configured for arrays from old kernels (<=6.18) by default.
5995+
* If the user confirms no rollback to old kernels,
5996+
* enable LBS by writing current LBS — to prevent data
5997+
* loss from LBS changes.
5998+
*/
5999+
curr_lbs = queue_logical_block_size(mddev->gendisk->queue);
6000+
if (lbs != curr_lbs)
6001+
return -EINVAL;
6002+
6003+
mddev->logical_block_size = curr_lbs;
6004+
set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
6005+
pr_info("%s: logical block size configured successfully, array will not be assembled in old kernels (<= 6.18)\n",
6006+
mdname(mddev));
6007+
return len;
6008+
}
6009+
59916010
err = mddev_lock(mddev);
59926011
if (err)
59936012
goto unlock;
@@ -6163,7 +6182,27 @@ int mddev_stack_rdev_limits(struct mddev *mddev, struct queue_limits *lim,
61636182
mdname(mddev));
61646183
return -EINVAL;
61656184
}
6166-
mddev->logical_block_size = lim->logical_block_size;
6185+
6186+
/* Only 1.x meta needs to set logical block size */
6187+
if (mddev->major_version == 0)
6188+
return 0;
6189+
6190+
/*
6191+
* Fix forward compatibility issue. Only set LBS by default for
6192+
* new arrays, mddev->events == 0 indicates the array was just
6193+
* created. When assembling an array, read LBS from the superblock
6194+
* instead — LBS is 0 in superblocks created by old kernels.
6195+
*/
6196+
if (!mddev->events) {
6197+
pr_info("%s: array will not be assembled in old kernels that lack configurable LBS support (<= 6.18)\n",
6198+
mdname(mddev));
6199+
mddev->logical_block_size = lim->logical_block_size;
6200+
}
6201+
6202+
if (!mddev->logical_block_size)
6203+
pr_warn("%s: echo current LBS to md/logical_block_size to prevent data loss issues from LBS changes.\n"
6204+
"\tNote: After setting, array will not be assembled in old kernels (<= 6.18)\n",
6205+
mdname(mddev));
61676206

61686207
return 0;
61696208
}

drivers/md/raid5.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7187,12 +7187,14 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
71877187
err = mddev_suspend_and_lock(mddev);
71887188
if (err)
71897189
return err;
7190+
conf = mddev->private;
7191+
if (!conf) {
7192+
mddev_unlock_and_resume(mddev);
7193+
return -ENODEV;
7194+
}
71907195
raid5_quiesce(mddev, true);
71917196

7192-
conf = mddev->private;
7193-
if (!conf)
7194-
err = -ENODEV;
7195-
else if (new != conf->worker_cnt_per_group) {
7197+
if (new != conf->worker_cnt_per_group) {
71967198
old_groups = conf->worker_groups;
71977199
if (old_groups)
71987200
flush_workqueue(raid5_wq);

0 commit comments

Comments
 (0)