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) | |||
1809 | struct md_rdev *repl = | 1809 | struct md_rdev *repl = |
1810 | conf->mirrors[conf->raid_disks + number].rdev; | 1810 | conf->mirrors[conf->raid_disks + number].rdev; |
1811 | freeze_array(conf, 0); | 1811 | freeze_array(conf, 0); |
1812 | if (atomic_read(&repl->nr_pending)) { | ||
1813 | /* It means that some queued IO of retry_list | ||
1814 | * hold repl. Thus, we cannot set replacement | ||
1815 | * as NULL, avoiding rdev NULL pointer | ||
1816 | * dereference in sync_request_write and | ||
1817 | * handle_write_finished. | ||
1818 | */ | ||
1819 | err = -EBUSY; | ||
1820 | unfreeze_array(conf); | ||
1821 | goto abort; | ||
1822 | } | ||
1812 | clear_bit(Replacement, &repl->flags); | 1823 | clear_bit(Replacement, &repl->flags); |
1813 | p->rdev = repl; | 1824 | p->rdev = repl; |
1814 | conf->mirrors[conf->raid_disks + number].rdev = NULL; | 1825 | conf->mirrors[conf->raid_disks + number].rdev = NULL; |