| From e8b849158508565e0cd6bc80061124afc5879160 Mon Sep 17 00:00:00 2001 |
| From: NeilBrown <neilb@suse.de> |
| Date: Mon, 6 Jan 2014 10:35:34 +1100 |
| Subject: md/raid10: fix bug when raid10 recovery fails to recover a block. |
| |
| From: NeilBrown <neilb@suse.de> |
| |
| commit e8b849158508565e0cd6bc80061124afc5879160 upstream. |
| |
| commit e875ecea266a543e643b19e44cf472f1412708f9 |
| md/raid10 record bad blocks as needed during recovery. |
| |
| added code to the "cannot recover this block" path to record a bad |
| block rather than fail the whole recovery. |
| Unfortunately this new case was placed *after* r10bio was freed rather |
| than *before*, yet it still uses r10bio. |
| This is will crash with a null dereference. |
| |
| So move the freeing of r10bio down where it is safe. |
| |
| Fixes: e875ecea266a543e643b19e44cf472f1412708f9 |
| 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> |
| |
| --- |
| drivers/md/raid10.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/md/raid10.c |
| +++ b/drivers/md/raid10.c |
| @@ -3220,10 +3220,6 @@ static sector_t sync_request(struct mdde |
| if (j == conf->copies) { |
| /* Cannot recover, so abort the recovery or |
| * record a bad block */ |
| - put_buf(r10_bio); |
| - if (rb2) |
| - atomic_dec(&rb2->remaining); |
| - r10_bio = rb2; |
| if (any_working) { |
| /* problem is that there are bad blocks |
| * on other device(s) |
| @@ -3255,6 +3251,10 @@ static sector_t sync_request(struct mdde |
| mirror->recovery_disabled |
| = mddev->recovery_disabled; |
| } |
| + put_buf(r10_bio); |
| + if (rb2) |
| + atomic_dec(&rb2->remaining); |
| + r10_bio = rb2; |
| break; |
| } |
| } |