Commit f3ac8bf7ce1c5abd763ea762e95d1cdcf7799372

Authored by NeilBrown
1 parent 046abeede7

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

... ... @@ -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)