diff options
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 11 | 
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f978eddc7a21..fe872dc6712e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1809,6 +1809,17 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)  			struct md_rdev *repl =  				conf->mirrors[conf->raid_disks + number].rdev;  			freeze_array(conf, 0); +			if (atomic_read(&repl->nr_pending)) { +				/* It means that some queued IO of retry_list +				 * hold repl. Thus, we cannot set replacement +				 * as NULL, avoiding rdev NULL pointer +				 * dereference in sync_request_write and +				 * handle_write_finished. +				 */ +				err = -EBUSY; +				unfreeze_array(conf); +				goto abort; +			}  			clear_bit(Replacement, &repl->flags);  			p->rdev = repl;  			conf->mirrors[conf->raid_disks + number].rdev = NULL;  | 
