Re: [PATCH] md/raid5: reject a per-device size smaller than one chunk

From: yu kuai

Date: Thu Sep 17 2026 - 03:55:51 EST


在 2026/9/16 17:51, Zizhi Wo 写道:

> From: Zizhi Wo<wozizhi@xxxxxxxxxx>
>
> Both raid5_run() and raid5_resize() align the per-device size down to a
> whole multiple of the chunk size:
>
> mddev->dev_sectors &= ~(chunk_sectors - 1);
>
> Neither checks the result, so a size smaller than one chunk silently
> becomes zero.
>
> In raid5_run() that is harmless: the array size is derived from the same
> zero, so the disk just ends up with no capacity.
>
> In raid5_resize() it leaves the array inconsistent -- mddev->dev_sectors
> becomes zero, while mddev->array_sectors and the gendisk capacity keep the
> previous. A later raid4/raid5 -> raid0 takeover copies the zero into every
> rdev->sectors (raid0_takeover_raid45()), so create_strip_zones() builds a
> strip zone table whose zone_end is zero. Any read then passes
> bio_check_eod() against the stale capacity and hits the BUG() in
> find_zone():
>
> kernel BUG at drivers/md/raid0.c:318!
> Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
> CPU: 45 UID: 0 PID: 1300 Comm: mdadm Not tainted 7.3.0-rc3+ #106 PREEMPT(full)
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc41 04/01/2014
> RIP: 0010:raid0_make_request+0x10cb/0x16a0
> Call Trace:
> <TASK>
> md_handle_request+0x566/0xb40
> __submit_bio+0x2b2/0x600
> submit_bio_noacct_nocheck+0x509/0xb30
> block_read_full_folio+0x364/0x6d0
> filemap_read_folio+0xa2/0x200
> do_read_cache_folio+0x1b6/0x330
> read_part_sector+0xb6/0x2a0
> read_lba+0x17d/0x280
> efi_partition+0x2a6/0x2520
> bdev_disk_changed+0x6e0/0xfa0
> ......
> bdev_open+0x214/0xc40
>
> Reject a size smaller than one chunk in both functions, so that a running
> raid4/raid5 array always has mddev->dev_sectors >= one chunk.
>
> The check is done where the value takes effect, not where it is assigned.
> mddev->dev_sectors is written from several places, and none of them can
> tell whether the value is usable: the chunk size may still change later.
> raid5_run() and raid5_resize() are where every input is final, so one check
> in each covers them all.
>
> Fixes: eea136d69f9f ("md: fix buglet in RAID5 -> RAID0 conversion.")
> Signed-off-by: Zizhi Wo<wozizhi@xxxxxxxxxx>
> ---
> drivers/md/raid5.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
Applied to md-7.4

--
Thanks,
Kuai