diff options
author | NeilBrown <neilb@suse.de> | 2009-03-30 23:56:41 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-03-30 23:56:41 -0400 |
commit | b3546035277847028df650b147469fc943cf5c71 (patch) | |
tree | 87966abc5456a62845326eb8d5a5cf0f88879b2d /drivers/md/md.c | |
parent | d562b0c4313e3ddea402a400371afa47ddf679f9 (diff) |
md/raid5: allow layout/chunksize to be changed on an active 2-drive raid5.
2-drive raid5's aren't very interesting. But if you are converting
a raid1 into a raid5, you will at least temporarily have one. And
that it a good time to set the layout/chunksize for the new RAID5
if you aren't happy with the defaults.
layout and chunksize don't actually affect the placement of data
on a 2-drive raid5, so we just do some internal book-keeping.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 05b613b5e4b2..0689d89d263c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2771,12 +2771,18 @@ layout_store(mddev_t *mddev, const char *buf, size_t len) | |||
2771 | if (!*buf || (*e && *e != '\n')) | 2771 | if (!*buf || (*e && *e != '\n')) |
2772 | return -EINVAL; | 2772 | return -EINVAL; |
2773 | 2773 | ||
2774 | if (mddev->pers) | 2774 | if (mddev->pers) { |
2775 | return -EBUSY; | 2775 | int err; |
2776 | 2776 | if (mddev->pers->reconfig == NULL) | |
2777 | mddev->new_layout = n; | 2777 | return -EBUSY; |
2778 | if (mddev->reshape_position == MaxSector) | 2778 | err = mddev->pers->reconfig(mddev, n, -1); |
2779 | mddev->layout = n; | 2779 | if (err) |
2780 | return err; | ||
2781 | } else { | ||
2782 | mddev->new_layout = n; | ||
2783 | if (mddev->reshape_position == MaxSector) | ||
2784 | mddev->layout = n; | ||
2785 | } | ||
2780 | return len; | 2786 | return len; |
2781 | } | 2787 | } |
2782 | static struct md_sysfs_entry md_layout = | 2788 | static struct md_sysfs_entry md_layout = |
@@ -2833,19 +2839,24 @@ chunk_size_show(mddev_t *mddev, char *page) | |||
2833 | static ssize_t | 2839 | static ssize_t |
2834 | chunk_size_store(mddev_t *mddev, const char *buf, size_t len) | 2840 | chunk_size_store(mddev_t *mddev, const char *buf, size_t len) |
2835 | { | 2841 | { |
2836 | /* can only set chunk_size if array is not yet active */ | ||
2837 | char *e; | 2842 | char *e; |
2838 | unsigned long n = simple_strtoul(buf, &e, 10); | 2843 | unsigned long n = simple_strtoul(buf, &e, 10); |
2839 | 2844 | ||
2840 | if (!*buf || (*e && *e != '\n')) | 2845 | if (!*buf || (*e && *e != '\n')) |
2841 | return -EINVAL; | 2846 | return -EINVAL; |
2842 | 2847 | ||
2843 | if (mddev->pers) | 2848 | if (mddev->pers) { |
2844 | return -EBUSY; | 2849 | int err; |
2845 | 2850 | if (mddev->pers->reconfig == NULL) | |
2846 | mddev->new_chunk = n; | 2851 | return -EBUSY; |
2847 | if (mddev->reshape_position == MaxSector) | 2852 | err = mddev->pers->reconfig(mddev, -1, n); |
2848 | mddev->chunk_size = n; | 2853 | if (err) |
2854 | return err; | ||
2855 | } else { | ||
2856 | mddev->new_chunk = n; | ||
2857 | if (mddev->reshape_position == MaxSector) | ||
2858 | mddev->chunk_size = n; | ||
2859 | } | ||
2849 | return len; | 2860 | return len; |
2850 | } | 2861 | } |
2851 | static struct md_sysfs_entry md_chunk_size = | 2862 | static struct md_sysfs_entry md_chunk_size = |