Skip to content

Commit dfa8ecd

Browse files
YuKuai-huaweiliu-song-6
authored andcommitted
md/raid1: factor out choose_slow_rdev() from read_balance()
read_balance() is hard to understand because there are too many status and branches, and it's overlong. This patch factor out the case to read the slow rdev from read_balance(), there are no functional changes. Co-developed-by: Paul Luse <[email protected]> Signed-off-by: Paul Luse <[email protected]> Signed-off-by: Yu Kuai <[email protected]> Reviewed-by: Xiao Ni <[email protected]> Signed-off-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 31a7333 commit dfa8ecd

File tree

1 file changed

+52
-17
lines changed

1 file changed

+52
-17
lines changed

drivers/md/raid1.c

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,53 @@ static int choose_first_rdev(struct r1conf *conf, struct r1bio *r1_bio,
620620
return -1;
621621
}
622622

623+
static int choose_slow_rdev(struct r1conf *conf, struct r1bio *r1_bio,
624+
int *max_sectors)
625+
{
626+
sector_t this_sector = r1_bio->sector;
627+
int bb_disk = -1;
628+
int bb_read_len = 0;
629+
int disk;
630+
631+
for (disk = 0 ; disk < conf->raid_disks * 2 ; disk++) {
632+
struct md_rdev *rdev;
633+
int len;
634+
int read_len;
635+
636+
if (r1_bio->bios[disk] == IO_BLOCKED)
637+
continue;
638+
639+
rdev = conf->mirrors[disk].rdev;
640+
if (!rdev || test_bit(Faulty, &rdev->flags) ||
641+
!test_bit(WriteMostly, &rdev->flags))
642+
continue;
643+
644+
/* there are no bad blocks, we can use this disk */
645+
len = r1_bio->sectors;
646+
read_len = raid1_check_read_range(rdev, this_sector, &len);
647+
if (read_len == r1_bio->sectors) {
648+
update_read_sectors(conf, disk, this_sector, read_len);
649+
return disk;
650+
}
651+
652+
/*
653+
* there are partial bad blocks, choose the rdev with largest
654+
* read length.
655+
*/
656+
if (read_len > bb_read_len) {
657+
bb_disk = disk;
658+
bb_read_len = read_len;
659+
}
660+
}
661+
662+
if (bb_disk != -1) {
663+
*max_sectors = bb_read_len;
664+
update_read_sectors(conf, bb_disk, this_sector, bb_read_len);
665+
}
666+
667+
return bb_disk;
668+
}
669+
623670
/*
624671
* This routine returns the disk from which the requested read should
625672
* be done. There is a per-array 'next expected sequential IO' sector
@@ -673,23 +720,8 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
673720
if (!test_bit(In_sync, &rdev->flags) &&
674721
rdev->recovery_offset < this_sector + sectors)
675722
continue;
676-
if (test_bit(WriteMostly, &rdev->flags)) {
677-
/* Don't balance among write-mostly, just
678-
* use the first as a last resort */
679-
if (best_dist_disk < 0) {
680-
if (is_badblock(rdev, this_sector, sectors,
681-
&first_bad, &bad_sectors)) {
682-
if (first_bad <= this_sector)
683-
/* Cannot use this */
684-
continue;
685-
best_good_sectors = first_bad - this_sector;
686-
} else
687-
best_good_sectors = sectors;
688-
best_dist_disk = disk;
689-
best_pending_disk = disk;
690-
}
723+
if (test_bit(WriteMostly, &rdev->flags))
691724
continue;
692-
}
693725
/* This is a reasonable device to use. It might
694726
* even be best.
695727
*/
@@ -808,7 +840,10 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
808840
}
809841
*max_sectors = sectors;
810842

811-
return best_disk;
843+
if (best_disk >= 0)
844+
return best_disk;
845+
846+
return choose_slow_rdev(conf, r1_bio, max_sectors);
812847
}
813848

814849
static void wake_up_barrier(struct r1conf *conf)

0 commit comments

Comments
 (0)