]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/mtd/mtd_blkdevs.c
mtd: Remove redundant mutex from mtd_blkdevs.c
[net-next-2.6.git] / drivers / mtd / mtd_blkdevs.c
index 62e68707b07f49a6f07a8f97a7333880f9d7f1db..cb20c67995d8ba52652d8765b80dbceb82eba2b8 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 #include <linux/hdreg.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
@@ -133,6 +132,10 @@ static int mtd_blktrans_thread(void *arg)
 
                if (!req && !(req = blk_fetch_request(rq))) {
                        set_current_state(TASK_INTERRUPTIBLE);
+
+                       if (kthread_should_stop())
+                               set_current_state(TASK_RUNNING);
+
                        spin_unlock_irq(rq->queue_lock);
                        schedule();
                        spin_lock_irq(rq->queue_lock);
@@ -176,54 +179,53 @@ static void mtd_blktrans_request(struct request_queue *rq)
 static int blktrans_open(struct block_device *bdev, fmode_t mode)
 {
        struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
-       int ret;
+       int ret = 0;
 
        if (!dev)
                return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
 
-       lock_kernel();
        mutex_lock(&dev->lock);
 
-       if (!dev->mtd) {
-               ret = -ENXIO;
+       if (dev->open++)
                goto unlock;
-       }
 
-       ret = !dev->open++ && dev->tr->open ? dev->tr->open(dev) : 0;
+       kref_get(&dev->ref);
+       __module_get(dev->tr->owner);
+
+       if (dev->mtd) {
+               ret = dev->tr->open ? dev->tr->open(dev) : 0;
+               __get_mtd_device(dev->mtd);
+       }
 
-       /* Take another reference on the device so it won't go away till
-               last release */
-       if (!ret)
-               kref_get(&dev->ref);
 unlock:
        mutex_unlock(&dev->lock);
        blktrans_dev_put(dev);
-       unlock_kernel();
        return ret;
 }
 
 static int blktrans_release(struct gendisk *disk, fmode_t mode)
 {
        struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
-       int ret = -ENXIO;
+       int ret = 0;
 
        if (!dev)
                return ret;
 
-       lock_kernel();
        mutex_lock(&dev->lock);
 
-       /* Release one reference, we sure its not the last one here*/
-       kref_put(&dev->ref, blktrans_dev_release);
-
-       if (!dev->mtd)
+       if (--dev->open)
                goto unlock;
 
-       ret = !--dev->open && dev->tr->release ? dev->tr->release(dev) : 0;
+       kref_put(&dev->ref, blktrans_dev_release);
+       module_put(dev->tr->owner);
+
+       if (dev->mtd) {
+               ret = dev->tr->release ? dev->tr->release(dev) : 0;
+               __put_mtd_device(dev->mtd);
+       }
 unlock:
        mutex_unlock(&dev->lock);
        blktrans_dev_put(dev);
-       unlock_kernel();
        return ret;
 }
 
@@ -256,7 +258,6 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
        if (!dev)
                return ret;
 
-       lock_kernel();
        mutex_lock(&dev->lock);
 
        if (!dev->mtd)
@@ -271,7 +272,6 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
        }
 unlock:
        mutex_unlock(&dev->lock);
-       unlock_kernel();
        blktrans_dev_put(dev);
        return ret;
 }
@@ -385,9 +385,6 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
        gd->queue = new->rq;
 
-       __get_mtd_device(new->mtd);
-       __module_get(tr->owner);
-
        /* Create processing thread */
        /* TODO: workqueue ? */
        new->thread = kthread_run(mtd_blktrans_thread, new,
@@ -410,8 +407,6 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
        }
        return 0;
 error4:
-       module_put(tr->owner);
-       __put_mtd_device(new->mtd);
        blk_cleanup_queue(new->rq);
 error3:
        put_disk(new->disk);
@@ -448,17 +443,15 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
        blk_start_queue(old->rq);
        spin_unlock_irqrestore(&old->queue_lock, flags);
 
-       /* Ask trans driver for release to the mtd device */
+       /* If the device is currently open, tell trans driver to close it,
+               then put mtd device, and don't touch it again */
        mutex_lock(&old->lock);
-       if (old->open && old->tr->release) {
-               old->tr->release(old);
-               old->open = 0;
+       if (old->open) {
+               if (old->tr->release)
+                       old->tr->release(old);
+               __put_mtd_device(old->mtd);
        }
 
-       __put_mtd_device(old->mtd);
-       module_put(old->tr->owner);
-
-       /* At that point, we don't touch the mtd anymore */
        old->mtd = NULL;
 
        mutex_unlock(&old->lock);
@@ -508,13 +501,16 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        mutex_lock(&mtd_table_mutex);
 
        ret = register_blkdev(tr->major, tr->name);
-       if (ret) {
+       if (ret < 0) {
                printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
                       tr->name, tr->major, ret);
                mutex_unlock(&mtd_table_mutex);
                return ret;
        }
 
+       if (ret)
+               tr->major = ret;
+
        tr->blkshift = ffs(tr->blksize) - 1;
 
        INIT_LIST_HEAD(&tr->devs);