aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a4c219e3c859..d5ab4493c8be 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2931,6 +2931,7 @@ offset_store(struct md_rdev *rdev, const char *buf, size_t len)
2931 * can be sane */ 2931 * can be sane */
2932 return -EBUSY; 2932 return -EBUSY;
2933 rdev->data_offset = offset; 2933 rdev->data_offset = offset;
2934 rdev->new_data_offset = offset;
2934 return len; 2935 return len;
2935} 2936}
2936 2937
@@ -3926,8 +3927,8 @@ array_state_show(struct mddev *mddev, char *page)
3926 return sprintf(page, "%s\n", array_states[st]); 3927 return sprintf(page, "%s\n", array_states[st]);
3927} 3928}
3928 3929
3929static int do_md_stop(struct mddev * mddev, int ro, int is_open); 3930static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev);
3930static int md_set_readonly(struct mddev * mddev, int is_open); 3931static int md_set_readonly(struct mddev * mddev, struct block_device *bdev);
3931static int do_md_run(struct mddev * mddev); 3932static int do_md_run(struct mddev * mddev);
3932static int restart_array(struct mddev *mddev); 3933static int restart_array(struct mddev *mddev);
3933 3934
@@ -3943,14 +3944,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
3943 /* stopping an active array */ 3944 /* stopping an active array */
3944 if (atomic_read(&mddev->openers) > 0) 3945 if (atomic_read(&mddev->openers) > 0)
3945 return -EBUSY; 3946 return -EBUSY;
3946 err = do_md_stop(mddev, 0, 0); 3947 err = do_md_stop(mddev, 0, NULL);
3947 break; 3948 break;
3948 case inactive: 3949 case inactive:
3949 /* stopping an active array */ 3950 /* stopping an active array */
3950 if (mddev->pers) { 3951 if (mddev->pers) {
3951 if (atomic_read(&mddev->openers) > 0) 3952 if (atomic_read(&mddev->openers) > 0)
3952 return -EBUSY; 3953 return -EBUSY;
3953 err = do_md_stop(mddev, 2, 0); 3954 err = do_md_stop(mddev, 2, NULL);
3954 } else 3955 } else
3955 err = 0; /* already inactive */ 3956 err = 0; /* already inactive */
3956 break; 3957 break;
@@ -3958,7 +3959,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
3958 break; /* not supported yet */ 3959 break; /* not supported yet */
3959 case readonly: 3960 case readonly:
3960 if (mddev->pers) 3961 if (mddev->pers)
3961 err = md_set_readonly(mddev, 0); 3962 err = md_set_readonly(mddev, NULL);
3962 else { 3963 else {
3963 mddev->ro = 1; 3964 mddev->ro = 1;
3964 set_disk_ro(mddev->gendisk, 1); 3965 set_disk_ro(mddev->gendisk, 1);
@@ -3968,7 +3969,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
3968 case read_auto: 3969 case read_auto:
3969 if (mddev->pers) { 3970 if (mddev->pers) {
3970 if (mddev->ro == 0) 3971 if (mddev->ro == 0)
3971 err = md_set_readonly(mddev, 0); 3972 err = md_set_readonly(mddev, NULL);
3972 else if (mddev->ro == 1) 3973 else if (mddev->ro == 1)
3973 err = restart_array(mddev); 3974 err = restart_array(mddev);
3974 if (err == 0) { 3975 if (err == 0) {
@@ -5351,15 +5352,17 @@ void md_stop(struct mddev *mddev)
5351} 5352}
5352EXPORT_SYMBOL_GPL(md_stop); 5353EXPORT_SYMBOL_GPL(md_stop);
5353 5354
5354static int md_set_readonly(struct mddev *mddev, int is_open) 5355static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
5355{ 5356{
5356 int err = 0; 5357 int err = 0;
5357 mutex_lock(&mddev->open_mutex); 5358 mutex_lock(&mddev->open_mutex);
5358 if (atomic_read(&mddev->openers) > is_open) { 5359 if (atomic_read(&mddev->openers) > !!bdev) {
5359 printk("md: %s still in use.\n",mdname(mddev)); 5360 printk("md: %s still in use.\n",mdname(mddev));
5360 err = -EBUSY; 5361 err = -EBUSY;
5361 goto out; 5362 goto out;
5362 } 5363 }
5364 if (bdev)
5365 sync_blockdev(bdev);
5363 if (mddev->pers) { 5366 if (mddev->pers) {
5364 __md_stop_writes(mddev); 5367 __md_stop_writes(mddev);
5365 5368
@@ -5381,18 +5384,26 @@ out:
5381 * 0 - completely stop and dis-assemble array 5384 * 0 - completely stop and dis-assemble array
5382 * 2 - stop but do not disassemble array 5385 * 2 - stop but do not disassemble array
5383 */ 5386 */
5384static int do_md_stop(struct mddev * mddev, int mode, int is_open) 5387static int do_md_stop(struct mddev * mddev, int mode,
5388 struct block_device *bdev)
5385{ 5389{
5386 struct gendisk *disk = mddev->gendisk; 5390 struct gendisk *disk = mddev->gendisk;
5387 struct md_rdev *rdev; 5391 struct md_rdev *rdev;
5388 5392
5389 mutex_lock(&mddev->open_mutex); 5393 mutex_lock(&mddev->open_mutex);
5390 if (atomic_read(&mddev->openers) > is_open || 5394 if (atomic_read(&mddev->openers) > !!bdev ||
5391 mddev->sysfs_active) { 5395 mddev->sysfs_active) {
5392 printk("md: %s still in use.\n",mdname(mddev)); 5396 printk("md: %s still in use.\n",mdname(mddev));
5393 mutex_unlock(&mddev->open_mutex); 5397 mutex_unlock(&mddev->open_mutex);
5394 return -EBUSY; 5398 return -EBUSY;
5395 } 5399 }
5400 if (bdev)
5401 /* It is possible IO was issued on some other
5402 * open file which was closed before we took ->open_mutex.
5403 * As that was not the last close __blkdev_put will not
5404 * have called sync_blockdev, so we must.
5405 */
5406 sync_blockdev(bdev);
5396 5407
5397 if (mddev->pers) { 5408 if (mddev->pers) {
5398 if (mddev->ro) 5409 if (mddev->ro)
@@ -5466,7 +5477,7 @@ static void autorun_array(struct mddev *mddev)
5466 err = do_md_run(mddev); 5477 err = do_md_run(mddev);
5467 if (err) { 5478 if (err) {
5468 printk(KERN_WARNING "md: do_md_run() returned %d\n", err); 5479 printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
5469 do_md_stop(mddev, 0, 0); 5480 do_md_stop(mddev, 0, NULL);
5470 } 5481 }
5471} 5482}
5472 5483
@@ -6481,11 +6492,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
6481 goto done_unlock; 6492 goto done_unlock;
6482 6493
6483 case STOP_ARRAY: 6494 case STOP_ARRAY:
6484 err = do_md_stop(mddev, 0, 1); 6495 err = do_md_stop(mddev, 0, bdev);
6485 goto done_unlock; 6496 goto done_unlock;
6486 6497
6487 case STOP_ARRAY_RO: 6498 case STOP_ARRAY_RO:
6488 err = md_set_readonly(mddev, 1); 6499 err = md_set_readonly(mddev, bdev);
6489 goto done_unlock; 6500 goto done_unlock;
6490 6501
6491 case BLKROSET: 6502 case BLKROSET: