aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-01-13 18:38:09 -0500
committerNeilBrown <neilb@suse.de>2014-01-14 00:44:07 -0500
commitb50c259e25d9260b9108dc0c2964c26e5ecbe1c1 (patch)
tree146cf33b0f029effcf8c9c413627558979093ce7 /drivers/md
parent1cc03eb93245e63b0b7a7832165efdc52e25b4e6 (diff)
md/raid10: fix two bugs in handling of known-bad-blocks.
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. Cc: stable@vger.kernel.org (v3.1+) 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>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid10.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c504e8389e69..65285211568f 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1319,7 +1319,7 @@ read_again:
1319 /* Could not read all from this device, so we will 1319 /* Could not read all from this device, so we will
1320 * need another r10_bio. 1320 * need another r10_bio.
1321 */ 1321 */
1322 sectors_handled = (r10_bio->sectors + max_sectors 1322 sectors_handled = (r10_bio->sector + max_sectors
1323 - bio->bi_sector); 1323 - bio->bi_sector);
1324 r10_bio->sectors = max_sectors; 1324 r10_bio->sectors = max_sectors;
1325 spin_lock_irq(&conf->device_lock); 1325 spin_lock_irq(&conf->device_lock);
@@ -1327,7 +1327,7 @@ read_again:
1327 bio->bi_phys_segments = 2; 1327 bio->bi_phys_segments = 2;
1328 else 1328 else
1329 bio->bi_phys_segments++; 1329 bio->bi_phys_segments++;
1330 spin_unlock(&conf->device_lock); 1330 spin_unlock_irq(&conf->device_lock);
1331 /* Cannot call generic_make_request directly 1331 /* Cannot call generic_make_request directly
1332 * as that will be queued in __generic_make_request 1332 * as that will be queued in __generic_make_request
1333 * and subsequent mempool_alloc might block 1333 * and subsequent mempool_alloc might block