Re: [PATCH v4 12/25] md/md-llbitmap: track target reshape geometry fields
[email protected] Sat, 01 Aug 2026 17:51:12 +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: New issues: - [High] Target reshape geometry is silently discarded across reboots due t= o NULL `mddev->pers` during array assembly. - [High] Reshape geometry tracking fails completely because target personal= ity callbacks are unimplemented. Pre-existing issues: - [Critical] Expanded array regions suffer silent data loss during I/O due = to mismatched chunkshift indexing. - [Critical] Use-After-Free (UAF) in timer callback during subsystem teardo= wn due to inadequate synchronization. -- --- Patch [12]: [PATCH v4 12/25] md/md-llbitmap: track target reshape geome= try fields --- commit fff2be87a121aeeb8a4cb9f28329398a1b07d67a Author: Yu Kuai <[email protected]> md/md-llbitmap: track target reshape geometry fields Track llbitmap bookkeeping for the target reshape geometry while keeping a single live bitmap instance. Add the reshape geometry fields, refresh helper, and update the load and resize paths to keep the target geometry in sync. > diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c > index cf522fae78f8a..37d1312e3eab9 100644 > --- a/drivers/md/md-llbitmap.c > +++ b/drivers/md/md-llbitmap.c [ ... ] > @@ -430,6 +433,39 @@ static void llbitmap_calculate_chunks(struct mddev *= mddev, sector_t blocks, > } > } > =20 > +static bool llbitmap_reshaping(struct llbitmap *llbitmap) > +{ > + return llbitmap->mddev->reshape_position !=3D MaxSector; > +} > + > +static sector_t llbitmap_personality_sync_size(struct llbitmap *llbitmap, > + bool previous) > +{ > + struct mddev *mddev =3D llbitmap->mddev; > + > + if (!llbitmap_reshaping(llbitmap) || !mddev->private || !mddev->pers || > + !mddev->pers->bitmap_sync_size) > + return llbitmap->sync_size; [Severity: High] Does this code handle array assembly correctly across reboots? During array assembly, md_run() invokes md_bitmap_create() to load the bitmap before explicitly assigning mddev->pers. Because mddev->pers is still NULL during this bitmap loading phase, this check will unconditionally hit the fallback path and return the old pre-reshape llbitmap->sync_size. Could this cause the target reshape geometry to be completely lost if the system reboots during a reshape, leading to inconsistent tracking? [Severity: High] Are there any RAID personality drivers that actually implement the new bitmap_sync_size callback? It appears these callbacks are not yet implemented in any RAID personality drivers (e.g., raid5, raid1). Consequently, the check for !mddev->pers->bitmap_sync_size will always evaluate to true, forcing a sile= nt fallback to the old geometry sizes. Will this render the newly introduced reshape tracking mechanisms unable to track the target geometry? > + return mddev->pers->bitmap_sync_size(mddev, previous); > +} > + > +static void llbitmap_refresh_reshape(struct llbitmap *llbitmap) > +{ [ ... ] > @@ -1289,6 +1327,9 @@ static int llbitmap_resize(struct mddev *mddev, sec= tor_t blocks, int chunksize) > goto out; > =20 > if (reshape) { > + llbitmap->reshape_sync_size =3D blocks; > + llbitmap->reshape_chunksize =3D bitmap_chunksize; > + llbitmap->reshape_chunks =3D chunks; > llbitmap->chunks =3D max(old_chunks, chunks); [Severity: High] This is a pre-existing issue, but does this code scale the chunkshift to ma= tch the updated chunksize? When a reshape increases array capacity beyond the bitmap's physical limits, bitmap_chunksize is scaled up. The code updates llbitmap->chunks but seems to miss updating llbitmap->chunkshift to match the new chunk size. Later, during I/O operations, llbitmap_start_write() calculates the chunk index using the stale, smaller chunkshift: unsigned long start =3D offset >> llbitmap->chunkshift; This produces artificially large chunk indices for data in the expanded reg= ion, which llbitmap_state_machine() then detects as exceeding llbitmap->chunks a= nd silently drops: if (start >=3D llbitmap->chunks) return BitNone; Could this lead to silent data corruption if writes to the expanded capacity are never tracked in the bitmap? > } else { > if (blocks < old_blocks && chunks < old_chunks) [ ... ] [Severity: High] This is a pre-existing issue, but is there adequate synchronization when tearing down the bitmap? During array destruction, llbitmap_destroy() initiates teardown by deleting the timer and flushing the workqueue: timer_delete_sync(&llbitmap->pending_timer); flush_workqueue(md_llbitmap_io_wq); However, the function doesn't seem to set any shutdown flag. If the backgro= und work md_llbitmap_daemon_fn() is executing or queued when flush_workqueue() is called, it runs to completion and unconditionally re-arms the timer: mod_timer(&llbitmap->pending_timer, ...); Once the workqueue is flushed, llbitmap_destroy() proceeds to free the llbitmap structure. The newly re-armed timer can subsequently fire and atte= mpt to access the freed memory inside llbitmap_pending_timer_fn(). Could this sequence result in a use-after-free? --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260801172519.2982= [email protected]?part=3D12