md: raid10: Fix null pointer dereference in fix_read_error()
Such NULL pointer dereference can occur when the driver was fixing the read errors/bad blocks and the disk was physically removed causing a system crash. This patch check if the rcu_dereference() returns valid rdev before accessing it in fix_read_error(). Cc: stable@kernel.org Signed-off-by: Prasanna S. Panchamukhi <prasanna.panchamukhi@riverbed.com> Signed-off-by: Rob Becker <rbecker@riverbed.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
Родитель
f3b99be19d
Коммит
0544a21db0
|
@ -1482,14 +1482,14 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
|
|||
int sectors = r10_bio->sectors;
|
||||
mdk_rdev_t*rdev;
|
||||
int max_read_errors = atomic_read(&mddev->max_corr_read_errors);
|
||||
int d = r10_bio->devs[r10_bio->read_slot].devnum;
|
||||
|
||||
rcu_read_lock();
|
||||
{
|
||||
int d = r10_bio->devs[r10_bio->read_slot].devnum;
|
||||
rdev = rcu_dereference(conf->mirrors[d].rdev);
|
||||
if (rdev) { /* If rdev is not NULL */
|
||||
char b[BDEVNAME_SIZE];
|
||||
int cur_read_error_count = 0;
|
||||
|
||||
rdev = rcu_dereference(conf->mirrors[d].rdev);
|
||||
bdevname(rdev->bdev, b);
|
||||
|
||||
if (test_bit(Faulty, &rdev->flags)) {
|
||||
|
@ -1530,7 +1530,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
|
|||
|
||||
rcu_read_lock();
|
||||
do {
|
||||
int d = r10_bio->devs[sl].devnum;
|
||||
d = r10_bio->devs[sl].devnum;
|
||||
rdev = rcu_dereference(conf->mirrors[d].rdev);
|
||||
if (rdev &&
|
||||
test_bit(In_sync, &rdev->flags)) {
|
||||
|
@ -1564,7 +1564,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
|
|||
rcu_read_lock();
|
||||
while (sl != r10_bio->read_slot) {
|
||||
char b[BDEVNAME_SIZE];
|
||||
int d;
|
||||
|
||||
if (sl==0)
|
||||
sl = conf->copies;
|
||||
sl--;
|
||||
|
@ -1601,7 +1601,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
|
|||
}
|
||||
sl = start;
|
||||
while (sl != r10_bio->read_slot) {
|
||||
int d;
|
||||
|
||||
if (sl==0)
|
||||
sl = conf->copies;
|
||||
sl--;
|
||||
|
|
Загрузка…
Ссылка в новой задаче