Commit f3ac8bf7ce1c5abd763ea762e95d1cdcf7799372
1 parent
046abeede7
Exists in
master
and in
7 other branches
md: tidy up device searches in read_balance.
The code for searching through the device list to read-balance in raid1 is rather clumsy and hard to follow. Try to simplify it a bit. No important functionality change here. Signed-off-by: NeilBrown <neilb@suse.de>
Showing 1 changed file with 36 additions and 56 deletions Side-by-side Diff
drivers/md/raid1.c
... | ... | @@ -419,11 +419,13 @@ |
419 | 419 | static int read_balance(conf_t *conf, r1bio_t *r1_bio) |
420 | 420 | { |
421 | 421 | const sector_t this_sector = r1_bio->sector; |
422 | - int new_disk = conf->last_used, disk = new_disk; | |
423 | - int wonly_disk = -1; | |
424 | 422 | const int sectors = r1_bio->sectors; |
423 | + int new_disk = -1; | |
424 | + int start_disk; | |
425 | + int i; | |
425 | 426 | sector_t new_distance, current_distance; |
426 | 427 | mdk_rdev_t *rdev; |
428 | + int choose_first; | |
427 | 429 | |
428 | 430 | rcu_read_lock(); |
429 | 431 | /* |
430 | 432 | |
431 | 433 | |
432 | 434 | |
433 | 435 | |
434 | 436 | |
435 | 437 | |
436 | 438 | |
... | ... | @@ -434,54 +436,33 @@ |
434 | 436 | retry: |
435 | 437 | if (conf->mddev->recovery_cp < MaxSector && |
436 | 438 | (this_sector + sectors >= conf->next_resync)) { |
437 | - /* Choose the first operational device, for consistancy */ | |
438 | - new_disk = 0; | |
439 | - | |
440 | - for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); | |
441 | - r1_bio->bios[new_disk] == IO_BLOCKED || | |
442 | - !rdev || !test_bit(In_sync, &rdev->flags) | |
443 | - || test_bit(WriteMostly, &rdev->flags); | |
444 | - rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) { | |
445 | - | |
446 | - if (rdev && test_bit(In_sync, &rdev->flags) && | |
447 | - r1_bio->bios[new_disk] != IO_BLOCKED) | |
448 | - wonly_disk = new_disk; | |
449 | - | |
450 | - if (new_disk == conf->raid_disks - 1) { | |
451 | - new_disk = wonly_disk; | |
452 | - break; | |
453 | - } | |
454 | - } | |
455 | - goto rb_out; | |
439 | + choose_first = 1; | |
440 | + start_disk = 0; | |
441 | + } else { | |
442 | + choose_first = 0; | |
443 | + start_disk = conf->last_used; | |
456 | 444 | } |
457 | 445 | |
458 | - | |
459 | 446 | /* make sure the disk is operational */ |
460 | - for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); | |
461 | - r1_bio->bios[new_disk] == IO_BLOCKED || | |
462 | - !rdev || !test_bit(In_sync, &rdev->flags) || | |
463 | - test_bit(WriteMostly, &rdev->flags); | |
464 | - rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) { | |
447 | + for (i = 0 ; i < conf->raid_disks ; i++) { | |
448 | + int disk = start_disk + i; | |
449 | + if (disk >= conf->raid_disks) | |
450 | + disk -= conf->raid_disks; | |
465 | 451 | |
466 | - if (rdev && test_bit(In_sync, &rdev->flags) && | |
467 | - r1_bio->bios[new_disk] != IO_BLOCKED) | |
468 | - wonly_disk = new_disk; | |
452 | + rdev = rcu_dereference(conf->mirrors[disk].rdev); | |
453 | + if (r1_bio->bios[disk] == IO_BLOCKED | |
454 | + || rdev == NULL | |
455 | + || !test_bit(In_sync, &rdev->flags)) | |
456 | + continue; | |
469 | 457 | |
470 | - if (new_disk <= 0) | |
471 | - new_disk = conf->raid_disks; | |
472 | - new_disk--; | |
473 | - if (new_disk == disk) { | |
474 | - new_disk = wonly_disk; | |
458 | + new_disk = disk; | |
459 | + if (!test_bit(WriteMostly, &rdev->flags)) | |
475 | 460 | break; |
476 | - } | |
477 | 461 | } |
478 | 462 | |
479 | - if (new_disk < 0) | |
463 | + if (new_disk < 0 || choose_first) | |
480 | 464 | goto rb_out; |
481 | 465 | |
482 | - disk = new_disk; | |
483 | - /* now disk == new_disk == starting point for search */ | |
484 | - | |
485 | 466 | /* |
486 | 467 | * Don't change to another disk for sequential reads: |
487 | 468 | */ |
488 | 469 | |
489 | 470 | |
490 | 471 | |
... | ... | @@ -490,20 +471,21 @@ |
490 | 471 | if (this_sector == conf->mirrors[new_disk].head_position) |
491 | 472 | goto rb_out; |
492 | 473 | |
493 | - current_distance = abs(this_sector - conf->mirrors[disk].head_position); | |
474 | + current_distance = abs(this_sector | |
475 | + - conf->mirrors[new_disk].head_position); | |
494 | 476 | |
495 | - /* Find the disk whose head is closest */ | |
477 | + /* look for a better disk - i.e. head is closer */ | |
478 | + start_disk = new_disk; | |
479 | + for (i = 1; i < conf->raid_disks; i++) { | |
480 | + int disk = start_disk + 1; | |
481 | + if (disk >= conf->raid_disks) | |
482 | + disk -= conf->raid_disks; | |
496 | 483 | |
497 | - do { | |
498 | - if (disk <= 0) | |
499 | - disk = conf->raid_disks; | |
500 | - disk--; | |
501 | - | |
502 | 484 | rdev = rcu_dereference(conf->mirrors[disk].rdev); |
503 | - | |
504 | - if (!rdev || r1_bio->bios[disk] == IO_BLOCKED || | |
505 | - !test_bit(In_sync, &rdev->flags) || | |
506 | - test_bit(WriteMostly, &rdev->flags)) | |
485 | + if (r1_bio->bios[disk] == IO_BLOCKED | |
486 | + || rdev == NULL | |
487 | + || !test_bit(In_sync, &rdev->flags) | |
488 | + || test_bit(WriteMostly, &rdev->flags)) | |
507 | 489 | continue; |
508 | 490 | |
509 | 491 | if (!atomic_read(&rdev->nr_pending)) { |
510 | 492 | |
... | ... | @@ -515,11 +497,9 @@ |
515 | 497 | current_distance = new_distance; |
516 | 498 | new_disk = disk; |
517 | 499 | } |
518 | - } while (disk != conf->last_used); | |
500 | + } | |
519 | 501 | |
520 | 502 | rb_out: |
521 | - | |
522 | - | |
523 | 503 | if (new_disk >= 0) { |
524 | 504 | rdev = rcu_dereference(conf->mirrors[new_disk].rdev); |
525 | 505 | if (!rdev) |