Skip to content

Commit 5236f04

Browse files
Zheng Qixingaxboe
authored andcommitted
badblocks: fix missing bad blocks on retry in _badblocks_check()
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: 3ea3354 ("badblocks: improve badblocks_check() for multiple ranges handling") Signed-off-by: Zheng Qixing <[email protected]> Reviewed-by: Yu Kuai <[email protected]> Acked-by: Coly Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 9ec65de commit 5236f04

File tree

1 file changed

+24
-26
lines changed

1 file changed

+24
-26
lines changed

block/badblocks.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,31 +1191,12 @@ static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
11911191
static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
11921192
sector_t *first_bad, int *bad_sectors)
11931193
{
1194-
int unacked_badblocks, acked_badblocks;
11951194
int prev = -1, hint = -1, set = 0;
11961195
struct badblocks_context bad;
1197-
unsigned int seq;
1196+
int unacked_badblocks = 0;
1197+
int acked_badblocks = 0;
1198+
u64 *p = bb->page;
11981199
int len, rv;
1199-
u64 *p;
1200-
1201-
WARN_ON(bb->shift < 0 || sectors == 0);
1202-
1203-
if (bb->shift > 0) {
1204-
sector_t target;
1205-
1206-
/* round the start down, and the end up */
1207-
target = s + sectors;
1208-
rounddown(s, 1 << bb->shift);
1209-
roundup(target, 1 << bb->shift);
1210-
sectors = target - s;
1211-
}
1212-
1213-
retry:
1214-
seq = read_seqbegin(&bb->lock);
1215-
1216-
p = bb->page;
1217-
unacked_badblocks = 0;
1218-
acked_badblocks = 0;
12191200

12201201
re_check:
12211202
bad.start = s;
@@ -1281,9 +1262,6 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
12811262
else
12821263
rv = 0;
12831264

1284-
if (read_seqretry(&bb->lock, seq))
1285-
goto retry;
1286-
12871265
return rv;
12881266
}
12891267

@@ -1324,7 +1302,27 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
13241302
int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
13251303
sector_t *first_bad, int *bad_sectors)
13261304
{
1327-
return _badblocks_check(bb, s, sectors, first_bad, bad_sectors);
1305+
unsigned int seq;
1306+
int rv;
1307+
1308+
WARN_ON(bb->shift < 0 || sectors == 0);
1309+
1310+
if (bb->shift > 0) {
1311+
/* round the start down, and the end up */
1312+
sector_t target = s + sectors;
1313+
1314+
rounddown(s, 1 << bb->shift);
1315+
roundup(target, 1 << bb->shift);
1316+
sectors = target - s;
1317+
}
1318+
1319+
retry:
1320+
seq = read_seqbegin(&bb->lock);
1321+
rv = _badblocks_check(bb, s, sectors, first_bad, bad_sectors);
1322+
if (read_seqretry(&bb->lock, seq))
1323+
goto retry;
1324+
1325+
return rv;
13281326
}
13291327
EXPORT_SYMBOL_GPL(badblocks_check);
13301328

0 commit comments

Comments
 (0)