diff options
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b2eae332e1a2..fe872dc6712e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1108,7 +1108,7 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio, | |||
1108 | 1108 | ||
1109 | bio_copy_data(behind_bio, bio); | 1109 | bio_copy_data(behind_bio, bio); |
1110 | skip_copy: | 1110 | skip_copy: |
1111 | r1_bio->behind_master_bio = behind_bio;; | 1111 | r1_bio->behind_master_bio = behind_bio; |
1112 | set_bit(R1BIO_BehindIO, &r1_bio->state); | 1112 | set_bit(R1BIO_BehindIO, &r1_bio->state); |
1113 | 1113 | ||
1114 | return; | 1114 | return; |
@@ -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; |