diff options
| author | NeilBrown <neilb@suse.de> | 2010-09-06 00:10:08 -0400 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2010-10-29 01:40:33 -0400 |
| commit | f3ac8bf7ce1c5abd763ea762e95d1cdcf7799372 (patch) | |
| tree | bb903d4265520d5c96a9ee08557dd7f92c1f08df | |
| parent | 046abeede717909feec38587d667cde1fc6c459c (diff) | |
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>
| -rw-r--r-- | drivers/md/raid1.c | 92 |
1 files changed, 36 insertions, 56 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a0322db4d355..45f8324196ec 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -419,11 +419,13 @@ static void raid1_end_write_request(struct bio *bio, int error) | |||
| 419 | static int read_balance(conf_t *conf, r1bio_t *r1_bio) | 419 | static int read_balance(conf_t *conf, r1bio_t *r1_bio) |
| 420 | { | 420 | { |
| 421 | const sector_t this_sector = r1_bio->sector; | 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 | const int sectors = r1_bio->sectors; | 422 | const int sectors = r1_bio->sectors; |
| 423 | int new_disk = -1; | ||
| 424 | int start_disk; | ||
| 425 | int i; | ||
| 425 | sector_t new_distance, current_distance; | 426 | sector_t new_distance, current_distance; |
| 426 | mdk_rdev_t *rdev; | 427 | mdk_rdev_t *rdev; |
| 428 | int choose_first; | ||
| 427 | 429 | ||
| 428 | rcu_read_lock(); | 430 | rcu_read_lock(); |
| 429 | /* | 431 | /* |
| @@ -434,54 +436,33 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) | |||
| 434 | retry: | 436 | retry: |
| 435 | if (conf->mddev->recovery_cp < MaxSector && | 437 | if (conf->mddev->recovery_cp < MaxSector && |
| 436 | (this_sector + sectors >= conf->next_resync)) { | 438 | (this_sector + sectors >= conf->next_resync)) { |
| 437 | /* Choose the first operational device, for consistancy */ | 439 | choose_first = 1; |
| 438 | new_disk = 0; | 440 | start_disk = 0; |
| 439 | 441 | } else { | |
| 440 | for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); | 442 | choose_first = 0; |
| 441 | r1_bio->bios[new_disk] == IO_BLOCKED || | 443 | start_disk = conf->last_used; |
| 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; | ||
| 456 | } | 444 | } |
| 457 | 445 | ||
| 458 | |||
| 459 | /* make sure the disk is operational */ | 446 | /* make sure the disk is operational */ |
| 460 | for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); | 447 | for (i = 0 ; i < conf->raid_disks ; i++) { |
| 461 | r1_bio->bios[new_disk] == IO_BLOCKED || | 448 | int disk = start_disk + i; |
| 462 | !rdev || !test_bit(In_sync, &rdev->flags) || | 449 | if (disk >= conf->raid_disks) |
| 463 | test_bit(WriteMostly, &rdev->flags); | 450 | disk -= conf->raid_disks; |
| 464 | rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) { | 451 | |
| 465 | 452 | rdev = rcu_dereference(conf->mirrors[disk].rdev); | |
| 466 | if (rdev && test_bit(In_sync, &rdev->flags) && | 453 | if (r1_bio->bios[disk] == IO_BLOCKED |
| 467 | r1_bio->bios[new_disk] != IO_BLOCKED) | 454 | || rdev == NULL |
| 468 | wonly_disk = new_disk; | 455 | || !test_bit(In_sync, &rdev->flags)) |
| 469 | 456 | continue; | |
| 470 | if (new_disk <= 0) | 457 | |
| 471 | new_disk = conf->raid_disks; | 458 | new_disk = disk; |
| 472 | new_disk--; | 459 | if (!test_bit(WriteMostly, &rdev->flags)) |
| 473 | if (new_disk == disk) { | ||
| 474 | new_disk = wonly_disk; | ||
| 475 | break; | 460 | break; |
| 476 | } | ||
| 477 | } | 461 | } |
| 478 | 462 | ||
| 479 | if (new_disk < 0) | 463 | if (new_disk < 0 || choose_first) |
| 480 | goto rb_out; | 464 | goto rb_out; |
| 481 | 465 | ||
| 482 | disk = new_disk; | ||
| 483 | /* now disk == new_disk == starting point for search */ | ||
| 484 | |||
| 485 | /* | 466 | /* |
| 486 | * Don't change to another disk for sequential reads: | 467 | * Don't change to another disk for sequential reads: |
| 487 | */ | 468 | */ |
| @@ -490,20 +471,21 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) | |||
| 490 | if (this_sector == conf->mirrors[new_disk].head_position) | 471 | if (this_sector == conf->mirrors[new_disk].head_position) |
| 491 | goto rb_out; | 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 */ |
| 496 | 478 | start_disk = new_disk; | |
| 497 | do { | 479 | for (i = 1; i < conf->raid_disks; i++) { |
| 498 | if (disk <= 0) | 480 | int disk = start_disk + 1; |
| 499 | disk = conf->raid_disks; | 481 | if (disk >= conf->raid_disks) |
| 500 | disk--; | 482 | disk -= conf->raid_disks; |
| 501 | 483 | ||
| 502 | rdev = rcu_dereference(conf->mirrors[disk].rdev); | 484 | rdev = rcu_dereference(conf->mirrors[disk].rdev); |
| 503 | 485 | if (r1_bio->bios[disk] == IO_BLOCKED | |
| 504 | if (!rdev || r1_bio->bios[disk] == IO_BLOCKED || | 486 | || rdev == NULL |
| 505 | !test_bit(In_sync, &rdev->flags) || | 487 | || !test_bit(In_sync, &rdev->flags) |
| 506 | test_bit(WriteMostly, &rdev->flags)) | 488 | || test_bit(WriteMostly, &rdev->flags)) |
| 507 | continue; | 489 | continue; |
| 508 | 490 | ||
| 509 | if (!atomic_read(&rdev->nr_pending)) { | 491 | if (!atomic_read(&rdev->nr_pending)) { |
| @@ -515,11 +497,9 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) | |||
| 515 | current_distance = new_distance; | 497 | current_distance = new_distance; |
| 516 | new_disk = disk; | 498 | new_disk = disk; |
| 517 | } | 499 | } |
| 518 | } while (disk != conf->last_used); | 500 | } |
| 519 | 501 | ||
| 520 | rb_out: | 502 | rb_out: |
| 521 | |||
| 522 | |||
| 523 | if (new_disk >= 0) { | 503 | if (new_disk >= 0) { |
| 524 | rdev = rcu_dereference(conf->mirrors[new_disk].rdev); | 504 | rdev = rcu_dereference(conf->mirrors[new_disk].rdev); |
| 525 | if (!rdev) | 505 | if (!rdev) |
