aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-01-06 03:20:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:34:09 -0500
commitda943b9912df063322d37b1a1f285460531d481d (patch)
tree09ec69816055934d264b0a0272435fee9abb2b95
parent4dbcdc751cb25ffca3a8374cbc5ab6de961cc545 (diff)
[PATCH] md: allow md/raid_disks to be settable
If array is active, try to reshape, else just set the value. Signed-off-by: Neil Brown <neilb@suse.de> Acked-by: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--Documentation/md.txt3
-rw-r--r--drivers/md/md.c74
2 files changed, 54 insertions, 23 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt
index a3eadf8e1701..69f742dee00f 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -165,6 +165,9 @@ All md devices contain:
165 in a fully functional array. If this is not yet known, the file 165 in a fully functional array. If this is not yet known, the file
166 will be empty. If an array is being resized (not currently 166 will be empty. If an array is being resized (not currently
167 possible) this will contain the larger of the old and new sizes. 167 possible) this will contain the larger of the old and new sizes.
168 Some raid level (RAID1) allow this value to be set while the
169 array is active. This will reconfigure the array. Otherwise
170 it can only be set while assembling an array.
168 171
169 chunk_size 172 chunk_size
170 This is the size if bytes for 'chunks' and is only relevant to 173 This is the size if bytes for 'chunks' and is only relevant to
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 32a4e2311e43..86e9f2efae5c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1843,7 +1843,27 @@ raid_disks_show(mddev_t *mddev, char *page)
1843 return sprintf(page, "%d\n", mddev->raid_disks); 1843 return sprintf(page, "%d\n", mddev->raid_disks);
1844} 1844}
1845 1845
1846static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks); 1846static int update_raid_disks(mddev_t *mddev, int raid_disks);
1847
1848static ssize_t
1849raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
1850{
1851 /* can only set raid_disks if array is not yet active */
1852 char *e;
1853 int rv = 0;
1854 unsigned long n = simple_strtoul(buf, &e, 10);
1855
1856 if (!*buf || (*e && *e != '\n'))
1857 return -EINVAL;
1858
1859 if (mddev->pers)
1860 rv = update_raid_disks(mddev, n);
1861 else
1862 mddev->raid_disks = n;
1863 return rv ? rv : len;
1864}
1865static struct md_sysfs_entry md_raid_disks =
1866__ATTR(raid_disks, 0644, raid_disks_show, raid_disks_store);
1847 1867
1848static ssize_t 1868static ssize_t
1849chunk_size_show(mddev_t *mddev, char *page) 1869chunk_size_show(mddev_t *mddev, char *page)
@@ -3201,6 +3221,33 @@ static int update_size(mddev_t *mddev, unsigned long size)
3201 return rv; 3221 return rv;
3202} 3222}
3203 3223
3224static int update_raid_disks(mddev_t *mddev, int raid_disks)
3225{
3226 int rv;
3227 /* change the number of raid disks */
3228 if (mddev->pers->reshape == NULL)
3229 return -EINVAL;
3230 if (raid_disks <= 0 ||
3231 raid_disks >= mddev->max_disks)
3232 return -EINVAL;
3233 if (mddev->sync_thread)
3234 return -EBUSY;
3235 rv = mddev->pers->reshape(mddev, raid_disks);
3236 if (!rv) {
3237 struct block_device *bdev;
3238
3239 bdev = bdget_disk(mddev->gendisk, 0);
3240 if (bdev) {
3241 down(&bdev->bd_inode->i_sem);
3242 i_size_write(bdev->bd_inode, mddev->array_size << 10);
3243 up(&bdev->bd_inode->i_sem);
3244 bdput(bdev);
3245 }
3246 }
3247 return rv;
3248}
3249
3250
3204/* 3251/*
3205 * update_array_info is used to change the configuration of an 3252 * update_array_info is used to change the configuration of an
3206 * on-line array. 3253 * on-line array.
@@ -3252,28 +3299,9 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
3252 if (mddev->size != info->size) 3299 if (mddev->size != info->size)
3253 rv = update_size(mddev, info->size); 3300 rv = update_size(mddev, info->size);
3254 3301
3255 if (mddev->raid_disks != info->raid_disks) { 3302 if (mddev->raid_disks != info->raid_disks)
3256 /* change the number of raid disks */ 3303 rv = update_raid_disks(mddev, info->raid_disks);
3257 if (mddev->pers->reshape == NULL) 3304
3258 return -EINVAL;
3259 if (info->raid_disks <= 0 ||
3260 info->raid_disks >= mddev->max_disks)
3261 return -EINVAL;
3262 if (mddev->sync_thread)
3263 return -EBUSY;
3264 rv = mddev->pers->reshape(mddev, info->raid_disks);
3265 if (!rv) {
3266 struct block_device *bdev;
3267
3268 bdev = bdget_disk(mddev->gendisk, 0);
3269 if (bdev) {
3270 down(&bdev->bd_inode->i_sem);
3271 i_size_write(bdev->bd_inode, mddev->array_size << 10);
3272 up(&bdev->bd_inode->i_sem);
3273 bdput(bdev);
3274 }
3275 }
3276 }
3277 if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) { 3305 if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) {
3278 if (mddev->pers->quiesce == NULL) 3306 if (mddev->pers->quiesce == NULL)
3279 return -EINVAL; 3307 return -EINVAL;