diff options
| author | NeilBrown <neilb@suse.de> | 2010-03-28 22:23:10 -0400 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2010-05-18 01:27:54 -0400 |
| commit | a4bd82d0d03b1485975579f131ccfd0aad6b7d6e (patch) | |
| tree | 7e560963b71f26fc487a1cd932f4b684bd3b3e62 /drivers/md/md.c | |
| parent | a047e125403112ceb4d41e68307a2e7498ddba4e (diff) | |
md: split md_set_readonly out of do_md_stop
Using do_md_stop to set an array to read-only is a little confusing.
Now most of the common code has been factored out, split
md_set_readonly off in to a separate function.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
| -rw-r--r-- | drivers/md/md.c | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 86dfbc361cc0..3a2710a2e104 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -3309,6 +3309,7 @@ array_state_show(mddev_t *mddev, char *page) | |||
| 3309 | } | 3309 | } |
| 3310 | 3310 | ||
| 3311 | static int do_md_stop(mddev_t * mddev, int ro, int is_open); | 3311 | static int do_md_stop(mddev_t * mddev, int ro, int is_open); |
| 3312 | static int md_set_readonly(mddev_t * mddev, int is_open); | ||
| 3312 | static int do_md_run(mddev_t * mddev); | 3313 | static int do_md_run(mddev_t * mddev); |
| 3313 | static int restart_array(mddev_t *mddev); | 3314 | static int restart_array(mddev_t *mddev); |
| 3314 | 3315 | ||
| @@ -3339,7 +3340,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
| 3339 | break; /* not supported yet */ | 3340 | break; /* not supported yet */ |
| 3340 | case readonly: | 3341 | case readonly: |
| 3341 | if (mddev->pers) | 3342 | if (mddev->pers) |
| 3342 | err = do_md_stop(mddev, 1, 0); | 3343 | err = md_set_readonly(mddev, 0); |
| 3343 | else { | 3344 | else { |
| 3344 | mddev->ro = 1; | 3345 | mddev->ro = 1; |
| 3345 | set_disk_ro(mddev->gendisk, 1); | 3346 | set_disk_ro(mddev->gendisk, 1); |
| @@ -3349,7 +3350,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
| 3349 | case read_auto: | 3350 | case read_auto: |
| 3350 | if (mddev->pers) { | 3351 | if (mddev->pers) { |
| 3351 | if (mddev->ro == 0) | 3352 | if (mddev->ro == 0) |
| 3352 | err = do_md_stop(mddev, 1, 0); | 3353 | err = md_set_readonly(mddev, 0); |
| 3353 | else if (mddev->ro == 1) | 3354 | else if (mddev->ro == 1) |
| 3354 | err = restart_array(mddev); | 3355 | err = restart_array(mddev); |
| 3355 | if (err == 0) { | 3356 | if (err == 0) { |
| @@ -4641,9 +4642,34 @@ static void md_stop(mddev_t *mddev) | |||
| 4641 | 4642 | ||
| 4642 | } | 4643 | } |
| 4643 | 4644 | ||
| 4645 | static int md_set_readonly(mddev_t *mddev, int is_open) | ||
| 4646 | { | ||
| 4647 | int err = 0; | ||
| 4648 | mutex_lock(&mddev->open_mutex); | ||
| 4649 | if (atomic_read(&mddev->openers) > is_open) { | ||
| 4650 | printk("md: %s still in use.\n",mdname(mddev)); | ||
| 4651 | err = -EBUSY; | ||
| 4652 | goto out; | ||
| 4653 | } | ||
| 4654 | if (mddev->pers) { | ||
| 4655 | md_stop_writes(mddev); | ||
| 4656 | |||
| 4657 | err = -ENXIO; | ||
| 4658 | if (mddev->ro==1) | ||
| 4659 | goto out; | ||
| 4660 | mddev->ro = 1; | ||
| 4661 | set_disk_ro(mddev->gendisk, 1); | ||
| 4662 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | ||
| 4663 | sysfs_notify_dirent(mddev->sysfs_state); | ||
| 4664 | err = 0; | ||
| 4665 | } | ||
| 4666 | out: | ||
| 4667 | mutex_unlock(&mddev->open_mutex); | ||
| 4668 | return err; | ||
| 4669 | } | ||
| 4670 | |||
| 4644 | /* mode: | 4671 | /* mode: |
| 4645 | * 0 - completely stop and dis-assemble array | 4672 | * 0 - completely stop and dis-assemble array |
| 4646 | * 1 - switch to readonly | ||
| 4647 | * 2 - stop but do not disassemble array | 4673 | * 2 - stop but do not disassemble array |
| 4648 | */ | 4674 | */ |
| 4649 | static int do_md_stop(mddev_t * mddev, int mode, int is_open) | 4675 | static int do_md_stop(mddev_t * mddev, int mode, int is_open) |
| @@ -4660,45 +4686,33 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 4660 | 4686 | ||
| 4661 | md_stop_writes(mddev); | 4687 | md_stop_writes(mddev); |
| 4662 | 4688 | ||
| 4663 | switch(mode) { | 4689 | if (mddev->ro) |
| 4664 | case 1: /* readonly */ | 4690 | set_disk_ro(disk, 0); |
| 4665 | err = -ENXIO; | ||
| 4666 | if (mddev->ro==1) | ||
| 4667 | goto out; | ||
| 4668 | mddev->ro = 1; | ||
| 4669 | break; | ||
| 4670 | case 0: /* disassemble */ | ||
| 4671 | case 2: /* stop */ | ||
| 4672 | if (mddev->ro) | ||
| 4673 | set_disk_ro(disk, 0); | ||
| 4674 | 4691 | ||
| 4675 | md_stop(mddev); | 4692 | md_stop(mddev); |
| 4676 | mddev->queue->merge_bvec_fn = NULL; | 4693 | mddev->queue->merge_bvec_fn = NULL; |
| 4677 | mddev->queue->unplug_fn = NULL; | 4694 | mddev->queue->unplug_fn = NULL; |
| 4678 | mddev->queue->backing_dev_info.congested_fn = NULL; | 4695 | mddev->queue->backing_dev_info.congested_fn = NULL; |
| 4679 | 4696 | ||
| 4680 | /* tell userspace to handle 'inactive' */ | 4697 | /* tell userspace to handle 'inactive' */ |
| 4681 | sysfs_notify_dirent(mddev->sysfs_state); | 4698 | sysfs_notify_dirent(mddev->sysfs_state); |
| 4682 | 4699 | ||
| 4683 | list_for_each_entry(rdev, &mddev->disks, same_set) | 4700 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 4684 | if (rdev->raid_disk >= 0) { | 4701 | if (rdev->raid_disk >= 0) { |
| 4685 | char nm[20]; | 4702 | char nm[20]; |
| 4686 | sprintf(nm, "rd%d", rdev->raid_disk); | 4703 | sprintf(nm, "rd%d", rdev->raid_disk); |
| 4687 | sysfs_remove_link(&mddev->kobj, nm); | 4704 | sysfs_remove_link(&mddev->kobj, nm); |
| 4688 | } | 4705 | } |
| 4689 | 4706 | ||
| 4690 | set_capacity(disk, 0); | 4707 | set_capacity(disk, 0); |
| 4691 | revalidate_disk(disk); | 4708 | revalidate_disk(disk); |
| 4692 | 4709 | ||
| 4693 | if (mddev->ro) | 4710 | if (mddev->ro) |
| 4694 | mddev->ro = 0; | 4711 | mddev->ro = 0; |
| 4695 | } | 4712 | |
| 4696 | if (mode == 1) | ||
| 4697 | set_disk_ro(disk, 1); | ||
| 4698 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 4713 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 4699 | err = 0; | 4714 | err = 0; |
| 4700 | } | 4715 | } |
| 4701 | out: | ||
| 4702 | mutex_unlock(&mddev->open_mutex); | 4716 | mutex_unlock(&mddev->open_mutex); |
| 4703 | if (err) | 4717 | if (err) |
| 4704 | return err; | 4718 | return err; |
| @@ -4724,9 +4738,7 @@ out: | |||
| 4724 | if (mddev->hold_active == UNTIL_STOP) | 4738 | if (mddev->hold_active == UNTIL_STOP) |
| 4725 | mddev->hold_active = 0; | 4739 | mddev->hold_active = 0; |
| 4726 | 4740 | ||
| 4727 | } else if (mddev->pers) | 4741 | } |
| 4728 | printk(KERN_INFO "md: %s switched to read-only mode.\n", | ||
| 4729 | mdname(mddev)); | ||
| 4730 | err = 0; | 4742 | err = 0; |
| 4731 | blk_integrity_unregister(disk); | 4743 | blk_integrity_unregister(disk); |
| 4732 | md_new_event(mddev); | 4744 | md_new_event(mddev); |
| @@ -5724,7 +5736,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 5724 | goto done_unlock; | 5736 | goto done_unlock; |
| 5725 | 5737 | ||
| 5726 | case STOP_ARRAY_RO: | 5738 | case STOP_ARRAY_RO: |
| 5727 | err = do_md_stop(mddev, 1, 1); | 5739 | err = md_set_readonly(mddev, 1); |
| 5728 | goto done_unlock; | 5740 | goto done_unlock; |
| 5729 | 5741 | ||
| 5730 | case BLKROSET: | 5742 | case BLKROSET: |
| @@ -7140,7 +7152,7 @@ static int md_notify_reboot(struct notifier_block *this, | |||
| 7140 | * appears to still be in use. Hence | 7152 | * appears to still be in use. Hence |
| 7141 | * the '100'. | 7153 | * the '100'. |
| 7142 | */ | 7154 | */ |
| 7143 | do_md_stop(mddev, 1, 100); | 7155 | md_set_readonly(mddev, 100); |
| 7144 | mddev_unlock(mddev); | 7156 | mddev_unlock(mddev); |
| 7145 | } | 7157 | } |
| 7146 | /* | 7158 | /* |
