From: Maxim Levitsky <maximlevitsky@gmail.com>
To: Artem Bityutskiy <dedekind1@gmail.com>
Cc: Alex Dubov <oakad@yahoo.com>, joern <joern@logfs.org>,
linux-kernel <linux-kernel@vger.kernel.org>,
linux-mtd <linux-mtd@lists.infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
David Woodhouse <dwmw2@infradead.org>
Subject: [PATCH 5/8] blktrans: add proper locking
Date: Sat, 23 Jan 2010 02:24:22 +0200 [thread overview]
Message-ID: <1264206262.31827.9.camel@maxim-laptop> (raw)
In-Reply-To: <1264205925.31827.3.camel@maxim-laptop>
>From 695c50a575ba7e004931e234f4706766be507289 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Sat, 23 Jan 2010 02:07:53 +0200
Subject: [PATCH 5/8] blktrans: add proper locking
First, use lockless versions of get/put_mtd_device
We don't care what happened to mtd table, because we have a pointer
to mtd device. It guaranteed to exist till we do final put_mtd_device
Also add locking to prevent all kinds or races
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
drivers/mtd/mtd_blkdevs.c | 83 ++++++++++++++++++++++++++++----------------
1 files changed, 53 insertions(+), 30 deletions(-)
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index c95e1ff..f165115 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -123,34 +123,34 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
{
struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
struct mtd_blktrans_ops *tr = dev->tr;
- int ret = -ENODEV;
-
- if (!get_mtd_device(NULL, dev->mtd->index))
- goto out;
+ int ret = 0;
+ mutex_lock(&dev->lock);
if (dev->open++)
goto out;
if (dev->deleted)
goto out;
-
+ ret = -ENODEV;
if (!try_module_get(tr->owner))
- goto out_tr;
+ goto out;
+
+ if (__get_mtd_device(dev->mtd)) {
+ module_put(tr->owner);
+ goto out;
+ }
- /* 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++;
ret = 0;
if (tr->open && (ret = tr->open(dev))) {
- dev->mtd->usecount--;
- put_mtd_device(dev->mtd);
- out_tr:
module_put(tr->owner);
+ __put_mtd_device(dev->mtd);
+ goto out;
+
}
out:
+ mutex_unlock(&dev->lock);
return ret;
}
@@ -160,18 +160,11 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
struct mtd_blktrans_ops *tr = dev->tr;
int ret = 0;
+ mutex_lock(&dev->lock);
dev->open--;
if (dev->open)
return 0;
- if (tr->release)
- ret = tr->release(dev);
-
- if (!ret) {
- dev->mtd->usecount--;
- put_mtd_device(dev->mtd);
- module_put(tr->owner);
- }
/* Free the private data */
if (dev->deleted) {
@@ -181,33 +174,59 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
return 0;
}
+ ret = tr->release ? tr->release(dev) : 0;
+ module_put(tr->owner);
+
+ if (dev->mtd)
+ __put_mtd_device(dev->mtd);
+out:
+ mutex_unlock(&dev->lock);
return ret;
}
static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
+ int error;
+
+ mutex_lock(&dev->lock);
+ error = -ENODEV;
+ if (dev->deleted)
+ goto out;
+
+ error = -ENOTTY;
if (dev->tr->getgeo)
- return dev->tr->getgeo(dev, geo);
- return -ENOTTY;
+ error = dev->tr->getgeo(dev, geo);
+out:
+ mutex_unlock(&dev->lock);
+ return error;
}
static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
- struct mtd_blktrans_ops *tr = dev->tr;
+ int error = -ENODEV;
+
+ mutex_lock(&dev->lock);
+
+ if (dev->deleted)
+ goto out;
+
+ error = -ENOTTY;
switch (cmd) {
case BLKFLSBUF:
- if (tr->flush)
- return tr->flush(dev);
- /* The core code did the work, we had nothing to do. */
- return 0;
+ if (dev->tr->flush)
+ error = dev->tr->flush(dev);
+ break;
default:
- return -ENOTTY;
+ break;
}
+out:
+ mutex_unlock(&dev->lock);
+ return error;
}
static const struct block_device_operations mtd_blktrans_ops = {
@@ -355,15 +374,19 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
/* Stop the thread */
kthread_stop(old->thread);
+ /* Tell trans driver to release the device */
+ mutex_lock(&old->lock);
+
if (old->open) {
if (old->tr->release)
old->tr->release(old);
- put_mtd_device(old->mtd);
+ __put_mtd_device(old->mtd);
}
/* From now on, no calls into trans can be made */
/* Mtd device will be gone real soon now */
old->mtd = NULL;
+ mutex_unlock(&old->lock);
blk_cleanup_queue(old->rq);
--
1.6.3.3
next prev parent reply other threads:[~2010-01-23 0:24 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-23 0:18 [PATCH 0/8] Cleanups for mtd translation layer (broken up) Maxim Levitsky
2010-01-23 0:19 ` [PATCH 1/8] blktrans: nuke mtd_blkcore_priv and make both thread and disk queue be per device Maxim Levitsky
2010-01-23 0:21 ` [PATCH 2/8] blktrans: track open and close calls Maxim Levitsky
2010-01-23 0:23 ` [PATCH 3/8] blktrans: don't free mtd_blktrans_dev, core will do that for you Maxim Levitsky
2010-01-23 0:23 ` [PATCH 4/8] MTD: create lockless versions of {get,put}_mtd_device Maxim Levitsky
2010-01-23 0:24 ` Maxim Levitsky [this message]
2010-01-23 0:24 ` [PATCH 6/8] blktrans: flush all requests before we remove the device Maxim Levitsky
2010-01-23 0:25 ` [PATCH 7/8] MTD: call remove notifiers before removing " Maxim Levitsky
2010-01-23 0:26 ` [PATCH 8/8] MTD: make mtdtrans thread freezeable Maxim Levitsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1264206262.31827.9.camel@maxim-laptop \
--to=maximlevitsky@gmail.com \
--cc=dedekind1@gmail.com \
--cc=dwmw2@infradead.org \
--cc=joern@logfs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=oakad@yahoo.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox