Commit c418d3f8 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] md: Convert md personalities to new module interface

Thanks to  Angus Sawyer <angus.sawyer@dsl.pipex.com> and
   Daniel McNeil <daniel@osdl.org>
parent becf88fa
...@@ -79,8 +79,6 @@ static int linear_run (mddev_t *mddev) ...@@ -79,8 +79,6 @@ static int linear_run (mddev_t *mddev)
unsigned int curr_offset; unsigned int curr_offset;
struct list_head *tmp; struct list_head *tmp;
MOD_INC_USE_COUNT;
conf = kmalloc (sizeof (*conf), GFP_KERNEL); conf = kmalloc (sizeof (*conf), GFP_KERNEL);
if (!conf) if (!conf)
goto out; goto out;
...@@ -167,7 +165,6 @@ static int linear_run (mddev_t *mddev) ...@@ -167,7 +165,6 @@ static int linear_run (mddev_t *mddev)
out: out:
if (conf) if (conf)
kfree(conf); kfree(conf);
MOD_DEC_USE_COUNT;
return 1; return 1;
} }
...@@ -178,8 +175,6 @@ static int linear_stop (mddev_t *mddev) ...@@ -178,8 +175,6 @@ static int linear_stop (mddev_t *mddev)
kfree(conf->hash_table); kfree(conf->hash_table);
kfree(conf); kfree(conf);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -246,6 +241,7 @@ static void linear_status (struct seq_file *seq, mddev_t *mddev) ...@@ -246,6 +241,7 @@ static void linear_status (struct seq_file *seq, mddev_t *mddev)
static mdk_personality_t linear_personality= static mdk_personality_t linear_personality=
{ {
.name = "linear", .name = "linear",
.owner = THIS_MODULE,
.make_request = linear_make_request, .make_request = linear_make_request,
.run = linear_run, .run = linear_run,
.stop = linear_stop, .stop = linear_stop,
......
...@@ -64,6 +64,7 @@ static void autostart_arrays (void); ...@@ -64,6 +64,7 @@ static void autostart_arrays (void);
#endif #endif
static mdk_personality_t *pers[MAX_PERSONALITY]; static mdk_personality_t *pers[MAX_PERSONALITY];
static spinlock_t pers_lock = SPIN_LOCK_UNLOCKED;
/* /*
* Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit' * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
...@@ -1648,20 +1649,14 @@ static int do_md_run(mddev_t * mddev) ...@@ -1648,20 +1649,14 @@ static int do_md_run(mddev_t * mddev)
return -EINVAL; return -EINVAL;
} }
#ifdef CONFIG_KMOD
if (!pers[pnum]) if (!pers[pnum])
{ {
#ifdef CONFIG_KMOD
char module_name[80]; char module_name[80];
sprintf (module_name, "md-personality-%d", pnum); sprintf (module_name, "md-personality-%d", pnum);
request_module (module_name); request_module (module_name);
if (!pers[pnum])
#endif
{
printk(KERN_ERR "md: personality %d is not loaded!\n",
pnum);
return -EINVAL;
}
} }
#endif
if (device_size_calculation(mddev)) if (device_size_calculation(mddev))
return -EINVAL; return -EINVAL;
...@@ -1695,7 +1690,17 @@ static int do_md_run(mddev_t * mddev) ...@@ -1695,7 +1690,17 @@ static int do_md_run(mddev_t * mddev)
disk = disks[mdidx(mddev)]; disk = disks[mdidx(mddev)];
if (!disk) if (!disk)
return -ENOMEM; return -ENOMEM;
spin_lock(&pers_lock);
if (!pers[pnum] || !try_module_get(pers[pnum]->owner)) {
spin_unlock(&pers_lock);
printk(KERN_ERR "md: personality %d is not loaded!\n",
pnum);
return -EINVAL;
}
mddev->pers = pers[pnum]; mddev->pers = pers[pnum];
spin_unlock(&pers_lock);
blk_queue_make_request(&mddev->queue, mddev->pers->make_request); blk_queue_make_request(&mddev->queue, mddev->pers->make_request);
printk("%s: setting max_sectors to %d, segment boundary to %d\n", printk("%s: setting max_sectors to %d, segment boundary to %d\n",
...@@ -1710,6 +1715,7 @@ static int do_md_run(mddev_t * mddev) ...@@ -1710,6 +1715,7 @@ static int do_md_run(mddev_t * mddev)
if (err) { if (err) {
printk(KERN_ERR "md: pers->run() failed ...\n"); printk(KERN_ERR "md: pers->run() failed ...\n");
mddev->pers = NULL; mddev->pers = NULL;
module_put(mddev->pers->owner);
return -EINVAL; return -EINVAL;
} }
atomic_set(&mddev->writes_pending,0); atomic_set(&mddev->writes_pending,0);
...@@ -1800,6 +1806,7 @@ static int do_md_stop(mddev_t * mddev, int ro) ...@@ -1800,6 +1806,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
set_disk_ro(disk, 1); set_disk_ro(disk, 1);
goto out; goto out;
} }
module_put(mddev->pers->owner);
mddev->pers = NULL; mddev->pers = NULL;
if (mddev->ro) if (mddev->ro)
mddev->ro = 0; mddev->ro = 0;
...@@ -3006,10 +3013,12 @@ static int md_seq_show(struct seq_file *seq, void *v) ...@@ -3006,10 +3013,12 @@ static int md_seq_show(struct seq_file *seq, void *v)
if (v == (void*)1) { if (v == (void*)1) {
seq_printf(seq, "Personalities : "); seq_printf(seq, "Personalities : ");
spin_lock(&pers_lock);
for (i = 0; i < MAX_PERSONALITY; i++) for (i = 0; i < MAX_PERSONALITY; i++)
if (pers[i]) if (pers[i])
seq_printf(seq, "[%s] ", pers[i]->name); seq_printf(seq, "[%s] ", pers[i]->name);
spin_unlock(&pers_lock);
seq_printf(seq, "\n"); seq_printf(seq, "\n");
return 0; return 0;
} }
...@@ -3093,13 +3102,16 @@ int register_md_personality(int pnum, mdk_personality_t *p) ...@@ -3093,13 +3102,16 @@ int register_md_personality(int pnum, mdk_personality_t *p)
return -EINVAL; return -EINVAL;
} }
spin_lock(&pers_lock);
if (pers[pnum]) { if (pers[pnum]) {
spin_unlock(&pers_lock);
MD_BUG(); MD_BUG();
return -EBUSY; return -EBUSY;
} }
pers[pnum] = p; pers[pnum] = p;
printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum); printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum);
spin_unlock(&pers_lock);
return 0; return 0;
} }
...@@ -3111,7 +3123,9 @@ int unregister_md_personality(int pnum) ...@@ -3111,7 +3123,9 @@ int unregister_md_personality(int pnum)
} }
printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name); printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
spin_lock(&pers_lock);
pers[pnum] = NULL; pers[pnum] = NULL;
spin_unlock(&pers_lock);
return 0; return 0;
} }
......
...@@ -365,8 +365,6 @@ static int multipath_run (mddev_t *mddev) ...@@ -365,8 +365,6 @@ static int multipath_run (mddev_t *mddev)
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp; struct list_head *tmp;
MOD_INC_USE_COUNT;
if (mddev->level != LEVEL_MULTIPATH) { if (mddev->level != LEVEL_MULTIPATH) {
printk("multipath: md%d: raid level not set to multipath IO (%d)\n", printk("multipath: md%d: raid level not set to multipath IO (%d)\n",
mdidx(mddev), mddev->level); mdidx(mddev), mddev->level);
...@@ -448,7 +446,6 @@ static int multipath_run (mddev_t *mddev) ...@@ -448,7 +446,6 @@ static int multipath_run (mddev_t *mddev)
kfree(conf); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
out: out:
MOD_DEC_USE_COUNT;
return -EIO; return -EIO;
} }
...@@ -461,13 +458,13 @@ static int multipath_stop (mddev_t *mddev) ...@@ -461,13 +458,13 @@ static int multipath_stop (mddev_t *mddev)
mempool_destroy(conf->pool); mempool_destroy(conf->pool);
kfree(conf); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
static mdk_personality_t multipath_personality= static mdk_personality_t multipath_personality=
{ {
.name = "multipath", .name = "multipath",
.owner = THIS_MODULE,
.make_request = multipath_make_request, .make_request = multipath_make_request,
.run = multipath_run, .run = multipath_run,
.stop = multipath_stop, .stop = multipath_stop,
......
...@@ -197,8 +197,6 @@ static int raid0_run (mddev_t *mddev) ...@@ -197,8 +197,6 @@ static int raid0_run (mddev_t *mddev)
s64 size; s64 size;
raid0_conf_t *conf; raid0_conf_t *conf;
MOD_INC_USE_COUNT;
conf = vmalloc(sizeof (raid0_conf_t)); conf = vmalloc(sizeof (raid0_conf_t));
if (!conf) if (!conf)
goto out; goto out;
...@@ -275,7 +273,6 @@ static int raid0_run (mddev_t *mddev) ...@@ -275,7 +273,6 @@ static int raid0_run (mddev_t *mddev)
vfree(conf); vfree(conf);
mddev->private = NULL; mddev->private = NULL;
out: out:
MOD_DEC_USE_COUNT;
return 1; return 1;
} }
...@@ -290,7 +287,6 @@ static int raid0_stop (mddev_t *mddev) ...@@ -290,7 +287,6 @@ static int raid0_stop (mddev_t *mddev)
vfree (conf); vfree (conf);
mddev->private = NULL; mddev->private = NULL;
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -424,6 +420,7 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev) ...@@ -424,6 +420,7 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev)
static mdk_personality_t raid0_personality= static mdk_personality_t raid0_personality=
{ {
.name = "raid0", .name = "raid0",
.owner = THIS_MODULE,
.make_request = raid0_make_request, .make_request = raid0_make_request,
.run = raid0_run, .run = raid0_run,
.stop = raid0_stop, .stop = raid0_stop,
......
...@@ -1061,8 +1061,6 @@ static int run(mddev_t *mddev) ...@@ -1061,8 +1061,6 @@ static int run(mddev_t *mddev)
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp; struct list_head *tmp;
MOD_INC_USE_COUNT;
if (mddev->level != 1) { if (mddev->level != 1) {
printk("raid1: md%d: raid level not set to mirroring (%d)\n", printk("raid1: md%d: raid level not set to mirroring (%d)\n",
mdidx(mddev), mddev->level); mdidx(mddev), mddev->level);
...@@ -1166,7 +1164,6 @@ static int run(mddev_t *mddev) ...@@ -1166,7 +1164,6 @@ static int run(mddev_t *mddev)
kfree(conf); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
out: out:
MOD_DEC_USE_COUNT;
return -EIO; return -EIO;
} }
...@@ -1180,13 +1177,13 @@ static int stop(mddev_t *mddev) ...@@ -1180,13 +1177,13 @@ static int stop(mddev_t *mddev)
mempool_destroy(conf->r1bio_pool); mempool_destroy(conf->r1bio_pool);
kfree(conf); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
static mdk_personality_t raid1_personality = static mdk_personality_t raid1_personality =
{ {
.name = "raid1", .name = "raid1",
.owner = THIS_MODULE,
.make_request = make_request, .make_request = make_request,
.run = run, .run = run,
.stop = stop, .stop = stop,
......
...@@ -1433,11 +1433,8 @@ static int run (mddev_t *mddev) ...@@ -1433,11 +1433,8 @@ static int run (mddev_t *mddev)
struct disk_info *disk; struct disk_info *disk;
struct list_head *tmp; struct list_head *tmp;
MOD_INC_USE_COUNT;
if (mddev->level != 5 && mddev->level != 4) { if (mddev->level != 5 && mddev->level != 4) {
printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), mddev->level); printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), mddev->level);
MOD_DEC_USE_COUNT;
return -EIO; return -EIO;
} }
...@@ -1563,7 +1560,6 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + ...@@ -1563,7 +1560,6 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
} }
mddev->private = NULL; mddev->private = NULL;
printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev)); printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev));
MOD_DEC_USE_COUNT;
return -EIO; return -EIO;
} }
...@@ -1579,7 +1575,6 @@ static int stop (mddev_t *mddev) ...@@ -1579,7 +1575,6 @@ static int stop (mddev_t *mddev)
free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
kfree(conf); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -1735,6 +1730,7 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -1735,6 +1730,7 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
static mdk_personality_t raid5_personality= static mdk_personality_t raid5_personality=
{ {
.name = "raid5", .name = "raid5",
.owner = THIS_MODULE,
.make_request = make_request, .make_request = make_request,
.run = run, .run = run,
.stop = stop, .stop = stop,
......
...@@ -254,6 +254,7 @@ struct mddev_s ...@@ -254,6 +254,7 @@ struct mddev_s
struct mdk_personality_s struct mdk_personality_s
{ {
char *name; char *name;
struct module *owner;
int (*make_request)(request_queue_t *q, struct bio *bio); int (*make_request)(request_queue_t *q, struct bio *bio);
int (*run)(mddev_t *mddev); int (*run)(mddev_t *mddev);
int (*stop)(mddev_t *mddev); int (*stop)(mddev_t *mddev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment