Skip to content

Commit 7435b73

Browse files
Li Nanhailan94
authored andcommitted
md/raid10: cleanup skip handling in raid10_sync_request
Skip a sector in raid10_sync_request() when it needs no syncing or no readable device exists. Current skip handling is unnecessary: - Use 'skip' label to reissue the next sector instead of return directly - Complete sync and return 'max_sectors' when multiple sectors are skipped due to badblocks The first is error-prone. For example, commit bc49694 ("md: pass in max_sectors for pers->sync_request()") removed redundant max_sector assignments. Since skip modifies max_sectors, `goto skip` leaves max_sectors equal to sector_nr after the jump, which is incorrect. The second causes sync to complete erroneously when no actual sync occurs. For recovery, recording badblocks and continue syncing subsequent sectors is more suitable. For resync, just skip bad sectors and syncing subsequent sectors. Clean up complex and unnecessary skip code. Return immediately when a sector should be skipped. Reduce code paths and lower regression risk. Link: https://lore.kernel.org/linux-raid/[email protected] Fixes: bc49694 ("md: pass in max_sectors for pers->sync_request()") Signed-off-by: Li Nan <[email protected]> Reviewed-by: Yu Kuai <[email protected]> Signed-off-by: Yu Kuai <[email protected]>
1 parent 99582ed commit 7435b73

1 file changed

Lines changed: 22 additions & 74 deletions

File tree

drivers/md/raid10.c

Lines changed: 22 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3161,11 +3161,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
31613161
int i;
31623162
int max_sync;
31633163
sector_t sync_blocks;
3164-
sector_t sectors_skipped = 0;
3165-
int chunks_skipped = 0;
31663164
sector_t chunk_mask = conf->geo.chunk_mask;
31673165
int page_idx = 0;
3168-
int error_disk = -1;
31693166

31703167
/*
31713168
* Allow skipping a full rebuild for incremental assembly
@@ -3186,7 +3183,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
31863183
if (init_resync(conf))
31873184
return 0;
31883185

3189-
skipped:
31903186
if (sector_nr >= max_sector) {
31913187
conf->cluster_sync_low = 0;
31923188
conf->cluster_sync_high = 0;
@@ -3238,33 +3234,12 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
32383234
mddev->bitmap_ops->close_sync(mddev);
32393235
close_sync(conf);
32403236
*skipped = 1;
3241-
return sectors_skipped;
3237+
return 0;
32423238
}
32433239

32443240
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
32453241
return reshape_request(mddev, sector_nr, skipped);
32463242

3247-
if (chunks_skipped >= conf->geo.raid_disks) {
3248-
pr_err("md/raid10:%s: %s fails\n", mdname(mddev),
3249-
test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ? "resync" : "recovery");
3250-
if (error_disk >= 0 &&
3251-
!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
3252-
/*
3253-
* recovery fails, set mirrors.recovery_disabled,
3254-
* device shouldn't be added to there.
3255-
*/
3256-
conf->mirrors[error_disk].recovery_disabled =
3257-
mddev->recovery_disabled;
3258-
return 0;
3259-
}
3260-
/*
3261-
* if there has been nothing to do on any drive,
3262-
* then there is nothing to do at all.
3263-
*/
3264-
*skipped = 1;
3265-
return (max_sector - sector_nr) + sectors_skipped;
3266-
}
3267-
32683243
if (max_sector > mddev->resync_max)
32693244
max_sector = mddev->resync_max; /* Don't do IO beyond here */
32703245

@@ -3347,7 +3322,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
33473322
/* yep, skip the sync_blocks here, but don't assume
33483323
* that there will never be anything to do here
33493324
*/
3350-
chunks_skipped = -1;
33513325
continue;
33523326
}
33533327
if (mrdev)
@@ -3478,29 +3452,19 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
34783452
for (k = 0; k < conf->copies; k++)
34793453
if (r10_bio->devs[k].devnum == i)
34803454
break;
3481-
if (mrdev && !test_bit(In_sync,
3482-
&mrdev->flags)
3483-
&& !rdev_set_badblocks(
3484-
mrdev,
3485-
r10_bio->devs[k].addr,
3486-
max_sync, 0))
3487-
any_working = 0;
3488-
if (mreplace &&
3489-
!rdev_set_badblocks(
3490-
mreplace,
3491-
r10_bio->devs[k].addr,
3492-
max_sync, 0))
3493-
any_working = 0;
3494-
}
3495-
if (!any_working) {
3496-
if (!test_and_set_bit(MD_RECOVERY_INTR,
3497-
&mddev->recovery))
3498-
pr_warn("md/raid10:%s: insufficient working devices for recovery.\n",
3499-
mdname(mddev));
3500-
mirror->recovery_disabled
3501-
= mddev->recovery_disabled;
3502-
} else {
3503-
error_disk = i;
3455+
if (mrdev &&
3456+
!test_bit(In_sync, &mrdev->flags))
3457+
rdev_set_badblocks(
3458+
mrdev,
3459+
r10_bio->devs[k].addr,
3460+
max_sync, 0);
3461+
if (mreplace)
3462+
rdev_set_badblocks(
3463+
mreplace,
3464+
r10_bio->devs[k].addr,
3465+
max_sync, 0);
3466+
pr_warn("md/raid10:%s: cannot recovery sector %llu + %d.\n",
3467+
mdname(mddev), r10_bio->devs[k].addr, max_sync);
35043468
}
35053469
put_buf(r10_bio);
35063470
if (rb2)
@@ -3541,7 +3505,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
35413505
rb2->master_bio = NULL;
35423506
put_buf(rb2);
35433507
}
3544-
goto giveup;
3508+
*skipped = 1;
3509+
return max_sync;
35453510
}
35463511
} else {
35473512
/* resync. Schedule a read for every block at this virt offset */
@@ -3565,7 +3530,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
35653530
&mddev->recovery)) {
35663531
/* We can skip this block */
35673532
*skipped = 1;
3568-
return sync_blocks + sectors_skipped;
3533+
return sync_blocks;
35693534
}
35703535
if (sync_blocks < max_sync)
35713536
max_sync = sync_blocks;
@@ -3657,8 +3622,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
36573622
mddev);
36583623
}
36593624
put_buf(r10_bio);
3660-
biolist = NULL;
3661-
goto giveup;
3625+
*skipped = 1;
3626+
return max_sync;
36623627
}
36633628
}
36643629

@@ -3678,7 +3643,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
36783643
if (WARN_ON(!bio_add_page(bio, page, len, 0))) {
36793644
bio->bi_status = BLK_STS_RESOURCE;
36803645
bio_endio(bio);
3681-
goto giveup;
3646+
*skipped = 1;
3647+
return max_sync;
36823648
}
36833649
}
36843650
nr_sectors += len>>9;
@@ -3746,25 +3712,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
37463712
}
37473713
}
37483714

3749-
if (sectors_skipped)
3750-
/* pretend they weren't skipped, it makes
3751-
* no important difference in this case
3752-
*/
3753-
md_done_sync(mddev, sectors_skipped);
3754-
3755-
return sectors_skipped + nr_sectors;
3756-
giveup:
3757-
/* There is nowhere to write, so all non-sync
3758-
* drives must be failed or in resync, all drives
3759-
* have a bad block, so try the next chunk...
3760-
*/
3761-
if (sector_nr + max_sync < max_sector)
3762-
max_sector = sector_nr + max_sync;
3763-
3764-
sectors_skipped += (max_sector - sector_nr);
3765-
chunks_skipped ++;
3766-
sector_nr = max_sector;
3767-
goto skipped;
3715+
return nr_sectors;
37683716
}
37693717

37703718
static sector_t

0 commit comments

Comments
 (0)