aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-03-27 04:18:06 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:45:01 -0500
commitb55e6bfcd23cb2f7249095050c649f7aea813f9f (patch)
tree78c854c1eeb85d48bf0956309cc7ccfa14e9805a
parent4588b42e9d0d0904a745c96cead66506c75bae21 (diff)
[PATCH] md: Split disks array out of raid5 conf structure so it is easier to grow
The remainder of this batch implements raid5 reshaping. Currently the only shape change that is supported is added a device, but it is envisioned that changing the chunksize and layout will also be supported, as well as changing the level (e.g. 1->5, 5->6). The reshape process naturally has to move all of the data in the array, and so should be used with caution. It is believed to work, and some testing does support this, but wider testing would be great for increasing my confidence. You will need a version of mdadm newer than 2.3.1 to make use of raid5 growth. This is because mdadm need to take a copy of a 'critical section' at the start of the array incase there is a crash at an awkward moment. On restart, mdadm will restore the critical section and allow reshape to continue. I hope to release a 2.4-pre by early next week - it still needs a little more polishing. This patch: Previously the array of disk information was included in the raid5 'conf' structure which was allocated to an appropriate size. This makes it awkward to change the size of that array. So we split it off into a separate kmalloced array which will require a little extra indexing, but is much easier to grow. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/raid5.c10
-rw-r--r--drivers/md/raid6main.c10
-rw-r--r--include/linux/raid/raid5.h2
3 files changed, 15 insertions, 7 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2dba305daf3c..03f31379cebb 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1822,11 +1822,13 @@ static int run(mddev_t *mddev)
1822 return -EIO; 1822 return -EIO;
1823 } 1823 }
1824 1824
1825 mddev->private = kzalloc(sizeof (raid5_conf_t) 1825 mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
1826 + mddev->raid_disks * sizeof(struct disk_info),
1827 GFP_KERNEL);
1828 if ((conf = mddev->private) == NULL) 1826 if ((conf = mddev->private) == NULL)
1829 goto abort; 1827 goto abort;
1828 conf->disks = kzalloc(mddev->raid_disks * sizeof(struct disk_info),
1829 GFP_KERNEL);
1830 if (!conf->disks)
1831 goto abort;
1830 1832
1831 conf->mddev = mddev; 1833 conf->mddev = mddev;
1832 1834
@@ -1966,6 +1968,7 @@ static int run(mddev_t *mddev)
1966abort: 1968abort:
1967 if (conf) { 1969 if (conf) {
1968 print_raid5_conf(conf); 1970 print_raid5_conf(conf);
1971 kfree(conf->disks);
1969 kfree(conf->stripe_hashtbl); 1972 kfree(conf->stripe_hashtbl);
1970 kfree(conf); 1973 kfree(conf);
1971 } 1974 }
@@ -1986,6 +1989,7 @@ static int stop(mddev_t *mddev)
1986 kfree(conf->stripe_hashtbl); 1989 kfree(conf->stripe_hashtbl);
1987 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 1990 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
1988 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); 1991 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
1992 kfree(conf->disks);
1989 kfree(conf); 1993 kfree(conf);
1990 mddev->private = NULL; 1994 mddev->private = NULL;
1991 return 0; 1995 return 0;
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index cd477ebf2ee4..c7632f6cc487 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -2006,11 +2006,14 @@ static int run(mddev_t *mddev)
2006 return -EIO; 2006 return -EIO;
2007 } 2007 }
2008 2008
2009 mddev->private = kzalloc(sizeof (raid6_conf_t) 2009 mddev->private = kzalloc(sizeof (raid6_conf_t), GFP_KERNEL);
2010 + mddev->raid_disks * sizeof(struct disk_info),
2011 GFP_KERNEL);
2012 if ((conf = mddev->private) == NULL) 2010 if ((conf = mddev->private) == NULL)
2013 goto abort; 2011 goto abort;
2012 conf->disks = kzalloc(mddev->raid_disks * sizeof(struct disk_info),
2013 GFP_KERNEL);
2014 if (!conf->disks)
2015 goto abort;
2016
2014 conf->mddev = mddev; 2017 conf->mddev = mddev;
2015 2018
2016 if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) 2019 if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
@@ -2158,6 +2161,7 @@ abort:
2158 print_raid6_conf(conf); 2161 print_raid6_conf(conf);
2159 safe_put_page(conf->spare_page); 2162 safe_put_page(conf->spare_page);
2160 kfree(conf->stripe_hashtbl); 2163 kfree(conf->stripe_hashtbl);
2164 kfree(conf->disks);
2161 kfree(conf); 2165 kfree(conf);
2162 } 2166 }
2163 mddev->private = NULL; 2167 mddev->private = NULL;
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 394da8207b34..94dbdd406f12 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -240,7 +240,7 @@ struct raid5_private_data {
240 * waiting for 25% to be free 240 * waiting for 25% to be free
241 */ 241 */
242 spinlock_t device_lock; 242 spinlock_t device_lock;
243 struct disk_info disks[0]; 243 struct disk_info *disks;
244}; 244};
245 245
246typedef struct raid5_private_data raid5_conf_t; 246typedef struct raid5_private_data raid5_conf_t;