aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/md.c74
1 files changed, 51 insertions, 23 deletions
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;