lkml.org 
[lkml]   [2003]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH 2.5.65] update md driver to new module API
From
Date
This patch updates the md driver and personalities to the new
module interfaces.

An owner field has been added to the struct mdk_personality_s.
This is initialized by each personality module. The md driver
now attempts to take a reference to the personality before calling
the personality's run routine. A pers_lock was added to protect
the setting, clearing and reading of pers[] entries. This protects
try_module_get() racing with unregister_md_personality().

I have tested each personality as a module.

--
Daniel McNeil <daniel@osdl.org>
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/arch/i386/kernel/i386_ksyms.c linux-2.5.65-md/arch/i386/kernel/i386_ksyms.c
--- linux-2.5.65/arch/i386/kernel/i386_ksyms.c Mon Mar 17 13:44:50 2003
+++ linux-2.5.65-md/arch/i386/kernel/i386_ksyms.c Wed Mar 19 11:27:53 2003
@@ -76,6 +76,7 @@ EXPORT_SYMBOL(xquad_portio);
#ifndef CONFIG_X86_WP_WORKS_OK
EXPORT_SYMBOL(__verify_write);
#endif
+EXPORT_SYMBOL(kernel_fpu_begin);
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(dump_extended_fpu);
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/drivers/md/linear.c linux-2.5.65-md/drivers/md/linear.c
--- linux-2.5.65/drivers/md/linear.c Mon Mar 17 13:44:04 2003
+++ linux-2.5.65-md/drivers/md/linear.c Wed Mar 19 14:43:10 2003
@@ -75,8 +75,6 @@ static int linear_run (mddev_t *mddev)
unsigned int curr_offset;
struct list_head *tmp;

- MOD_INC_USE_COUNT;
-
conf = kmalloc (sizeof (*conf), GFP_KERNEL);
if (!conf)
goto out;
@@ -163,7 +161,6 @@ static int linear_run (mddev_t *mddev)
out:
if (conf)
kfree(conf);
- MOD_DEC_USE_COUNT;
return 1;
}

@@ -174,8 +171,6 @@ static int linear_stop (mddev_t *mddev)
kfree(conf->hash_table);
kfree(conf);

- MOD_DEC_USE_COUNT;
-
return 0;
}

@@ -241,6 +236,7 @@ static mdk_personality_t linear_personal
.run = linear_run,
.stop = linear_stop,
.status = linear_status,
+ .owner = THIS_MODULE
};

static int __init linear_init (void)
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/drivers/md/md.c linux-2.5.65-md/drivers/md/md.c
--- linux-2.5.65/drivers/md/md.c Mon Mar 17 13:43:50 2003
+++ linux-2.5.65-md/drivers/md/md.c Tue Mar 18 17:25:02 2003
@@ -63,6 +63,12 @@
static void autostart_arrays (void);
#endif

+/*
+ * pers_lock protects the setting, clearing and reading of pers[] entries.
+ * This protects try_module_get() racing with unregister_md_personality().
+ */
+static spinlock_t pers_lock = SPIN_LOCK_UNLOCKED;
+
static mdk_personality_t *pers[MAX_PERSONALITY];

/*
@@ -182,7 +188,6 @@ static void mddev_put(mddev_t *mddev)
list_del(&mddev->all_mddevs);
mddev_map[mdidx(mddev)] = NULL;
kfree(mddev);
- MOD_DEC_USE_COUNT;
}
spin_unlock(&all_mddevs_lock);
}
@@ -204,7 +209,6 @@ static mddev_t * mddev_find(int unit)
mddev_map[unit] = new;
list_add(&new->all_mddevs, &all_mddevs);
spin_unlock(&all_mddevs_lock);
- MOD_INC_USE_COUNT;
return new;
}
spin_unlock(&all_mddevs_lock);
@@ -1605,6 +1609,7 @@ static int do_md_run(mddev_t * mddev)
struct list_head *tmp;
mdk_rdev_t *rdev;
struct gendisk *disk;
+ mdk_personality_t *per;

if (list_empty(&mddev->disks)) {
MD_BUG();
@@ -1664,23 +1669,29 @@ static int do_md_run(mddev_t * mddev)
return -EINVAL;
}

- if (!pers[pnum])
- {
#ifdef CONFIG_KMOD
+ if (!pers[pnum]) {
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);
+ /*
+ * Get a module reference for the personality.
+ */
+ spin_lock(&pers_lock);
+ per = pers[pnum];
+ if (per == 0 || !try_module_get(per->owner)) {
+ spin_unlock(&pers_lock);
+ printk(KERN_ERR "md: personality %d is not loaded!\n", pnum);
return -EINVAL;
- }
}
+ spin_unlock(&pers_lock);

- if (device_size_calculation(mddev))
+ if (device_size_calculation(mddev)) {
+ module_put(per->owner); /* drop ref on personality */
return -EINVAL;
+ }

/*
* Drop all container device buffers, from now on
@@ -1709,9 +1720,11 @@ static int do_md_run(mddev_t * mddev)

md_probe(mdidx(mddev), NULL, NULL);
disk = disks[mdidx(mddev)];
- if (!disk)
+ if (!disk) {
+ module_put(per->owner); /* drop ref on personality */
return -ENOMEM;
- mddev->pers = pers[pnum];
+ }
+ mddev->pers = per;

blk_queue_make_request(&mddev->queue, mddev->pers->make_request);
printk("%s: setting max_sectors to %d, segment boundary to %d\n",
@@ -1724,6 +1737,7 @@ static int do_md_run(mddev_t * mddev)

err = mddev->pers->run(mddev);
if (err) {
+ module_put(per->owner); /* drop ref on personality */
printk(KERN_ERR "md: pers->run() failed ...\n");
mddev->pers = NULL;
return -EINVAL;
@@ -1826,6 +1840,10 @@ static int do_md_stop(mddev_t * mddev, i
set_disk_ro(disk, 1);
goto out;
}
+ /*
+ * Drop module reference to personality.
+ */
+ module_put(mddev->pers->owner);
mddev->pers = NULL;
if (mddev->ro)
mddev->ro = 0;
@@ -3040,10 +3058,12 @@ static int md_seq_show(struct seq_file *

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;
}
@@ -3127,12 +3147,15 @@ int register_md_personality(int pnum, md
return -EINVAL;
}

+ spin_lock(&pers_lock);
if (pers[pnum]) {
+ spin_unlock(&pers_lock);
MD_BUG();
return -EBUSY;
}

pers[pnum] = p;
+ spin_unlock(&pers_lock);
printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum);
return 0;
}
@@ -3145,7 +3168,9 @@ int unregister_md_personality(int pnum)
}

printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
+ spin_lock(&pers_lock);
pers[pnum] = NULL;
+ spin_unlock(&pers_lock);
return 0;
}

diff -rupN -X /home/daniel/dontdiff linux-2.5.65/drivers/md/multipath.c linux-2.5.65-md/drivers/md/multipath.c
--- linux-2.5.65/drivers/md/multipath.c Mon Mar 17 13:44:05 2003
+++ linux-2.5.65-md/drivers/md/multipath.c Tue Mar 18 17:27:28 2003
@@ -416,8 +416,6 @@ static int multipath_run (mddev_t *mddev
mdk_rdev_t *rdev;
struct list_head *tmp;

- MOD_INC_USE_COUNT;
-
if (mddev->level != LEVEL_MULTIPATH) {
printk(INVALID_LEVEL, mdidx(mddev), mddev->level);
goto out;
@@ -491,7 +489,6 @@ out_free_conf:
kfree(conf);
mddev->private = NULL;
out:
- MOD_DEC_USE_COUNT;
return -EIO;
}

@@ -515,7 +512,6 @@ static int multipath_stop (mddev_t *mdde
mempool_destroy(conf->pool);
kfree(conf);
mddev->private = NULL;
- MOD_DEC_USE_COUNT;
return 0;
}

@@ -529,6 +525,7 @@ static mdk_personality_t multipath_perso
.error_handler = multipath_error,
.hot_add_disk = multipath_add_disk,
.hot_remove_disk= multipath_remove_disk,
+ .owner = THIS_MODULE
};

static int __init multipath_init (void)
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/drivers/md/raid0.c linux-2.5.65-md/drivers/md/raid0.c
--- linux-2.5.65/drivers/md/raid0.c Mon Mar 17 13:44:07 2003
+++ linux-2.5.65-md/drivers/md/raid0.c Tue Mar 18 17:28:22 2003
@@ -191,8 +191,6 @@ static int raid0_run (mddev_t *mddev)
s64 size;
raid0_conf_t *conf;

- MOD_INC_USE_COUNT;
-
conf = vmalloc(sizeof (raid0_conf_t));
if (!conf)
goto out;
@@ -267,7 +265,6 @@ out_free_conf:
vfree(conf);
mddev->private = NULL;
out:
- MOD_DEC_USE_COUNT;
return 1;
}

@@ -282,7 +279,6 @@ static int raid0_stop (mddev_t *mddev)
vfree (conf);
mddev->private = NULL;

- MOD_DEC_USE_COUNT;
return 0;
}

@@ -415,6 +411,7 @@ static mdk_personality_t raid0_personali
.run = raid0_run,
.stop = raid0_stop,
.status = raid0_status,
+ .owner = THIS_MODULE
};

static int __init raid0_init (void)
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/drivers/md/raid1.c linux-2.5.65-md/drivers/md/raid1.c
--- linux-2.5.65/drivers/md/raid1.c Mon Mar 17 13:44:07 2003
+++ linux-2.5.65-md/drivers/md/raid1.c Tue Mar 18 17:29:10 2003
@@ -1109,8 +1109,6 @@ static int run(mddev_t *mddev)
mdk_rdev_t *rdev;
struct list_head *tmp;

- MOD_INC_USE_COUNT;
-
if (mddev->level != 1) {
printk(INVALID_LEVEL, mdidx(mddev), mddev->level);
goto out;
@@ -1206,7 +1204,6 @@ out_free_conf:
kfree(conf);
mddev->private = NULL;
out:
- MOD_DEC_USE_COUNT;
return -EIO;
}

@@ -1220,7 +1217,6 @@ static int stop(mddev_t *mddev)
mempool_destroy(conf->r1bio_pool);
kfree(conf);
mddev->private = NULL;
- MOD_DEC_USE_COUNT;
return 0;
}

@@ -1236,6 +1232,7 @@ static mdk_personality_t raid1_personali
.hot_remove_disk= raid1_remove_disk,
.spare_active = raid1_spare_active,
.sync_request = sync_request,
+ .owner = THIS_MODULE
};

static int __init raid_init(void)
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/drivers/md/raid5.c linux-2.5.65-md/drivers/md/raid5.c
--- linux-2.5.65/drivers/md/raid5.c Mon Mar 17 13:43:45 2003
+++ linux-2.5.65-md/drivers/md/raid5.c Tue Mar 18 17:29:45 2003
@@ -1410,11 +1410,8 @@ static int run (mddev_t *mddev)
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;
}

@@ -1524,7 +1521,6 @@ abort:
}
mddev->private = NULL;
printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev));
- MOD_DEC_USE_COUNT;
return -EIO;
}

@@ -1540,7 +1536,6 @@ static int stop (mddev_t *mddev)
free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
kfree(conf);
mddev->private = NULL;
- MOD_DEC_USE_COUNT;
return 0;
}

@@ -1702,6 +1697,7 @@ static mdk_personality_t raid5_personali
.hot_remove_disk= raid5_remove_disk,
.spare_active = raid5_spare_active,
.sync_request = sync_request,
+ .owner = THIS_MODULE
};

static int __init raid5_init (void)
diff -rupN -X /home/daniel/dontdiff linux-2.5.65/include/linux/raid/md_k.h linux-2.5.65-md/include/linux/raid/md_k.h
--- linux-2.5.65/include/linux/raid/md_k.h Mon Mar 17 13:43:39 2003
+++ linux-2.5.65-md/include/linux/raid/md_k.h Tue Mar 18 17:04:30 2003
@@ -266,6 +266,7 @@ struct mdk_personality_s
int (*hot_remove_disk) (mddev_t *mddev, int number);
int (*spare_active) (mddev_t *mddev);
int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster);
+ struct module *owner;
};

\
 
 \ /
  Last update: 2005-03-22 13:34    [W:0.025 / U:0.416 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site