Re: [PATCH v5 19/29] md/md-llbitmap: add reshape range mapping helpers
[email protected] Sun, 02 Aug 2026 20:31:17 +0000
| Newsgroups | org.kernel.vger.linux-raid |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 4 potential issue(= s) to consider: - [Critical] Missing implementation of `bitmap_array_sectors` and `bitmap_s= ector_map` in RAID personalities breaks range mapping and drops valid array= writes. - [Critical] Omitted post-mapping clamp allows out-of-bounds offsets to tri= gger out-of-bounds array accesses in `llbitmap_start_write`. - [Critical] Decoupled reshape geometry logic causes `start_sync` to decode= modified bits incorrectly during array recovery. - [High] Skipping reshape boundary splitting when `MD_RECOVERY_RESHAPE` is = clear corrupts straddling bios. -- --- Patch [19]: [PATCH v5 19/29] md/md-llbitmap: add reshape range mapping = helpers --- commit 633da220a726aec9691f97e3c1481f36882f4315 Author: Yu Kuai <[email protected]> md/md-llbitmap: add reshape range mapping helpers Teach llbitmap to choose old versus new geometry during reshape and to encode exact bitmap ranges for the active geometry. This is the mapping groundwork for checkpoint remapping. Link: https://lore.kernel.org/all/20260726185916.2223460-1-mykola@meshstor.= io/ > diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c > index f8a1b0f79be6a..fa16a4224c45a 100644 > --- a/drivers/md/md-llbitmap.c > +++ b/drivers/md/md-llbitmap.c [ ... ] > +static sector_t llbitmap_logical_size(struct llbitmap *llbitmap, bool pr= evious) > +{ > + struct mddev *mddev =3D llbitmap->mddev; > + > + if (!mddev->private || !mddev->pers || > + !mddev->pers->bitmap_array_sectors) > + return llbitmap_personality_sync_size(llbitmap, previous); > + return mddev->pers->bitmap_array_sectors(mddev, previous); > +} [Severity: Critical] Since bitmap_array_sectors is absent from all RAID personalities in this patch series, won't this always fall back to llbitmap_personality_sync_size()? If a write is issued to a RAID5 array at a logical offset greater than dev_sectors, it appears this will incorrectly use the physical component size (dev_sectors) as the limit for the logical array offset, causing llbitmap_map_layout() to drop valid array writes. [ ... ] > +static void llbitmap_map_layout(struct llbitmap *llbitmap, sector_t *off= set, > + unsigned long *sectors, bool previous) > +{ [ ... ] > + if (llbitmap->mddev->pers->bitmap_sector_map) > + llbitmap->mddev->pers->bitmap_sector_map(llbitmap->mddev, offset, > + sectors, previous); > + else if (!previous && llbitmap->mddev->pers->bitmap_sector) > + llbitmap->mddev->pers->bitmap_sector(llbitmap->mddev, offset, > + sectors); > +} [Severity: Critical] The commit message states we need to keep the existing sync-size clamp after mapping, but does this code actually enforce that post-mapping clamp? Without a clamp against llbitmap_personality_sync_size() here at the end of the function, could an out-of-bounds logical offset bypass filtering? If that happens, llbitmap_start_write() could calculate an out-of-bounds page_start index and trigger memory corruption inside llbitmap_raise_barrier() before the state machine drops it. [ ... ] > +static void llbitmap_encode_range(struct llbitmap *llbitmap, sector_t *o= ffset, > + unsigned long *sectors, bool previous) > +{ > + unsigned long chunksize =3D previous ? llbitmap->chunksize : > + llbitmap->reshape_chunksize; [ ... ] > + start =3D div64_u64(*offset, chunksize); > + end =3D div64_u64(*offset + *sectors - 1, chunksize); > + *offset =3D (sector_t)start << llbitmap->chunkshift; > + *sectors =3D (end - start + 1) << llbitmap->chunkshift; > +} [Severity: Critical] Does this decoupling of reshape geometry logic cause issues for the sync pa= th during recovery? Here, writers calculate the chunk index using the new geometry (reshape_chunksize) but scale it using the old chunkshift. Later, during array recovery, llbitmap_start_sync() unconditionally shifts the physical component offset by the old chunkshift: unsigned long p =3D offset >> llbitmap->chunkshift; Will this mismatch cause llbitmap_start_sync() to decode the wrong bit index and skip recovering modified active data? [ ... ] > +static bool llbitmap_map_previous(struct llbitmap *llbitmap, sector_t of= fset, > + unsigned long sectors) > +{ > + struct mddev *mddev =3D llbitmap->mddev; > + sector_t boundary =3D READ_ONCE(mddev->reshape_position); > + > + if (boundary =3D=3D MaxSector) > + return false; > + > + WARN_ON_ONCE(sectors && offset < boundary && offset + sectors > boundar= y); > + > + return mddev->reshape_backwards ? offset < boundary : offset >=3D bound= ary; > +} [Severity: High] Can a straddling bio trigger this WARN_ON_ONCE and corrupt the bitmap if a reshape is paused? If a user pauses a reshape or the array enters a degraded state, MD_RECOVERY_RESHAPE might be cleared. If mddev_bio_split_at_reshape_offset() checks this flag and skips splitting the bio, a fully unsplit straddling bio could reach here. This would force the entire bio to be evaluated against a single geometry based purely on its starting sector, destroying bitmap integrity for the straddling tail. --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260802195038.1642= [email protected]?part=3D19