aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c79
1 files changed, 29 insertions, 50 deletions
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}