On Fri, Feb 21, 2025 at 04:11:06PM +0800, Zheng Qixing wrote: > From: Zheng Qixing <zhengqixing@xxxxxxxxxx> > > The bad blocks check would miss bad blocks when retrying under contention, > as checking parameters are not reset. These stale values from the previous > attempt could lead to incorrect scanning in the subsequent retry. > > Move seqlock to outer function and reinitialize checking state for each > retry. This ensures a clean state for each check attempt, preventing any > missed bad blocks. > > Fixes: 3ea3354cb9f0 ("badblocks: improve badblocks_check() for multiple ranges handling") > Signed-off-by: Zheng Qixing <zhengqixing@xxxxxxxxxx> Looks good to me. Acked-by: Coly Li <colyli@xxxxxxxxxx> Thanks. > --- > block/badblocks.c | 50 +++++++++++++++++++++++------------------------ > 1 file changed, 24 insertions(+), 26 deletions(-) > > diff --git a/block/badblocks.c b/block/badblocks.c > index 381f9db423d6..79d91be468c4 100644 > --- a/block/badblocks.c > +++ b/block/badblocks.c > @@ -1191,31 +1191,12 @@ static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors) > static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors, > sector_t *first_bad, int *bad_sectors) > { > - int unacked_badblocks, acked_badblocks; > int prev = -1, hint = -1, set = 0; > struct badblocks_context bad; > - unsigned int seq; > + int unacked_badblocks = 0; > + int acked_badblocks = 0; > + u64 *p = bb->page; > int len, rv; > - u64 *p; > - > - WARN_ON(bb->shift < 0 || sectors == 0); > - > - if (bb->shift > 0) { > - sector_t target; > - > - /* round the start down, and the end up */ > - target = s + sectors; > - rounddown(s, 1 << bb->shift); > - roundup(target, 1 << bb->shift); > - sectors = target - s; > - } > - > -retry: > - seq = read_seqbegin(&bb->lock); > - > - p = bb->page; > - unacked_badblocks = 0; > - acked_badblocks = 0; > > re_check: > bad.start = s; > @@ -1281,9 +1262,6 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors, > else > rv = 0; > > - if (read_seqretry(&bb->lock, seq)) > - goto retry; > - > return rv; > } > > @@ -1324,7 +1302,27 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors, > int badblocks_check(struct badblocks *bb, sector_t s, int sectors, > sector_t *first_bad, int *bad_sectors) > { > - return _badblocks_check(bb, s, sectors, first_bad, bad_sectors); > + unsigned int seq; > + int rv; > + > + WARN_ON(bb->shift < 0 || sectors == 0); > + > + if (bb->shift > 0) { > + /* round the start down, and the end up */ > + sector_t target = s + sectors; > + > + rounddown(s, 1 << bb->shift); > + roundup(target, 1 << bb->shift); > + sectors = target - s; > + } > + > +retry: > + seq = read_seqbegin(&bb->lock); > + rv = _badblocks_check(bb, s, sectors, first_bad, bad_sectors); > + if (read_seqretry(&bb->lock, seq)) > + goto retry; > + > + return rv; > } > EXPORT_SYMBOL_GPL(badblocks_check); > > -- > 2.39.2 > -- Coly Li