Re: [PATCH v4 24/25] md/raid5: wire llbitmap reshape lifecycle
[email protected] Sat, 01 Aug 2026 18:12:35 +0000
| Newsgroups | gmane.linux.raid |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 3 potential issue(= s) to consider: New issues: - [High] raid5_start_reshape fails to invoke the reshape_can_start bitmap o= peration before starting the reshape process. - [High] raid5_finish_reshape unconditionally sets mddev->resync_offset =3D= 0 when llbitmap is enabled, forcing an immediate full array parity rebuild. Pre-existing issues: - [High] The llbitmap daemon work and pending timer can mutually re-arm eac= h other during llbitmap_destroy(), leading to a Use-After-Free. -- --- Patch [24]: [PATCH v4 24/25] md/raid5: wire llbitmap reshape lifecycle = --- commit 5324dd2fc19c643561ddccf4575506b5ce251538 Author: Yu Kuai <[email protected]> md/raid5: wire llbitmap reshape lifecycle Prepare llbitmap before RAID5 reshape starts, checkpoint the bitmap before advancing reshape_position, and finish the llbitmap geometry update when reshape completes. > diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c > index 5697570120da9..896aa522f446c 100644 > --- a/drivers/md/raid5.c > +++ b/drivers/md/raid5.c [ ... ] > @@ -8579,6 +8593,12 @@ static int raid5_start_reshape(struct mddev *mddev) > mdname(mddev)); > return -EINVAL; > } > + if (md_bitmap_enabled(mddev, false) && > + mddev->bitmap_id =3D=3D ID_LLBITMAP) { > + i =3D mddev->bitmap_ops->resize(mddev, mddev->dev_sectors, 0); [Severity: High] Does this code need to call the reshape_can_start() bitmap operation before proceeding with the resize? If a reshape begins while the llbitmap is actively tracking out-of-sync chunks (BitNeedSync or BitSyncing), couldn't the reshape incorrectly map the sync state to the new geometry?=20 This might lead to a loss of sync tracking and potential data regressions. > + if (i) > + return i; > + } > =20 > atomic_set(&conf->reshape_stripes, 0); [ ... ] > @@ -8693,8 +8722,16 @@ static void raid5_finish_reshape(struct mddev *mdd= ev) > { > struct r5conf *conf =3D mddev->private; > struct md_rdev *rdev; > + bool llbitmap =3D mddev->bitmap_id =3D=3D ID_LLBITMAP && > + md_bitmap_enabled(mddev, false); > =20 > if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { > + if (llbitmap && mddev->bitmap_ops->reshape_finish) > + mddev->bitmap_ops->reshape_finish(mddev); > + if (llbitmap) { > + mddev->resync_offset =3D 0; [Severity: High] Does setting mddev->resync_offset to 0 here force an immediate full array parity rebuild? By unconditionally resetting the resync offset, the MD core might be instructed that the entire array is out-of-sync upon reshape completion. This would force a full resync of all sectors, despite the reshape correctly remapping in-sync sectors, and cause performance regressions. > + mddev->resync_max_sectors =3D mddev->dev_sectors; > + } > =20 > if (mddev->delta_disks <=3D 0) { As a related note regarding llbitmap teardown: [Severity: High] This isn't a bug introduced by this patch, but can the llbitmap daemon work and pending timer mutually re-arm each other during llbitmap_destroy(), leading to a use-after-free regression? Looking at drivers/md/md-llbitmap.c:llbitmap_destroy(): timer_delete_sync(&llbitmap->pending_timer); flush_workqueue(md_llbitmap_io_wq); If the daemon_work is queued, the flush executes md_llbitmap_daemon_fn(). If there are unexpired dirty pages inside the work function, it will unconditionally re-arm the timer via mod_timer(). Since there is no cancel_work_sync() or subsequent timer deletion, could the newly armed timer fire after kfree(llbitmap) completes? --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260801172519.2982= [email protected]?part=3D24