#endif
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'
return -EINVAL;
}
+#ifdef CONFIG_KMOD
if (!pers[pnum])
{
-#ifdef CONFIG_KMOD
char module_name[80];
sprintf (module_name, "md-personality-%d", pnum);
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))
return -EINVAL;
disk = disks[mdidx(mddev)];
if (!disk)
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];
+ spin_unlock(&pers_lock);
blk_queue_make_request(&mddev->queue, mddev->pers->make_request);
printk("%s: setting max_sectors to %d, segment boundary to %d\n",
if (err) {
printk(KERN_ERR "md: pers->run() failed ...\n");
mddev->pers = NULL;
+ module_put(mddev->pers->owner);
return -EINVAL;
}
atomic_set(&mddev->writes_pending,0);
set_disk_ro(disk, 1);
goto out;
}
+ module_put(mddev->pers->owner);
mddev->pers = NULL;
if (mddev->ro)
mddev->ro = 0;
if (v == (void*)1) {
seq_printf(seq, "Personalities : ");
+ spin_lock(&pers_lock);
for (i = 0; i < MAX_PERSONALITY; i++)
if (pers[i])
seq_printf(seq, "[%s] ", pers[i]->name);
+ spin_unlock(&pers_lock);
seq_printf(seq, "\n");
return 0;
}
return -EINVAL;
}
+ spin_lock(&pers_lock);
if (pers[pnum]) {
+ spin_unlock(&pers_lock);
MD_BUG();
return -EBUSY;
}
pers[pnum] = p;
printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum);
+ spin_unlock(&pers_lock);
return 0;
}
}
printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
+ spin_lock(&pers_lock);
pers[pnum] = NULL;
+ spin_unlock(&pers_lock);
return 0;
}
mdk_rdev_t *rdev;
struct list_head *tmp;
- MOD_INC_USE_COUNT;
-
if (mddev->level != LEVEL_MULTIPATH) {
printk("multipath: md%d: raid level not set to multipath IO (%d)\n",
mdidx(mddev), mddev->level);
kfree(conf);
mddev->private = NULL;
out:
- MOD_DEC_USE_COUNT;
return -EIO;
}
mempool_destroy(conf->pool);
kfree(conf);
mddev->private = NULL;
- MOD_DEC_USE_COUNT;
return 0;
}
static mdk_personality_t multipath_personality=
{
.name = "multipath",
+ .owner = THIS_MODULE,
.make_request = multipath_make_request,
.run = multipath_run,
.stop = multipath_stop,
mdk_rdev_t *rdev;
struct list_head *tmp;
- MOD_INC_USE_COUNT;
-
if (mddev->level != 1) {
printk("raid1: md%d: raid level not set to mirroring (%d)\n",
mdidx(mddev), mddev->level);
kfree(conf);
mddev->private = NULL;
out:
- MOD_DEC_USE_COUNT;
return -EIO;
}
mempool_destroy(conf->r1bio_pool);
kfree(conf);
mddev->private = NULL;
- MOD_DEC_USE_COUNT;
return 0;
}
static mdk_personality_t raid1_personality =
{
.name = "raid1",
+ .owner = THIS_MODULE,
.make_request = make_request,
.run = run,
.stop = stop,
struct disk_info *disk;
struct list_head *tmp;
- MOD_INC_USE_COUNT;
-
if (mddev->level != 5 && mddev->level != 4) {
printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), mddev->level);
- MOD_DEC_USE_COUNT;
return -EIO;
}
}
mddev->private = NULL;
printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev));
- MOD_DEC_USE_COUNT;
return -EIO;
}
free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
kfree(conf);
mddev->private = NULL;
- MOD_DEC_USE_COUNT;
return 0;
}
static mdk_personality_t raid5_personality=
{
.name = "raid5",
+ .owner = THIS_MODULE,
.make_request = make_request,
.run = run,
.stop = stop,