diff options
Diffstat (limited to 'drivers/md/md.c')
| -rw-r--r-- | drivers/md/md.c | 74 |
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 | ||
| 1846 | static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks); | 1846 | static int update_raid_disks(mddev_t *mddev, int raid_disks); |
| 1847 | |||
| 1848 | static ssize_t | ||
| 1849 | raid_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 | } | ||
| 1865 | static struct md_sysfs_entry md_raid_disks = | ||
| 1866 | __ATTR(raid_disks, 0644, raid_disks_show, raid_disks_store); | ||
| 1847 | 1867 | ||
| 1848 | static ssize_t | 1868 | static ssize_t |
| 1849 | chunk_size_show(mddev_t *mddev, char *page) | 1869 | chunk_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 | ||
| 3224 | static 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; |
