mtd/drivers/mtd mtdcore.c,1.34,1.35 mtdpart.c,1.34,1.35
David Woodhouse
dwmw2 at infradead.org
Wed May 14 18:27:00 EDT 2003
- Previous message: mtd/include/linux/mtd compatmac.h,1.48,1.49 mtd.h,1.42,1.43
- Next message: mtd/drivers/mtd/devices blkmtd-25.c,1.2,1.3 blkmtd.c,1.17,1.18
doc2000.c,1.50,1.51 doc2001.c,1.38,1.39 lart.c,1.3,1.4
ms02-nv.c,1.2,1.3 mtdram.c,1.29,1.30 pmc551.c,1.22,1.23slram.c,1.28,1.29
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv14262/drivers/mtd
Modified Files:
mtdcore.c mtdpart.c
Log Message:
fix races in get_mtd_device etc, use set_module_owner everywhere
Index: mtdcore.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtdcore.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- mtdcore.c 24 Jan 2003 23:32:25 -0000 1.34
+++ mtdcore.c 14 May 2003 22:26:27 -0000 1.35
@@ -26,7 +26,7 @@
static DECLARE_MUTEX(mtd_table_mutex);
static struct mtd_info *mtd_table[MAX_MTD_DEVICES];
-static struct mtd_notifier *mtd_notifiers = NULL;
+static LIST_HEAD(mtd_notifiers);
/**
* add_mtd_device - register an MTD device
@@ -44,21 +44,28 @@
down(&mtd_table_mutex);
- for (i=0; i< MAX_MTD_DEVICES; i++)
- if (!mtd_table[i])
- {
- struct mtd_notifier *not=mtd_notifiers;
+ for (i=0; i < MAX_MTD_DEVICES; i++)
+ if (!mtd_table[i]) {
+ struct list_head *this;
mtd_table[i] = mtd;
mtd->index = i;
+ mtd->usecount = 0;
+
DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
- while (not)
- {
- (*(not->add))(mtd);
- not = not->next;
+ /* No need to get a refcount on the module containing
+ the notifier, since we hold the mtd_table_mutex */
+ list_for_each(this, &mtd_notifiers) {
+ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
+ not->add(mtd);
}
+
up(&mtd_table_mutex);
- MOD_INC_USE_COUNT;
+ /* We _know_ we aren't being removed, because
+ our caller is still holding us here. So none
+ of this try_ nonsense, and no bitching about it
+ either. :) */
+ __module_get(THIS_MODULE);
return 0;
}
@@ -78,29 +85,34 @@
int del_mtd_device (struct mtd_info *mtd)
{
- struct mtd_notifier *not=mtd_notifiers;
- int i;
+ int ret;
down(&mtd_table_mutex);
- for (i=0; i < MAX_MTD_DEVICES; i++)
- {
- if (mtd_table[i] == mtd)
- {
- while (not)
- {
- (*(not->remove))(mtd);
- not = not->next;
- }
- mtd_table[i] = NULL;
- up (&mtd_table_mutex);
- MOD_DEC_USE_COUNT;
- return 0;
+ if (mtd_table[mtd->index] != mtd) {
+ ret = -ENODEV;
+ } else if (mtd->usecount) {
+ printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
+ mtd->index, mtd->name, mtd->usecount);
+ ret = -EBUSY;
+ } else {
+ struct list_head *this;
+
+ /* No need to get a refcount on the module containing
+ the notifier, since we hold the mtd_table_mutex */
+ list_for_each(this, &mtd_notifiers) {
+ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
+ not->remove(mtd);
}
+
+ mtd_table[mtd->index] = NULL;
+
+ module_put(THIS_MODULE);
+ ret = 0;
}
up(&mtd_table_mutex);
- return 1;
+ return ret;
}
/**
@@ -118,10 +130,9 @@
down(&mtd_table_mutex);
- new->next = mtd_notifiers;
- mtd_notifiers = new;
+ list_add(&mtd_notifiers, &new->list);
- MOD_INC_USE_COUNT;
+ __module_get(THIS_MODULE);
for (i=0; i< MAX_MTD_DEVICES; i++)
if (mtd_table[i])
@@ -142,34 +153,24 @@
int unregister_mtd_user (struct mtd_notifier *old)
{
- struct mtd_notifier **prev = &mtd_notifiers;
- struct mtd_notifier *cur;
int i;
down(&mtd_table_mutex);
- while ((cur = *prev)) {
- if (cur == old) {
- *prev = cur->next;
-
- MOD_DEC_USE_COUNT;
-
- for (i=0; i< MAX_MTD_DEVICES; i++)
- if (mtd_table[i])
- old->remove(mtd_table[i]);
+ module_put(THIS_MODULE);
+
+ for (i=0; i< MAX_MTD_DEVICES; i++)
+ if (mtd_table[i])
+ old->remove(mtd_table[i]);
- up(&mtd_table_mutex);
- return 0;
- }
- prev = &cur->next;
- }
+ list_del(&old->list);
up(&mtd_table_mutex);
- return 1;
+ return 0;
}
/**
- * __get_mtd_device - obtain a validated handle for an MTD device
+ * ___get_mtd_device - obtain a validated handle for an MTD device
* @mtd: last known address of the required MTD device
* @num: internal device number of the required MTD device
*
@@ -181,7 +182,7 @@
* __get_mtd_device() doesn't - you should generally use get_mtd_device().
*/
-struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num)
+struct mtd_info *___get_mtd_device(struct mtd_info *mtd, int num, int count)
{
struct mtd_info *ret = NULL;
int i;
@@ -197,11 +198,28 @@
if (mtd && mtd != ret)
ret = NULL;
}
+ if (count) {
+ if (ret && !try_module_get(ret->owner))
+ ret = NULL;
+ if (ret)
+ ret->usecount++;
+ }
up(&mtd_table_mutex);
return ret;
}
+void put_mtd_device(struct mtd_info *mtd)
+{
+ int c;
+
+ down(&mtd_table_mutex);
+ c = --mtd->usecount;
+ up(&mtd_table_mutex);
+ BUG_ON(c < 0);
+
+ module_put(mtd->owner);
+}
/* default_mtd_writev - default mtd writev method for MTD devices that
* dont implement their own
@@ -265,7 +283,8 @@
EXPORT_SYMBOL(add_mtd_device);
EXPORT_SYMBOL(del_mtd_device);
-EXPORT_SYMBOL(__get_mtd_device);
+EXPORT_SYMBOL(___get_mtd_device);
+EXPORT_SYMBOL(put_mtd_device);
EXPORT_SYMBOL(register_mtd_user);
EXPORT_SYMBOL(unregister_mtd_user);
EXPORT_SYMBOL(default_mtd_writev);
Index: mtdpart.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtdpart.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- mtdpart.c 18 Feb 2003 20:53:53 -0000 1.34
+++ mtdpart.c 14 May 2003 22:26:27 -0000 1.35
@@ -348,7 +348,7 @@
slave->mtd.name = parts[i].name;
slave->mtd.bank_size = master->bank_size;
- slave->mtd.module = master->module;
+ slave->mtd.owner = master->owner;
slave->mtd.read = part_read;
slave->mtd.write = part_write;
- Previous message: mtd/include/linux/mtd compatmac.h,1.48,1.49 mtd.h,1.42,1.43
- Next message: mtd/drivers/mtd/devices blkmtd-25.c,1.2,1.3 blkmtd.c,1.17,1.18
doc2000.c,1.50,1.51 doc2001.c,1.38,1.39 lart.c,1.3,1.4
ms02-nv.c,1.2,1.3 mtdram.c,1.29,1.30 pmc551.c,1.22,1.23slram.c,1.28,1.29
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the linux-mtd-cvs
mailing list