| From d1901ef099c38afd11add4cfb3312c02ef21ec4a Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hodek?= <tomas.hodek@volny.cz> |
| Date: Mon, 23 Feb 2015 11:00:38 +1100 |
| Subject: md/raid1: fix read balance when a drive is write-mostly. |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hodek?= <tomas.hodek@volny.cz> |
| |
| commit d1901ef099c38afd11add4cfb3312c02ef21ec4a upstream. |
| |
| When a drive is marked write-mostly it should only be the |
| target of reads if there is no other option. |
| |
| This behaviour was broken by |
| |
| commit 9dedf60313fa4dddfd5b9b226a0ef12a512bf9dc |
| md/raid1: read balance chooses idlest disk for SSD |
| |
| which causes a write-mostly device to be *preferred* is some cases. |
| |
| Restore correct behaviour by checking and setting |
| best_dist_disk and best_pending_disk rather than best_disk. |
| |
| We only need to test one of these as they are both changed |
| from -1 or >=0 at the same time. |
| |
| As we leave min_pending and best_dist unchanged, any non-write-mostly |
| device will appear better than the write-mostly device. |
| |
| Reported-by: Tomรกลก Hodek <tomas.hodek@volny.cz> |
| Reported-by: Dark Penguin <darkpenguin@yandex.ru> |
| Signed-off-by: NeilBrown <neilb@suse.de> |
| Link: http://marc.info/?l=linux-raid&m=135982797322422 |
| Fixes: 9dedf60313fa4dddfd5b9b226a0ef12a512bf9dc |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/md/raid1.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/md/raid1.c |
| +++ b/drivers/md/raid1.c |
| @@ -561,7 +561,7 @@ static int read_balance(struct r1conf *c |
| if (test_bit(WriteMostly, &rdev->flags)) { |
| /* Don't balance among write-mostly, just |
| * use the first as a last resort */ |
| - if (best_disk < 0) { |
| + if (best_dist_disk < 0) { |
| if (is_badblock(rdev, this_sector, sectors, |
| &first_bad, &bad_sectors)) { |
| if (first_bad < this_sector) |
| @@ -570,7 +570,8 @@ static int read_balance(struct r1conf *c |
| best_good_sectors = first_bad - this_sector; |
| } else |
| best_good_sectors = sectors; |
| - best_disk = disk; |
| + best_dist_disk = disk; |
| + best_pending_disk = disk; |
| } |
| continue; |
| } |