aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-11-13 05:55:16 -0500
committerTejun Heo <tj@kernel.org>2010-11-13 05:55:16 -0500
commit731edacb7567c15f25b1fccac18a203bd432ae5e (patch)
tree0ad6f16b306847e7626cea84c684ea4a044233da
parentf6614b7bb405a9b35dd28baea989a749492c46b2 (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>
-rw-r--r--drivers/mtd/devices/block2mtd.c13
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 */
235static struct block2mtd_dev *add_device(char *devname, int erase_size) 235static 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