aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2007-05-09 05:35:38 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:30:57 -0400
commit08a02ecd28bad35a47357e611044dcbeab06e3d7 (patch)
tree31050d686e58d55411f95c89204321aa2ea2b63a /drivers/md
parent42b9bebe3fea3d3ce381bc6735a3fb50e6613f06 (diff)
md: allow reshape_position for md arrays to be set via sysfs
"reshape_position" records how much progress has been made on a "reshape" (adding drives, changing layout or chunksize). When it is set, the number of drives, layout and chunksize can have two possible values, an old an a new. So allow these different values to be visible, and allow both old and new to be set: Set the old ones first, then the reshape_position, then the new values. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index bad324171cad..65814b0340cb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -274,6 +274,7 @@ static mddev_t * mddev_find(dev_t unit)
274 atomic_set(&new->active, 1); 274 atomic_set(&new->active, 1);
275 spin_lock_init(&new->write_lock); 275 spin_lock_init(&new->write_lock);
276 init_waitqueue_head(&new->sb_wait); 276 init_waitqueue_head(&new->sb_wait);
277 new->reshape_position = MaxSector;
277 278
278 new->queue = blk_alloc_queue(GFP_KERNEL); 279 new->queue = blk_alloc_queue(GFP_KERNEL);
279 if (!new->queue) { 280 if (!new->queue) {
@@ -2242,6 +2243,10 @@ static ssize_t
2242layout_show(mddev_t *mddev, char *page) 2243layout_show(mddev_t *mddev, char *page)
2243{ 2244{
2244 /* just a number, not meaningful for all levels */ 2245 /* just a number, not meaningful for all levels */
2246 if (mddev->reshape_position != MaxSector &&
2247 mddev->layout != mddev->new_layout)
2248 return sprintf(page, "%d (%d)\n",
2249 mddev->new_layout, mddev->layout);
2245 return sprintf(page, "%d\n", mddev->layout); 2250 return sprintf(page, "%d\n", mddev->layout);
2246} 2251}
2247 2252
@@ -2250,13 +2255,16 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
2250{ 2255{
2251 char *e; 2256 char *e;
2252 unsigned long n = simple_strtoul(buf, &e, 10); 2257 unsigned long n = simple_strtoul(buf, &e, 10);
2253 if (mddev->pers)
2254 return -EBUSY;
2255 2258
2256 if (!*buf || (*e && *e != '\n')) 2259 if (!*buf || (*e && *e != '\n'))
2257 return -EINVAL; 2260 return -EINVAL;
2258 2261
2259 mddev->layout = n; 2262 if (mddev->pers)
2263 return -EBUSY;
2264 if (mddev->reshape_position != MaxSector)
2265 mddev->new_layout = n;
2266 else
2267 mddev->layout = n;
2260 return len; 2268 return len;
2261} 2269}
2262static struct md_sysfs_entry md_layout = 2270static struct md_sysfs_entry md_layout =
@@ -2268,6 +2276,10 @@ raid_disks_show(mddev_t *mddev, char *page)
2268{ 2276{
2269 if (mddev->raid_disks == 0) 2277 if (mddev->raid_disks == 0)
2270 return 0; 2278 return 0;
2279 if (mddev->reshape_position != MaxSector &&
2280 mddev->delta_disks != 0)
2281 return sprintf(page, "%d (%d)\n", mddev->raid_disks,
2282 mddev->raid_disks - mddev->delta_disks);
2271 return sprintf(page, "%d\n", mddev->raid_disks); 2283 return sprintf(page, "%d\n", mddev->raid_disks);
2272} 2284}
2273 2285
@@ -2285,7 +2297,11 @@ raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
2285 2297
2286 if (mddev->pers) 2298 if (mddev->pers)
2287 rv = update_raid_disks(mddev, n); 2299 rv = update_raid_disks(mddev, n);
2288 else 2300 else if (mddev->reshape_position != MaxSector) {
2301 int olddisks = mddev->raid_disks - mddev->delta_disks;
2302 mddev->delta_disks = n - olddisks;
2303 mddev->raid_disks = n;
2304 } else
2289 mddev->raid_disks = n; 2305 mddev->raid_disks = n;
2290 return rv ? rv : len; 2306 return rv ? rv : len;
2291} 2307}
@@ -2295,6 +2311,10 @@ __ATTR(raid_disks, S_IRUGO|S_IWUSR, raid_disks_show, raid_disks_store);
2295static ssize_t 2311static ssize_t
2296chunk_size_show(mddev_t *mddev, char *page) 2312chunk_size_show(mddev_t *mddev, char *page)
2297{ 2313{
2314 if (mddev->reshape_position != MaxSector &&
2315 mddev->chunk_size != mddev->new_chunk)
2316 return sprintf(page, "%d (%d)\n", mddev->new_chunk,
2317 mddev->chunk_size);
2298 return sprintf(page, "%d\n", mddev->chunk_size); 2318 return sprintf(page, "%d\n", mddev->chunk_size);
2299} 2319}
2300 2320
@@ -2305,12 +2325,15 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
2305 char *e; 2325 char *e;
2306 unsigned long n = simple_strtoul(buf, &e, 10); 2326 unsigned long n = simple_strtoul(buf, &e, 10);
2307 2327
2308 if (mddev->pers)
2309 return -EBUSY;
2310 if (!*buf || (*e && *e != '\n')) 2328 if (!*buf || (*e && *e != '\n'))
2311 return -EINVAL; 2329 return -EINVAL;
2312 2330
2313 mddev->chunk_size = n; 2331 if (mddev->pers)
2332 return -EBUSY;
2333 else if (mddev->reshape_position != MaxSector)
2334 mddev->new_chunk = n;
2335 else
2336 mddev->chunk_size = n;
2314 return len; 2337 return len;
2315} 2338}
2316static struct md_sysfs_entry md_chunk_size = 2339static struct md_sysfs_entry md_chunk_size =
@@ -2896,6 +2919,37 @@ suspend_hi_store(mddev_t *mddev, const char *buf, size_t len)
2896static struct md_sysfs_entry md_suspend_hi = 2919static struct md_sysfs_entry md_suspend_hi =
2897__ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); 2920__ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store);
2898 2921
2922static ssize_t
2923reshape_position_show(mddev_t *mddev, char *page)
2924{
2925 if (mddev->reshape_position != MaxSector)
2926 return sprintf(page, "%llu\n",
2927 (unsigned long long)mddev->reshape_position);
2928 strcpy(page, "none\n");
2929 return 5;
2930}
2931
2932static ssize_t
2933reshape_position_store(mddev_t *mddev, const char *buf, size_t len)
2934{
2935 char *e;
2936 unsigned long long new = simple_strtoull(buf, &e, 10);
2937 if (mddev->pers)
2938 return -EBUSY;
2939 if (buf == e || (*e && *e != '\n'))
2940 return -EINVAL;
2941 mddev->reshape_position = new;
2942 mddev->delta_disks = 0;
2943 mddev->new_level = mddev->level;
2944 mddev->new_layout = mddev->layout;
2945 mddev->new_chunk = mddev->chunk_size;
2946 return len;
2947}
2948
2949static struct md_sysfs_entry md_reshape_position =
2950__ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show,
2951 reshape_position_store);
2952
2899 2953
2900static struct attribute *md_default_attrs[] = { 2954static struct attribute *md_default_attrs[] = {
2901 &md_level.attr, 2955 &md_level.attr,
@@ -2908,6 +2962,7 @@ static struct attribute *md_default_attrs[] = {
2908 &md_new_device.attr, 2962 &md_new_device.attr,
2909 &md_safe_delay.attr, 2963 &md_safe_delay.attr,
2910 &md_array_state.attr, 2964 &md_array_state.attr,
2965 &md_reshape_position.attr,
2911 NULL, 2966 NULL,
2912}; 2967};
2913 2968
@@ -3446,6 +3501,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
3446 mddev->size = 0; 3501 mddev->size = 0;
3447 mddev->raid_disks = 0; 3502 mddev->raid_disks = 0;
3448 mddev->recovery_cp = 0; 3503 mddev->recovery_cp = 0;
3504 mddev->reshape_position = MaxSector;
3449 3505
3450 } else if (mddev->pers) 3506 } else if (mddev->pers)
3451 printk(KERN_INFO "md: %s switched to read-only mode.\n", 3507 printk(KERN_INFO "md: %s switched to read-only mode.\n",