mtd/drivers/mtd mtd_blkdevs.c,1.11,1.12

David Woodhouse dwmw2 at infradead.org
Tue May 20 21:01:02 EDT 2003


Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv20708/drivers/mtd

Modified Files:
	mtd_blkdevs.c 
Log Message:
clean up open, release and ioctl to avoid lookups and locking

Index: mtd_blkdevs.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtd_blkdevs.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- mtd_blkdevs.c	20 May 2003 22:29:08 -0000	1.11
+++ mtd_blkdevs.c	21 May 2003 01:00:59 -0000	1.12
@@ -27,44 +27,14 @@
 extern struct semaphore mtd_table_mutex;
 extern struct mtd_info *mtd_table[];
 
-static struct request_queue mtd_blktrans_queue;
-static spinlock_t mtd_blktrans_queue_lock;
-
 struct mtd_blkcore_priv {
 	struct completion thread_dead;
 	int exiting;
 	wait_queue_head_t thread_wq;
+	struct request_queue rq;
+	spinlock_t queue_lock;
 };
 
-static inline struct mtd_blktrans_dev *tr_get_dev(struct mtd_blktrans_ops *tr,
-					   int devnum)
-{
-	struct list_head *this;
-	struct mtd_blktrans_dev *d;
-
-	list_for_each(this, &tr->devs) {
-		d = list_entry(this, struct mtd_blktrans_dev, list);
-
-		if (d->devnum == devnum)
-			return d;
-	}
-	return NULL;
-}
-
-static inline struct mtd_blktrans_ops *get_tr(int major)
-{
-	struct list_head *this;
-	struct mtd_blktrans_ops *t;
-
-	list_for_each(this, &blktrans_majors) {
-		t = list_entry(this, struct mtd_blktrans_ops, list);
-
-		if (t->major == major)
-			return t;
-	}
-	return NULL;
-}
-
 static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 			       struct mtd_blktrans_dev *dev,
 			       struct request *req)
@@ -107,7 +77,7 @@
 static int mtd_blktrans_thread(void *arg)
 {
 	struct mtd_blktrans_ops *tr = arg;
-	struct request_queue *rq = &mtd_blktrans_queue;
+	struct request_queue *rq = &tr->blkcore_priv->rq;
 
 	/* we might get involved when memory gets low, so use PF_MEMALLOC */
 	current->flags |= PF_MEMALLOC;
@@ -170,61 +140,32 @@
 
 int blktrans_open(struct inode *i, struct file *f)
 {
-	struct mtd_blktrans_ops *tr = NULL;
-	struct mtd_blktrans_dev *dev = NULL;
-	int major_nr = major(i->i_rdev);
-	int minor_nr = minor(i->i_rdev);
-	int devnum;
+	struct mtd_blktrans_dev *dev;
+	struct mtd_blktrans_ops *tr;
 	int ret = -ENODEV;
 
-#if 0 /* Do we still have to do this in 2.5? Hopefully not since I don't
-	 see how */
-	if (is_read_only(i->i_rdev) && (f->f_mode & FMODE_WRITE))
-		return -EROFS;
-#endif
-
-	down(&mtd_table_mutex);
-
-	tr = get_tr(major_nr);
+	dev = i->i_bdev->bd_disk->private_data;
+	tr = dev->tr;
 
-	if (!tr)
-		goto out;
- 
-	devnum = minor_nr >> tr->part_bits;
-
-	dev = tr_get_dev(tr, devnum);
-
-	if (!dev)
-		goto out;
-
-#if 0 /* Does it prevent us from opening a partition which doesn't exist */
-	if (!tr->blkcore_priv->part_table[minor_nr].nr_sects) {
-		ret = -ENODEV;
-		goto out;
-	}
-#endif
 	if (!try_module_get(dev->mtd->owner))
 		goto out;
 
 	if (!try_module_get(tr->owner))
 		goto out_tr;
 
+	/* FIXME: Locking. A hot pluggable device can go away 
+	   (del_mtd_device can be called for it) without its module
+	   being unloaded. */
 	dev->mtd->usecount++;
-	dev->usecount++;
-	tr->usecount++;
 
 	ret = 0;
 	if (tr->open && (ret = tr->open(dev, i, f))) {
-		tr->usecount--;
-		dev->usecount--;
 		dev->mtd->usecount--;
 		module_put(dev->mtd->owner);
 	out_tr:
 		module_put(tr->owner);
 	}
  out:
-	up(&mtd_table_mutex);
-
 	return ret;
 }
 
@@ -233,36 +174,18 @@
 	struct mtd_blktrans_dev *dev;
 	struct mtd_blktrans_ops *tr;
 	int ret = 0;
-	int devnum;
 
-	down(&mtd_table_mutex);
-
-	tr = get_tr(major(i->i_rdev));
-	if (!tr) {
-		up(&mtd_table_mutex);
-		return -ENODEV;
-	}
-
-	devnum = minor(i->i_rdev) >> tr->part_bits;
-	dev = tr_get_dev(tr, devnum);
-
-	if (!dev) {
-		up(&mtd_table_mutex);
-		return -ENODEV;
-	}
+	dev = i->i_bdev->bd_disk->private_data;
+	tr = dev->tr;
 
 	if (tr->release)
 		ret = tr->release(dev, i, f);
 
 	if (!ret) {
-		tr->usecount--;
-		dev->usecount--;
 		dev->mtd->usecount--;
 		module_put(dev->mtd->owner);
 		module_put(tr->owner);
 	}
-	
-	up(&mtd_table_mutex);
 
 	return ret;
 }
@@ -273,24 +196,10 @@
 {
 	struct mtd_blktrans_dev *dev;
 	struct mtd_blktrans_ops *tr;
-	int devnum;
 	int ret = -ENOTTY;
 
-	down(&mtd_table_mutex);
-
-	tr = get_tr(major(inode->i_rdev));
-	if (!tr) {
-		up(&mtd_table_mutex);
-		return -ENODEV;
-	}
-
-	devnum = minor(inode->i_rdev) >> tr->part_bits;
-	dev = tr_get_dev(tr, devnum);
-
-	up(&mtd_table_mutex);
-
-	if (!dev)
-		return -ENODEV;
+	dev = inode->i_bdev->bd_disk->private_data;
+	tr = dev->tr;
 
 	if (tr->ioctl)
 		ret = tr->ioctl(dev, inode, file, cmd, arg);
@@ -351,8 +260,6 @@
 	init_MUTEX(&new->sem);
 	list_add_tail(&new->list, &tr->devs);
  added:
-	new->usecount = 0;
-
 	if (!tr->writesect)
 		new->readonly = 1;
 
@@ -373,7 +280,7 @@
 	set_capacity(gd, new->size);
 	gd->private_data = new;
 	new->blkcore_priv = gd;
-	gd->queue = &mtd_blktrans_queue;
+	gd->queue = &tr->blkcore_priv->rq;
 
 	if (new->readonly)
 		set_disk_ro(gd, 1);
@@ -390,9 +297,6 @@
 		BUG();
 	}
 
-	if (old->usecount)
-		return -EBUSY;
-
 	list_del(&old->list);
 
 	del_gendisk(old->blkcore_priv);
@@ -424,6 +328,8 @@
 	if (mtd->type == MTD_ABSENT)
 		return;
 
+	printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count));
+
 	list_for_each(this, &blktrans_majors) {
 		struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
 
@@ -447,35 +353,47 @@
 	if (!blktrans_notifier.list.next)
 		register_mtd_user(&blktrans_notifier);
 
+	tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
+	if (!tr->blkcore_priv)
+		return -ENOMEM;
+
+	memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
+
 	down(&mtd_table_mutex);
 
 	ret = register_blkdev(tr->major, tr->name);
 	if (ret) {
 		printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
 		       tr->name, tr->major, ret);
+		kfree(tr->blkcore_priv);
 		up(&mtd_table_mutex);
 		return ret;
 	}
-	blk_init_queue(&mtd_blktrans_queue, mtd_blktrans_request, 
-		       &mtd_blktrans_queue_lock);
-
+	spin_lock_init(&tr->blkcore_priv->queue_lock);
 	init_completion(&tr->blkcore_priv->thread_dead);
 	init_waitqueue_head(&tr->blkcore_priv->thread_wq);
 
+	blk_init_queue(&tr->blkcore_priv->rq, mtd_blktrans_request, 
+		       &tr->blkcore_priv->queue_lock);
+	tr->blkcore_priv->rq.queuedata = tr;
+
 	ret = kernel_thread(mtd_blktrans_thread, tr, 
 			    CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
 	if (ret < 0) {
-		blk_cleanup_queue(&mtd_blktrans_queue);
+		blk_cleanup_queue(&tr->blkcore_priv->rq);
 		unregister_blkdev(tr->major, tr->name);
+		kfree(tr->blkcore_priv);
+		up(&mtd_table_mutex);
 		return ret;
-       } 
+	} 
 
 	devfs_mk_dir(tr->name);
 
-	tr->usecount = 0;
 	INIT_LIST_HEAD(&tr->devs);
 	list_add(&tr->list, &blktrans_majors);
 
+	printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count));
+
 	for (i=0; i<MAX_MTD_DEVICES; i++) {
 		if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
 			tr->add_mtd(tr, mtd_table[i]);
@@ -492,12 +410,6 @@
 
 	down(&mtd_table_mutex);
 
-	if (tr->usecount) {
-		up(&mtd_table_mutex);
-		return -EBUSY;
-	}
-
-
 	/* Clean up the kernel thread */
 	tr->blkcore_priv->exiting = 1;
 	wake_up(&tr->blkcore_priv->thread_wq);
@@ -512,11 +424,13 @@
 	}
 
 	devfs_remove(tr->name);
-	blk_cleanup_queue(&mtd_blktrans_queue);
+	blk_cleanup_queue(&tr->blkcore_priv->rq);
 	unregister_blkdev(tr->major, tr->name);
 
 	up(&mtd_table_mutex);
 
+	kfree(tr->blkcore_priv);
+
 	if (!list_empty(&tr->devs))
 		BUG();
 	return 0;
@@ -531,6 +445,11 @@
 }
 
 module_exit(mtd_blktrans_exit);
+
+EXPORT_SYMBOL_GPL(register_mtd_blktrans);
+EXPORT_SYMBOL_GPL(deregister_mtd_blktrans);
+EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev);
+EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev);
 
 MODULE_AUTHOR("David Woodhouse <dwmw2 at infradead.org>");
 MODULE_LICENSE("GPL");




More information about the linux-mtd-cvs mailing list