diff options
author | NeilBrown <neilb@suse.de> | 2014-01-13 18:38:09 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-25 11:27:12 -0500 |
commit | ddd618aa9eee9f143d750d15497bf6f117874928 (patch) | |
tree | 1c3e679a2ba741e88899262e411d766fffd7877a /drivers/md | |
parent | 16342c21c94760ac4d426371546d4f9e27758e1b (diff) |
md/raid10: fix two bugs in handling of known-bad-blocks.
commit b50c259e25d9260b9108dc0c2964c26e5ecbe1c1 upstream.
If we discover a bad block when reading we split the request and
potentially read some of it from a different device.
The code path of this has two bugs in RAID10.
1/ we get a spin_lock with _irq, but unlock without _irq!!
2/ The calculation of 'sectors_handled' is wrong, as can be clearly
seen by comparison with raid1.c
This leads to at least 2 warnings and a probable crash is a RAID10
ever had known bad blocks.
Fixes: 856e08e23762dfb92ffc68fd0a8d228f9e152160
Reported-by: Damian Nowak <spam@nowaker.net>
URL: https://bugzilla.kernel.org/show_bug.cgi?id=68181
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid10.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ff3f8d057e0a..d2f8cd332b4a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1321,7 +1321,7 @@ read_again: | |||
1321 | /* Could not read all from this device, so we will | 1321 | /* Could not read all from this device, so we will |
1322 | * need another r10_bio. | 1322 | * need another r10_bio. |
1323 | */ | 1323 | */ |
1324 | sectors_handled = (r10_bio->sectors + max_sectors | 1324 | sectors_handled = (r10_bio->sector + max_sectors |
1325 | - bio->bi_sector); | 1325 | - bio->bi_sector); |
1326 | r10_bio->sectors = max_sectors; | 1326 | r10_bio->sectors = max_sectors; |
1327 | spin_lock_irq(&conf->device_lock); | 1327 | spin_lock_irq(&conf->device_lock); |
@@ -1329,7 +1329,7 @@ read_again: | |||
1329 | bio->bi_phys_segments = 2; | 1329 | bio->bi_phys_segments = 2; |
1330 | else | 1330 | else |
1331 | bio->bi_phys_segments++; | 1331 | bio->bi_phys_segments++; |
1332 | spin_unlock(&conf->device_lock); | 1332 | spin_unlock_irq(&conf->device_lock); |
1333 | /* Cannot call generic_make_request directly | 1333 | /* Cannot call generic_make_request directly |
1334 | * as that will be queued in __generic_make_request | 1334 | * as that will be queued in __generic_make_request |
1335 | * and subsequent mempool_alloc might block | 1335 | * and subsequent mempool_alloc might block |