aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-01-06 03:20:36 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:34:06 -0500
commit2604b703b6b3db80e3c75ce472a54dfd0b7bf9f4 (patch)
tree8c0e985c455ff35af24fbe60d8a3f5a276034370
parenta24a8dd858e0ba50f06a9fd8f61fe8c4fe7a8d8e (diff)
[PATCH] md: remove personality numbering from md
md supports multiple different RAID level, each being implemented by a 'personality' (which is often in a separate module). These personalities have fairly artificial 'numbers'. The numbers are use to: 1- provide an index into an array where the various personalities are recorded 2- identify the module (via an alias) which implements are particular personality. Neither of these uses really justify the existence of personality numbers. The array can be replaced by a linked list which is searched (array lookup only happens very rarely). Module identification can be done using an alias based on level rather than 'personality' number. The current 'raid5' modules support two level (4 and 5) but only one personality. This slight awkwardness (which was handled in the mapping from level to personality) can be better handled by allowing raid5 to register 2 personalities. With this change in place, the core md module does not need to have an exhaustive list of all possible personalities, so other personalities can be added independently. This patch also moves the check for chunksize being non-zero into the ->run routines for the personalities that need it, rather than having it in core-md. This has a side effect of allowing 'faulty' and 'linear' not to have a chunk-size set. 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/faulty.c8
-rw-r--r--drivers/md/linear.c10
-rw-r--r--drivers/md/md.c79
-rw-r--r--drivers/md/multipath.c11
-rw-r--r--drivers/md/raid0.c14
-rw-r--r--drivers/md/raid1.c9
-rw-r--r--drivers/md/raid10.c16
-rw-r--r--drivers/md/raid5.c34
-rw-r--r--drivers/md/raid6main.c10
-rw-r--r--include/linux/raid/md.h4
-rw-r--r--include/linux/raid/md_k.h63
-rw-r--r--init/do_mounts_md.c22
12 files changed, 125 insertions, 155 deletions
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 0248f8e7eac0..f12e83086897 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -316,9 +316,10 @@ static int stop(mddev_t *mddev)
316 return 0; 316 return 0;
317} 317}
318 318
319static mdk_personality_t faulty_personality = 319static struct mdk_personality faulty_personality =
320{ 320{
321 .name = "faulty", 321 .name = "faulty",
322 .level = LEVEL_FAULTY,
322 .owner = THIS_MODULE, 323 .owner = THIS_MODULE,
323 .make_request = make_request, 324 .make_request = make_request,
324 .run = run, 325 .run = run,
@@ -329,15 +330,16 @@ static mdk_personality_t faulty_personality =
329 330
330static int __init raid_init(void) 331static int __init raid_init(void)
331{ 332{
332 return register_md_personality(FAULTY, &faulty_personality); 333 return register_md_personality(&faulty_personality);
333} 334}
334 335
335static void raid_exit(void) 336static void raid_exit(void)
336{ 337{
337 unregister_md_personality(FAULTY); 338 unregister_md_personality(&faulty_personality);
338} 339}
339 340
340module_init(raid_init); 341module_init(raid_init);
341module_exit(raid_exit); 342module_exit(raid_exit);
342MODULE_LICENSE("GPL"); 343MODULE_LICENSE("GPL");
343MODULE_ALIAS("md-personality-10"); /* faulty */ 344MODULE_ALIAS("md-personality-10"); /* faulty */
345MODULE_ALIAS("md-level--5");
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index f46c98d05b44..79dee8159217 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -351,9 +351,10 @@ static void linear_status (struct seq_file *seq, mddev_t *mddev)
351} 351}
352 352
353 353
354static mdk_personality_t linear_personality= 354static struct mdk_personality linear_personality =
355{ 355{
356 .name = "linear", 356 .name = "linear",
357 .level = LEVEL_LINEAR,
357 .owner = THIS_MODULE, 358 .owner = THIS_MODULE,
358 .make_request = linear_make_request, 359 .make_request = linear_make_request,
359 .run = linear_run, 360 .run = linear_run,
@@ -363,16 +364,17 @@ static mdk_personality_t linear_personality=
363 364
364static int __init linear_init (void) 365static int __init linear_init (void)
365{ 366{
366 return register_md_personality (LINEAR, &linear_personality); 367 return register_md_personality (&linear_personality);
367} 368}
368 369
369static void linear_exit (void) 370static void linear_exit (void)
370{ 371{
371 unregister_md_personality (LINEAR); 372 unregister_md_personality (&linear_personality);
372} 373}
373 374
374 375
375module_init(linear_init); 376module_init(linear_init);
376module_exit(linear_exit); 377module_exit(linear_exit);
377MODULE_LICENSE("GPL"); 378MODULE_LICENSE("GPL");
378MODULE_ALIAS("md-personality-1"); /* LINEAR */ 379MODULE_ALIAS("md-personality-1"); /* LINEAR - degrecated*/
380MODULE_ALIAS("md-level--1");
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a6a066fc92e3..07f180f95b47 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -68,7 +68,7 @@
68static void autostart_arrays (int part); 68static void autostart_arrays (int part);
69#endif 69#endif
70 70
71static mdk_personality_t *pers[MAX_PERSONALITY]; 71static LIST_HEAD(pers_list);
72static DEFINE_SPINLOCK(pers_lock); 72static DEFINE_SPINLOCK(pers_lock);
73 73
74/* 74/*
@@ -303,6 +303,15 @@ static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev)
303 return NULL; 303 return NULL;
304} 304}
305 305
306static struct mdk_personality *find_pers(int level)
307{
308 struct mdk_personality *pers;
309 list_for_each_entry(pers, &pers_list, list)
310 if (pers->level == level)
311 return pers;
312 return NULL;
313}
314
306static inline sector_t calc_dev_sboffset(struct block_device *bdev) 315static inline sector_t calc_dev_sboffset(struct block_device *bdev)
307{ 316{
308 sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 317 sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
@@ -1744,7 +1753,7 @@ static void analyze_sbs(mddev_t * mddev)
1744static ssize_t 1753static ssize_t
1745level_show(mddev_t *mddev, char *page) 1754level_show(mddev_t *mddev, char *page)
1746{ 1755{
1747 mdk_personality_t *p = mddev->pers; 1756 struct mdk_personality *p = mddev->pers;
1748 if (p == NULL && mddev->raid_disks == 0) 1757 if (p == NULL && mddev->raid_disks == 0)
1749 return 0; 1758 return 0;
1750 if (mddev->level >= 0) 1759 if (mddev->level >= 0)
@@ -1960,11 +1969,12 @@ static int start_dirty_degraded;
1960 1969
1961static int do_md_run(mddev_t * mddev) 1970static int do_md_run(mddev_t * mddev)
1962{ 1971{
1963 int pnum, err; 1972 int err;
1964 int chunk_size; 1973 int chunk_size;
1965 struct list_head *tmp; 1974 struct list_head *tmp;
1966 mdk_rdev_t *rdev; 1975 mdk_rdev_t *rdev;
1967 struct gendisk *disk; 1976 struct gendisk *disk;
1977 struct mdk_personality *pers;
1968 char b[BDEVNAME_SIZE]; 1978 char b[BDEVNAME_SIZE];
1969 1979
1970 if (list_empty(&mddev->disks)) 1980 if (list_empty(&mddev->disks))
@@ -1981,20 +1991,8 @@ static int do_md_run(mddev_t * mddev)
1981 analyze_sbs(mddev); 1991 analyze_sbs(mddev);
1982 1992
1983 chunk_size = mddev->chunk_size; 1993 chunk_size = mddev->chunk_size;
1984 pnum = level_to_pers(mddev->level);
1985 1994
1986 if ((pnum != MULTIPATH) && (pnum != RAID1)) { 1995 if (chunk_size) {
1987 if (!chunk_size) {
1988 /*
1989 * 'default chunksize' in the old md code used to
1990 * be PAGE_SIZE, baaad.
1991 * we abort here to be on the safe side. We don't
1992 * want to continue the bad practice.
1993 */
1994 printk(KERN_ERR
1995 "no chunksize specified, see 'man raidtab'\n");
1996 return -EINVAL;
1997 }
1998 if (chunk_size > MAX_CHUNK_SIZE) { 1996 if (chunk_size > MAX_CHUNK_SIZE) {
1999 printk(KERN_ERR "too big chunk_size: %d > %d\n", 1997 printk(KERN_ERR "too big chunk_size: %d > %d\n",
2000 chunk_size, MAX_CHUNK_SIZE); 1998 chunk_size, MAX_CHUNK_SIZE);
@@ -2030,10 +2028,7 @@ static int do_md_run(mddev_t * mddev)
2030 } 2028 }
2031 2029
2032#ifdef CONFIG_KMOD 2030#ifdef CONFIG_KMOD
2033 if (!pers[pnum]) 2031 request_module("md-level-%d", mddev->level);
2034 {
2035 request_module("md-personality-%d", pnum);
2036 }
2037#endif 2032#endif
2038 2033
2039 /* 2034 /*
@@ -2055,14 +2050,14 @@ static int do_md_run(mddev_t * mddev)
2055 return -ENOMEM; 2050 return -ENOMEM;
2056 2051
2057 spin_lock(&pers_lock); 2052 spin_lock(&pers_lock);
2058 if (!pers[pnum] || !try_module_get(pers[pnum]->owner)) { 2053 pers = find_pers(mddev->level);
2054 if (!pers || !try_module_get(pers->owner)) {
2059 spin_unlock(&pers_lock); 2055 spin_unlock(&pers_lock);
2060 printk(KERN_WARNING "md: personality %d is not loaded!\n", 2056 printk(KERN_WARNING "md: personality for level %d is not loaded!\n",
2061 pnum); 2057 mddev->level);
2062 return -EINVAL; 2058 return -EINVAL;
2063 } 2059 }
2064 2060 mddev->pers = pers;
2065 mddev->pers = pers[pnum];
2066 spin_unlock(&pers_lock); 2061 spin_unlock(&pers_lock);
2067 2062
2068 mddev->recovery = 0; 2063 mddev->recovery = 0;
@@ -3701,15 +3696,14 @@ static int md_seq_show(struct seq_file *seq, void *v)
3701 struct list_head *tmp2; 3696 struct list_head *tmp2;
3702 mdk_rdev_t *rdev; 3697 mdk_rdev_t *rdev;
3703 struct mdstat_info *mi = seq->private; 3698 struct mdstat_info *mi = seq->private;
3704 int i;
3705 struct bitmap *bitmap; 3699 struct bitmap *bitmap;
3706 3700
3707 if (v == (void*)1) { 3701 if (v == (void*)1) {
3702 struct mdk_personality *pers;
3708 seq_printf(seq, "Personalities : "); 3703 seq_printf(seq, "Personalities : ");
3709 spin_lock(&pers_lock); 3704 spin_lock(&pers_lock);
3710 for (i = 0; i < MAX_PERSONALITY; i++) 3705 list_for_each_entry(pers, &pers_list, list)
3711 if (pers[i]) 3706 seq_printf(seq, "[%s] ", pers->name);
3712 seq_printf(seq, "[%s] ", pers[i]->name);
3713 3707
3714 spin_unlock(&pers_lock); 3708 spin_unlock(&pers_lock);
3715 seq_printf(seq, "\n"); 3709 seq_printf(seq, "\n");
@@ -3870,35 +3864,20 @@ static struct file_operations md_seq_fops = {
3870 .poll = mdstat_poll, 3864 .poll = mdstat_poll,
3871}; 3865};
3872 3866
3873int register_md_personality(int pnum, mdk_personality_t *p) 3867int register_md_personality(struct mdk_personality *p)
3874{ 3868{
3875 if (pnum >= MAX_PERSONALITY) {
3876 printk(KERN_ERR
3877 "md: tried to install personality %s as nr %d, but max is %lu\n",
3878 p->name, pnum, MAX_PERSONALITY-1);
3879 return -EINVAL;
3880 }
3881
3882 spin_lock(&pers_lock); 3869 spin_lock(&pers_lock);
3883 if (pers[pnum]) { 3870 list_add_tail(&p->list, &pers_list);
3884 spin_unlock(&pers_lock); 3871 printk(KERN_INFO "md: %s personality registered for level %d\n", p->name, p->level);
3885 return -EBUSY;
3886 }
3887
3888 pers[pnum] = p;
3889 printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum);
3890 spin_unlock(&pers_lock); 3872 spin_unlock(&pers_lock);
3891 return 0; 3873 return 0;
3892} 3874}
3893 3875
3894int unregister_md_personality(int pnum) 3876int unregister_md_personality(struct mdk_personality *p)
3895{ 3877{
3896 if (pnum >= MAX_PERSONALITY) 3878 printk(KERN_INFO "md: %s personality unregistered\n", p->name);
3897 return -EINVAL;
3898
3899 printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
3900 spin_lock(&pers_lock); 3879 spin_lock(&pers_lock);
3901 pers[pnum] = NULL; 3880 list_del_init(&p->list);
3902 spin_unlock(&pers_lock); 3881 spin_unlock(&pers_lock);
3903 return 0; 3882 return 0;
3904} 3883}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 97a56aaaef6d..d4d838e3f9f8 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -35,9 +35,6 @@
35#define NR_RESERVED_BUFS 32 35#define NR_RESERVED_BUFS 32
36 36
37 37
38static mdk_personality_t multipath_personality;
39
40
41static void *mp_pool_alloc(gfp_t gfp_flags, void *data) 38static void *mp_pool_alloc(gfp_t gfp_flags, void *data)
42{ 39{
43 struct multipath_bh *mpb; 40 struct multipath_bh *mpb;
@@ -553,9 +550,10 @@ static int multipath_stop (mddev_t *mddev)
553 return 0; 550 return 0;
554} 551}
555 552
556static mdk_personality_t multipath_personality= 553static struct mdk_personality multipath_personality =
557{ 554{
558 .name = "multipath", 555 .name = "multipath",
556 .level = LEVEL_MULTIPATH,
559 .owner = THIS_MODULE, 557 .owner = THIS_MODULE,
560 .make_request = multipath_make_request, 558 .make_request = multipath_make_request,
561 .run = multipath_run, 559 .run = multipath_run,
@@ -568,15 +566,16 @@ static mdk_personality_t multipath_personality=
568 566
569static int __init multipath_init (void) 567static int __init multipath_init (void)
570{ 568{
571 return register_md_personality (MULTIPATH, &multipath_personality); 569 return register_md_personality (&multipath_personality);
572} 570}
573 571
574static void __exit multipath_exit (void) 572static void __exit multipath_exit (void)
575{ 573{
576 unregister_md_personality (MULTIPATH); 574 unregister_md_personality (&multipath_personality);
577} 575}
578 576
579module_init(multipath_init); 577module_init(multipath_init);
580module_exit(multipath_exit); 578module_exit(multipath_exit);
581MODULE_LICENSE("GPL"); 579MODULE_LICENSE("GPL");
582MODULE_ALIAS("md-personality-7"); /* MULTIPATH */ 580MODULE_ALIAS("md-personality-7"); /* MULTIPATH */
581MODULE_ALIAS("md-level--4");
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index b4eaa67fabde..7fb69e29391b 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -275,7 +275,11 @@ static int raid0_run (mddev_t *mddev)
275 mdk_rdev_t *rdev; 275 mdk_rdev_t *rdev;
276 struct list_head *tmp; 276 struct list_head *tmp;
277 277
278 printk("%s: setting max_sectors to %d, segment boundary to %d\n", 278 if (mddev->chunk_size == 0) {
279 printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
280 return -EINVAL;
281 }
282 printk(KERN_INFO "%s: setting max_sectors to %d, segment boundary to %d\n",
279 mdname(mddev), 283 mdname(mddev),
280 mddev->chunk_size >> 9, 284 mddev->chunk_size >> 9,
281 (mddev->chunk_size>>1)-1); 285 (mddev->chunk_size>>1)-1);
@@ -507,9 +511,10 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev)
507 return; 511 return;
508} 512}
509 513
510static mdk_personality_t raid0_personality= 514static struct mdk_personality raid0_personality=
511{ 515{
512 .name = "raid0", 516 .name = "raid0",
517 .level = 0,
513 .owner = THIS_MODULE, 518 .owner = THIS_MODULE,
514 .make_request = raid0_make_request, 519 .make_request = raid0_make_request,
515 .run = raid0_run, 520 .run = raid0_run,
@@ -519,15 +524,16 @@ static mdk_personality_t raid0_personality=
519 524
520static int __init raid0_init (void) 525static int __init raid0_init (void)
521{ 526{
522 return register_md_personality (RAID0, &raid0_personality); 527 return register_md_personality (&raid0_personality);
523} 528}
524 529
525static void raid0_exit (void) 530static void raid0_exit (void)
526{ 531{
527 unregister_md_personality (RAID0); 532 unregister_md_personality (&raid0_personality);
528} 533}
529 534
530module_init(raid0_init); 535module_init(raid0_init);
531module_exit(raid0_exit); 536module_exit(raid0_exit);
532MODULE_LICENSE("GPL"); 537MODULE_LICENSE("GPL");
533MODULE_ALIAS("md-personality-2"); /* RAID0 */ 538MODULE_ALIAS("md-personality-2"); /* RAID0 */
539MODULE_ALIAS("md-level-0");
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index c42ef1c99fa0..6e0f59ed3d80 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -47,7 +47,6 @@
47 */ 47 */
48#define NR_RAID1_BIOS 256 48#define NR_RAID1_BIOS 256
49 49
50static mdk_personality_t raid1_personality;
51 50
52static void unplug_slaves(mddev_t *mddev); 51static void unplug_slaves(mddev_t *mddev);
53 52
@@ -2036,9 +2035,10 @@ static void raid1_quiesce(mddev_t *mddev, int state)
2036} 2035}
2037 2036
2038 2037
2039static mdk_personality_t raid1_personality = 2038static struct mdk_personality raid1_personality =
2040{ 2039{
2041 .name = "raid1", 2040 .name = "raid1",
2041 .level = 1,
2042 .owner = THIS_MODULE, 2042 .owner = THIS_MODULE,
2043 .make_request = make_request, 2043 .make_request = make_request,
2044 .run = run, 2044 .run = run,
@@ -2056,15 +2056,16 @@ static mdk_personality_t raid1_personality =
2056 2056
2057static int __init raid_init(void) 2057static int __init raid_init(void)
2058{ 2058{
2059 return register_md_personality(RAID1, &raid1_personality); 2059 return register_md_personality(&raid1_personality);
2060} 2060}
2061 2061
2062static void raid_exit(void) 2062static void raid_exit(void)
2063{ 2063{
2064 unregister_md_personality(RAID1); 2064 unregister_md_personality(&raid1_personality);
2065} 2065}
2066 2066
2067module_init(raid_init); 2067module_init(raid_init);
2068module_exit(raid_exit); 2068module_exit(raid_exit);
2069MODULE_LICENSE("GPL"); 2069MODULE_LICENSE("GPL");
2070MODULE_ALIAS("md-personality-3"); /* RAID1 */ 2070MODULE_ALIAS("md-personality-3"); /* RAID1 */
2071MODULE_ALIAS("md-level-1");
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 253322ae9195..f23d52c5df94 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1883,11 +1883,11 @@ static int run(mddev_t *mddev)
1883 int nc, fc; 1883 int nc, fc;
1884 sector_t stride, size; 1884 sector_t stride, size;
1885 1885
1886 if (mddev->level != 10) { 1886 if (mddev->chunk_size == 0) {
1887 printk(KERN_ERR "raid10: %s: raid level not set correctly... (%d)\n", 1887 printk(KERN_ERR "md/raid10: non-zero chunk size required.\n");
1888 mdname(mddev), mddev->level); 1888 return -EINVAL;
1889 goto out;
1890 } 1889 }
1890
1891 nc = mddev->layout & 255; 1891 nc = mddev->layout & 255;
1892 fc = (mddev->layout >> 8) & 255; 1892 fc = (mddev->layout >> 8) & 255;
1893 if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks || 1893 if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks ||
@@ -2072,9 +2072,10 @@ static void raid10_quiesce(mddev_t *mddev, int state)
2072 } 2072 }
2073} 2073}
2074 2074
2075static mdk_personality_t raid10_personality = 2075static struct mdk_personality raid10_personality =
2076{ 2076{
2077 .name = "raid10", 2077 .name = "raid10",
2078 .level = 10,
2078 .owner = THIS_MODULE, 2079 .owner = THIS_MODULE,
2079 .make_request = make_request, 2080 .make_request = make_request,
2080 .run = run, 2081 .run = run,
@@ -2090,15 +2091,16 @@ static mdk_personality_t raid10_personality =
2090 2091
2091static int __init raid_init(void) 2092static int __init raid_init(void)
2092{ 2093{
2093 return register_md_personality(RAID10, &raid10_personality); 2094 return register_md_personality(&raid10_personality);
2094} 2095}
2095 2096
2096static void raid_exit(void) 2097static void raid_exit(void)
2097{ 2098{
2098 unregister_md_personality(RAID10); 2099 unregister_md_personality(&raid10_personality);
2099} 2100}
2100 2101
2101module_init(raid_init); 2102module_init(raid_init);
2102module_exit(raid_exit); 2103module_exit(raid_exit);
2103MODULE_LICENSE("GPL"); 2104MODULE_LICENSE("GPL");
2104MODULE_ALIAS("md-personality-9"); /* RAID10 */ 2105MODULE_ALIAS("md-personality-9"); /* RAID10 */
2106MODULE_ALIAS("md-level-10");
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 6e4db95cebb1..b0cfd3ca9ca0 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2187,9 +2187,10 @@ static void raid5_quiesce(mddev_t *mddev, int state)
2187 } 2187 }
2188} 2188}
2189 2189
2190static mdk_personality_t raid5_personality= 2190static struct mdk_personality raid5_personality =
2191{ 2191{
2192 .name = "raid5", 2192 .name = "raid5",
2193 .level = 5,
2193 .owner = THIS_MODULE, 2194 .owner = THIS_MODULE,
2194 .make_request = make_request, 2195 .make_request = make_request,
2195 .run = run, 2196 .run = run,
@@ -2204,17 +2205,40 @@ static mdk_personality_t raid5_personality=
2204 .quiesce = raid5_quiesce, 2205 .quiesce = raid5_quiesce,
2205}; 2206};
2206 2207
2207static int __init raid5_init (void) 2208static struct mdk_personality raid4_personality =
2208{ 2209{
2209 return register_md_personality (RAID5, &raid5_personality); 2210 .name = "raid4",
2211 .level = 4,
2212 .owner = THIS_MODULE,
2213 .make_request = make_request,
2214 .run = run,
2215 .stop = stop,
2216 .status = status,
2217 .error_handler = error,
2218 .hot_add_disk = raid5_add_disk,
2219 .hot_remove_disk= raid5_remove_disk,
2220 .spare_active = raid5_spare_active,
2221 .sync_request = sync_request,
2222 .resize = raid5_resize,
2223 .quiesce = raid5_quiesce,
2224};
2225
2226static int __init raid5_init(void)
2227{
2228 register_md_personality(&raid5_personality);
2229 register_md_personality(&raid4_personality);
2230 return 0;
2210} 2231}
2211 2232
2212static void raid5_exit (void) 2233static void raid5_exit(void)
2213{ 2234{
2214 unregister_md_personality (RAID5); 2235 unregister_md_personality(&raid5_personality);
2236 unregister_md_personality(&raid4_personality);
2215} 2237}
2216 2238
2217module_init(raid5_init); 2239module_init(raid5_init);
2218module_exit(raid5_exit); 2240module_exit(raid5_exit);
2219MODULE_LICENSE("GPL"); 2241MODULE_LICENSE("GPL");
2220MODULE_ALIAS("md-personality-4"); /* RAID5 */ 2242MODULE_ALIAS("md-personality-4"); /* RAID5 */
2243MODULE_ALIAS("md-level-5");
2244MODULE_ALIAS("md-level-4");
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 79b5244f44f4..950e5fa6e1f2 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -2304,9 +2304,10 @@ static void raid6_quiesce(mddev_t *mddev, int state)
2304 } 2304 }
2305} 2305}
2306 2306
2307static mdk_personality_t raid6_personality= 2307static struct mdk_personality raid6_personality =
2308{ 2308{
2309 .name = "raid6", 2309 .name = "raid6",
2310 .level = 6,
2310 .owner = THIS_MODULE, 2311 .owner = THIS_MODULE,
2311 .make_request = make_request, 2312 .make_request = make_request,
2312 .run = run, 2313 .run = run,
@@ -2321,7 +2322,7 @@ static mdk_personality_t raid6_personality=
2321 .quiesce = raid6_quiesce, 2322 .quiesce = raid6_quiesce,
2322}; 2323};
2323 2324
2324static int __init raid6_init (void) 2325static int __init raid6_init(void)
2325{ 2326{
2326 int e; 2327 int e;
2327 2328
@@ -2329,15 +2330,16 @@ static int __init raid6_init (void)
2329 if ( e ) 2330 if ( e )
2330 return e; 2331 return e;
2331 2332
2332 return register_md_personality (RAID6, &raid6_personality); 2333 return register_md_personality(&raid6_personality);
2333} 2334}
2334 2335
2335static void raid6_exit (void) 2336static void raid6_exit (void)
2336{ 2337{
2337 unregister_md_personality (RAID6); 2338 unregister_md_personality(&raid6_personality);
2338} 2339}
2339 2340
2340module_init(raid6_init); 2341module_init(raid6_init);
2341module_exit(raid6_exit); 2342module_exit(raid6_exit);
2342MODULE_LICENSE("GPL"); 2343MODULE_LICENSE("GPL");
2343MODULE_ALIAS("md-personality-8"); /* RAID6 */ 2344MODULE_ALIAS("md-personality-8"); /* RAID6 */
2345MODULE_ALIAS("md-level-6");
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index 13e7c4b62367..b6e0bcad84e1 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -71,8 +71,8 @@
71 */ 71 */
72#define MD_PATCHLEVEL_VERSION 3 72#define MD_PATCHLEVEL_VERSION 3
73 73
74extern int register_md_personality (int p_num, mdk_personality_t *p); 74extern int register_md_personality (struct mdk_personality *p);
75extern int unregister_md_personality (int p_num); 75extern int unregister_md_personality (struct mdk_personality *p);
76extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), 76extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev),
77 mddev_t *mddev, const char *name); 77 mddev_t *mddev, const char *name);
78extern void md_unregister_thread (mdk_thread_t *thread); 78extern void md_unregister_thread (mdk_thread_t *thread);
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 1dd587b5975a..e559fb701aa1 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -18,62 +18,19 @@
18/* and dm-bio-list.h is not under include/linux because.... ??? */ 18/* and dm-bio-list.h is not under include/linux because.... ??? */
19#include "../../../drivers/md/dm-bio-list.h" 19#include "../../../drivers/md/dm-bio-list.h"
20 20
21#define MD_RESERVED 0UL
22#define LINEAR 1UL
23#define RAID0 2UL
24#define RAID1 3UL
25#define RAID5 4UL
26#define TRANSLUCENT 5UL
27#define HSM 6UL
28#define MULTIPATH 7UL
29#define RAID6 8UL
30#define RAID10 9UL
31#define FAULTY 10UL
32#define MAX_PERSONALITY 11UL
33
34#define LEVEL_MULTIPATH (-4) 21#define LEVEL_MULTIPATH (-4)
35#define LEVEL_LINEAR (-1) 22#define LEVEL_LINEAR (-1)
36#define LEVEL_FAULTY (-5) 23#define LEVEL_FAULTY (-5)
37 24
25/* we need a value for 'no level specified' and 0
26 * means 'raid0', so we need something else. This is
27 * for internal use only
28 */
29#define LEVEL_NONE (-1000000)
30
38#define MaxSector (~(sector_t)0) 31#define MaxSector (~(sector_t)0)
39#define MD_THREAD_NAME_MAX 14 32#define MD_THREAD_NAME_MAX 14
40 33
41static inline int pers_to_level (int pers)
42{
43 switch (pers) {
44 case FAULTY: return LEVEL_FAULTY;
45 case MULTIPATH: return LEVEL_MULTIPATH;
46 case HSM: return -3;
47 case TRANSLUCENT: return -2;
48 case LINEAR: return LEVEL_LINEAR;
49 case RAID0: return 0;
50 case RAID1: return 1;
51 case RAID5: return 5;
52 case RAID6: return 6;
53 case RAID10: return 10;
54 }
55 BUG();
56 return MD_RESERVED;
57}
58
59static inline int level_to_pers (int level)
60{
61 switch (level) {
62 case LEVEL_FAULTY: return FAULTY;
63 case LEVEL_MULTIPATH: return MULTIPATH;
64 case -3: return HSM;
65 case -2: return TRANSLUCENT;
66 case LEVEL_LINEAR: return LINEAR;
67 case 0: return RAID0;
68 case 1: return RAID1;
69 case 4:
70 case 5: return RAID5;
71 case 6: return RAID6;
72 case 10: return RAID10;
73 }
74 return MD_RESERVED;
75}
76
77typedef struct mddev_s mddev_t; 34typedef struct mddev_s mddev_t;
78typedef struct mdk_rdev_s mdk_rdev_t; 35typedef struct mdk_rdev_s mdk_rdev_t;
79 36
@@ -140,12 +97,10 @@ struct mdk_rdev_s
140 */ 97 */
141}; 98};
142 99
143typedef struct mdk_personality_s mdk_personality_t;
144
145struct mddev_s 100struct mddev_s
146{ 101{
147 void *private; 102 void *private;
148 mdk_personality_t *pers; 103 struct mdk_personality *pers;
149 dev_t unit; 104 dev_t unit;
150 int md_minor; 105 int md_minor;
151 struct list_head disks; 106 struct list_head disks;
@@ -266,9 +221,11 @@ static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sect
266 atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io); 221 atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
267} 222}
268 223
269struct mdk_personality_s 224struct mdk_personality
270{ 225{
271 char *name; 226 char *name;
227 int level;
228 struct list_head list;
272 struct module *owner; 229 struct module *owner;
273 int (*make_request)(request_queue_t *q, struct bio *bio); 230 int (*make_request)(request_queue_t *q, struct bio *bio);
274 int (*run)(mddev_t *mddev); 231 int (*run)(mddev_t *mddev);
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 3fbc3555ce96..f6f36806f84a 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -17,7 +17,7 @@ static int __initdata raid_noautodetect, raid_autopart;
17static struct { 17static struct {
18 int minor; 18 int minor;
19 int partitioned; 19 int partitioned;
20 int pers; 20 int level;
21 int chunk; 21 int chunk;
22 char *device_names; 22 char *device_names;
23} md_setup_args[MAX_MD_DEVS] __initdata; 23} md_setup_args[MAX_MD_DEVS] __initdata;
@@ -47,7 +47,7 @@ extern int mdp_major;
47 */ 47 */
48static int __init md_setup(char *str) 48static int __init md_setup(char *str)
49{ 49{
50 int minor, level, factor, fault, pers, partitioned = 0; 50 int minor, level, factor, fault, partitioned = 0;
51 char *pername = ""; 51 char *pername = "";
52 char *str1; 52 char *str1;
53 int ent; 53 int ent;
@@ -78,7 +78,7 @@ static int __init md_setup(char *str)
78 } 78 }
79 if (ent >= md_setup_ents) 79 if (ent >= md_setup_ents)
80 md_setup_ents++; 80 md_setup_ents++;
81 switch (get_option(&str, &level)) { /* RAID Personality */ 81 switch (get_option(&str, &level)) { /* RAID level */
82 case 2: /* could be 0 or -1.. */ 82 case 2: /* could be 0 or -1.. */
83 if (level == 0 || level == LEVEL_LINEAR) { 83 if (level == 0 || level == LEVEL_LINEAR) {
84 if (get_option(&str, &factor) != 2 || /* Chunk Size */ 84 if (get_option(&str, &factor) != 2 || /* Chunk Size */
@@ -86,16 +86,12 @@ static int __init md_setup(char *str)
86 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); 86 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
87 return 0; 87 return 0;
88 } 88 }
89 md_setup_args[ent].pers = level; 89 md_setup_args[ent].level = level;
90 md_setup_args[ent].chunk = 1 << (factor+12); 90 md_setup_args[ent].chunk = 1 << (factor+12);
91 if (level == LEVEL_LINEAR) { 91 if (level == LEVEL_LINEAR)
92 pers = LINEAR;
93 pername = "linear"; 92 pername = "linear";
94 } else { 93 else
95 pers = RAID0;
96 pername = "raid0"; 94 pername = "raid0";
97 }
98 md_setup_args[ent].pers = pers;
99 break; 95 break;
100 } 96 }
101 /* FALL THROUGH */ 97 /* FALL THROUGH */
@@ -103,7 +99,7 @@ static int __init md_setup(char *str)
103 str = str1; 99 str = str1;
104 /* FALL THROUGH */ 100 /* FALL THROUGH */
105 case 0: 101 case 0:
106 md_setup_args[ent].pers = 0; 102 md_setup_args[ent].level = LEVEL_NONE;
107 pername="super-block"; 103 pername="super-block";
108 } 104 }
109 105
@@ -190,10 +186,10 @@ static void __init md_setup_drive(void)
190 continue; 186 continue;
191 } 187 }
192 188
193 if (md_setup_args[ent].pers) { 189 if (md_setup_args[ent].level != LEVEL_NONE) {
194 /* non-persistent */ 190 /* non-persistent */
195 mdu_array_info_t ainfo; 191 mdu_array_info_t ainfo;
196 ainfo.level = pers_to_level(md_setup_args[ent].pers); 192 ainfo.level = md_setup_args[ent].level;
197 ainfo.size = 0; 193 ainfo.size = 0;
198 ainfo.nr_disks =0; 194 ainfo.nr_disks =0;
199 ainfo.raid_disks =0; 195 ainfo.raid_disks =0;