diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7d6f7f18a920..aa640a85bb21 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3324,7 +3324,7 @@ resync_start_store(mddev_t *mddev, const char *buf, size_t len) | |||
3324 | char *e; | 3324 | char *e; |
3325 | unsigned long long n = simple_strtoull(buf, &e, 10); | 3325 | unsigned long long n = simple_strtoull(buf, &e, 10); |
3326 | 3326 | ||
3327 | if (mddev->pers) | 3327 | if (mddev->pers && !test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) |
3328 | return -EBUSY; | 3328 | return -EBUSY; |
3329 | if (cmd_match(buf, "none")) | 3329 | if (cmd_match(buf, "none")) |
3330 | n = MaxSector; | 3330 | n = MaxSector; |
@@ -4347,13 +4347,19 @@ static int md_alloc(dev_t dev, char *name) | |||
4347 | disk->fops = &md_fops; | 4347 | disk->fops = &md_fops; |
4348 | disk->private_data = mddev; | 4348 | disk->private_data = mddev; |
4349 | disk->queue = mddev->queue; | 4349 | disk->queue = mddev->queue; |
4350 | blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA); | ||
4350 | /* Allow extended partitions. This makes the | 4351 | /* Allow extended partitions. This makes the |
4351 | * 'mdp' device redundant, but we can't really | 4352 | * 'mdp' device redundant, but we can't really |
4352 | * remove it now. | 4353 | * remove it now. |
4353 | */ | 4354 | */ |
4354 | disk->flags |= GENHD_FL_EXT_DEVT; | 4355 | disk->flags |= GENHD_FL_EXT_DEVT; |
4355 | add_disk(disk); | ||
4356 | mddev->gendisk = disk; | 4356 | mddev->gendisk = disk; |
4357 | /* As soon as we call add_disk(), another thread could get | ||
4358 | * through to md_open, so make sure it doesn't get too far | ||
4359 | */ | ||
4360 | mutex_lock(&mddev->open_mutex); | ||
4361 | add_disk(disk); | ||
4362 | |||
4357 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, | 4363 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, |
4358 | &disk_to_dev(disk)->kobj, "%s", "md"); | 4364 | &disk_to_dev(disk)->kobj, "%s", "md"); |
4359 | if (error) { | 4365 | if (error) { |
@@ -4367,8 +4373,7 @@ static int md_alloc(dev_t dev, char *name) | |||
4367 | if (mddev->kobj.sd && | 4373 | if (mddev->kobj.sd && |
4368 | sysfs_create_group(&mddev->kobj, &md_bitmap_group)) | 4374 | sysfs_create_group(&mddev->kobj, &md_bitmap_group)) |
4369 | printk(KERN_DEBUG "pointless warning\n"); | 4375 | printk(KERN_DEBUG "pointless warning\n"); |
4370 | 4376 | mutex_unlock(&mddev->open_mutex); | |
4371 | blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA); | ||
4372 | abort: | 4377 | abort: |
4373 | mutex_unlock(&disks_mutex); | 4378 | mutex_unlock(&disks_mutex); |
4374 | if (!error && mddev->kobj.sd) { | 4379 | if (!error && mddev->kobj.sd) { |
@@ -5211,6 +5216,16 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5211 | } else | 5216 | } else |
5212 | super_types[mddev->major_version]. | 5217 | super_types[mddev->major_version]. |
5213 | validate_super(mddev, rdev); | 5218 | validate_super(mddev, rdev); |
5219 | if ((info->state & (1<<MD_DISK_SYNC)) && | ||
5220 | (!test_bit(In_sync, &rdev->flags) || | ||
5221 | rdev->raid_disk != info->raid_disk)) { | ||
5222 | /* This was a hot-add request, but events doesn't | ||
5223 | * match, so reject it. | ||
5224 | */ | ||
5225 | export_rdev(rdev); | ||
5226 | return -EINVAL; | ||
5227 | } | ||
5228 | |||
5214 | if (test_bit(In_sync, &rdev->flags)) | 5229 | if (test_bit(In_sync, &rdev->flags)) |
5215 | rdev->saved_raid_disk = rdev->raid_disk; | 5230 | rdev->saved_raid_disk = rdev->raid_disk; |
5216 | else | 5231 | else |