diff options
author | Tejun Heo <tj@kernel.org> | 2010-11-13 05:55:16 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-11-13 05:55:16 -0500 |
commit | 731edacb7567c15f25b1fccac18a203bd432ae5e (patch) | |
tree | 0ad6f16b306847e7626cea84c684ea4a044233da /drivers/mtd/devices | |
parent | f6614b7bb405a9b35dd28baea989a749492c46b2 (diff) |
mtd: fix bdev exclusive open bugs in block2mtd::add_device()
There are two bdev exclusive open bugs.
* open_bdev_exclusive() must not be called with NULL holder. Use dev
as the holder.
* open_by_devnum() doesn't open the bdev exclusively but
block2mtd_free_device() always assumes it. Explicitly claim the
bdev.
The latter is rather clumsy but will be simplified with future
blkdev_get/put() cleanups.
- Updated to use local variable @mode to cache FMODE_* masks as
suggested by Artem Bityutskiy.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: linux-mtd@lists.infradead.org
Cc: Artem Bityutskiy <dedekind1@gmail.com>
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r-- | drivers/mtd/devices/block2mtd.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 2cf0cc6a4189..a9e2d3b38aeb 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -234,6 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) | |||
234 | /* FIXME: ensure that mtd->size % erase_size == 0 */ | 234 | /* FIXME: ensure that mtd->size % erase_size == 0 */ |
235 | static struct block2mtd_dev *add_device(char *devname, int erase_size) | 235 | static struct block2mtd_dev *add_device(char *devname, int erase_size) |
236 | { | 236 | { |
237 | const fmode_t mode = FMODE_READ | FMODE_WRITE; | ||
237 | struct block_device *bdev; | 238 | struct block_device *bdev; |
238 | struct block2mtd_dev *dev; | 239 | struct block2mtd_dev *dev; |
239 | char *name; | 240 | char *name; |
@@ -246,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
246 | return NULL; | 247 | return NULL; |
247 | 248 | ||
248 | /* Get a handle on the device */ | 249 | /* Get a handle on the device */ |
249 | bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL); | 250 | bdev = open_bdev_exclusive(devname, mode, dev); |
250 | #ifndef MODULE | 251 | #ifndef MODULE |
251 | if (IS_ERR(bdev)) { | 252 | if (IS_ERR(bdev)) { |
252 | 253 | ||
@@ -255,7 +256,15 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
255 | 256 | ||
256 | dev_t devt = name_to_dev_t(devname); | 257 | dev_t devt = name_to_dev_t(devname); |
257 | if (devt) { | 258 | if (devt) { |
258 | bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); | 259 | bdev = open_by_devnum(devt, mode); |
260 | if (!IS_ERR(bdev)) { | ||
261 | int ret; | ||
262 | ret = bd_claim(bdev, dev); | ||
263 | if (ret) { | ||
264 | blkdev_put(bdev, mode); | ||
265 | bdev = ERR_PTR(ret); | ||
266 | } | ||
267 | } | ||
259 | } | 268 | } |
260 | } | 269 | } |
261 | #endif | 270 | #endif |