Re: [PATCH v4 10/25] md/md-llbitmap: allocate page controls independently

[email protected] Sat, 01 Aug 2026 17:47:56 +0000
Newsgroups org.kernel.vger.linux-raid
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 2 potential issue(=
s) to consider:

New issues:
- [Critical] Unflushed zeroed pages create a memory-disk inconsistency, lea=
ding to silent parity corruption on crash/reboot after an array resize.

Pre-existing issues:
- [High] Incomplete fix for out-of-bounds array access on `pctl` during max=
imum in-place array growth.
--

--- Patch [10]: [PATCH v4 10/25] md/md-llbitmap: allocate page controls ind=
ependently ---
commit 325d92bcc68f880073f4c6b96714394c0bafe835
Author: Yu Kuai <[email protected]>

md/md-llbitmap: allocate page controls independently

This patch allocates one llbitmap page-control object at a time and frees
each object through the same model. It also updates llbitmap_read_page() to
return a zeroed page without reading from disk when the page index is beyond
the current bitmap size.

> diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
> index 3417da288e994..d12b3dba6ae15 100644
> --- a/drivers/md/md-llbitmap.c
> +++ b/drivers/md/md-llbitmap.c
[ ... ]
> @@ -526,6 +532,8 @@ static struct page *llbitmap_read_page(struct llbitma=
p *llbitmap, int idx)
>  	page =3D alloc_page(GFP_NOIO | __GFP_ZERO);
>  	if (!page)
>  		return ERR_PTR(-ENOMEM);
> +	if (idx >=3D llbitmap_used_pages(llbitmap, llbitmap->chunks))
> +		return page;

[Severity: Critical]
Does this new bypass create a memory-disk inconsistency?

By returning a zeroed page in memory without reading or flushing to disk, t=
he
physical disk is left containing uninitialized garbage. If the array is
reshaped and expands into this pre-allocated region, a crash before the new
region is fully written could expose the disk garbage to the state machine =
on
the subsequent boot. If the garbage matches states like BitClean, resync
might be incorrectly skipped for the new region.

> =20
>  	rdev_for_each(rdev, mddev) {
[ ... ]
> +static unsigned int llbitmap_reserved_pages(struct llbitmap *llbitmap)
> +{
> +	return DIV_ROUND_UP(llbitmap->mddev->bitmap_info.space << SECTOR_SHIFT,
> +			    PAGE_SIZE);
> +}

[Severity: High]
This isn't a bug introduced by this patch, but does this calculation
under-allocate the array by one page for the maximum allowed chunk size?

This calculation omits BITMAP_DATA_OFFSET. Because llbitmap_resize() allows
chunks to grow up to space << SECTOR_SHIFT, the maximum used_pages (which
correctly includes the offset) can exceed reserved_pages by 1.

When pos approaches the maximum allowed chunks in llbitmap_write():

    pos +=3D BITMAP_DATA_OFFSET;
    idx =3D pos >> PAGE_SHIFT;

the offset causes idx to exceed the pre-allocated bounds of the pctl array,
which could lead to out-of-bounds memory corruption.

> +
> +static int llbitmap_alloc_pages(struct llbitmap *llbitmap)
> +{
[ ... ]

--=20
Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260801172519.2982=
[email protected]?part=3D10