1 --- a/drivers/mtd/devices/block2mtd.c
2 +++ b/drivers/mtd/devices/block2mtd.c
3 @@ -29,6 +29,8 @@ struct block2mtd_dev {
4 struct block_device *blkdev;
6 struct mutex write_mutex;
12 @@ -79,6 +81,12 @@ static int block2mtd_erase(struct mtd_in
13 size_t len = instr->len;
16 + read_lock(&dev->bdev_mutex);
22 instr->state = MTD_ERASING;
23 mutex_lock(&dev->write_mutex);
24 err = _block2mtd_erase(dev, from, len);
25 @@ -90,6 +98,10 @@ static int block2mtd_erase(struct mtd_in
26 instr->state = MTD_ERASE_DONE;
28 mtd_erase_callback(instr);
31 + read_unlock(&dev->bdev_mutex);
36 @@ -101,7 +113,13 @@ static int block2mtd_read(struct mtd_inf
38 int index = from >> PAGE_SHIFT;
39 int offset = from & (PAGE_SIZE-1);
41 + int cpylen, err = 0;
43 + read_lock(&dev->bdev_mutex);
44 + if (!dev->blkdev || (from > mtd->size)) {
50 if ((offset + len) > PAGE_SIZE)
51 @@ -111,8 +129,10 @@ static int block2mtd_read(struct mtd_inf
54 page = page_read(dev->blkdev->bd_inode->i_mapping, index);
61 memcpy(buf, page_address(page) + offset, cpylen);
62 page_cache_release(page);
63 @@ -123,7 +143,10 @@ static int block2mtd_read(struct mtd_inf
70 + read_unlock(&dev->bdev_mutex);
75 @@ -171,13 +194,22 @@ static int block2mtd_write(struct mtd_in
76 size_t *retlen, const u_char *buf)
78 struct block2mtd_dev *dev = mtd->priv;
82 + read_lock(&dev->bdev_mutex);
88 mutex_lock(&dev->write_mutex);
89 err = _block2mtd_write(dev, buf, to, len, retlen);
90 mutex_unlock(&dev->write_mutex);
95 + read_unlock(&dev->bdev_mutex);
99 @@ -186,33 +218,110 @@ static int block2mtd_write(struct mtd_in
100 static void block2mtd_sync(struct mtd_info *mtd)
102 struct block2mtd_dev *dev = mtd->priv;
103 + read_lock(&dev->bdev_mutex);
105 sync_blockdev(dev->blkdev);
106 + read_unlock(&dev->bdev_mutex);
112 +static int _open_bdev(struct block2mtd_dev *dev)
114 + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
115 + struct block_device *bdev;
117 + /* Get a handle on the device */
118 + bdev = blkdev_get_by_path(dev->devname, mode, dev);
120 + if (IS_ERR(bdev)) {
123 + /* We might not have rootfs mounted at this point. Try
124 + to resolve the device name by other means. */
126 + devt = name_to_dev_t(dev->devname);
128 + bdev = blkdev_get_by_dev(devt, mode, dev);
132 + if (IS_ERR(bdev)) {
133 + ERROR("error: cannot open device %s", dev->devname);
136 + dev->blkdev = bdev;
138 + if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
139 + ERROR("attempting to use an MTD device as a block device");
146 +static void _close_bdev(struct block2mtd_dev *dev)
148 + struct block_device *bdev;
153 + bdev = dev->blkdev;
154 + invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
155 + blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
156 + dev->blkdev = NULL;
159 static void block2mtd_free_device(struct block2mtd_dev *dev)
164 kfree(dev->mtd.name);
167 - invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
169 - blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
177 -/* FIXME: ensure that mtd->size % erase_size == 0 */
178 -static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
179 +static int block2mtd_refresh(struct mtd_info *mtd)
181 - const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
182 + struct block2mtd_dev *dev = mtd->priv;
183 struct block_device *bdev;
187 + /* no other mtd function can run at this point */
188 + write_lock(&dev->bdev_mutex);
190 + /* get the device number for the whole disk */
191 + devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
193 + /* close the old block device */
196 + /* open the whole disk, issue a partition rescan, then */
197 + bdev = blkdev_get_by_dev(devt, FMODE_WRITE | FMODE_READ, mtd);
198 + if (!bdev || !bdev->bd_disk)
200 +#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
202 + err = rescan_partitions(bdev->bd_disk, bdev);
205 + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
207 + /* try to open the partition block device again */
209 + write_unlock(&dev->bdev_mutex);
214 +/* FIXME: ensure that mtd->size % erase_size == 0 */
215 +static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
217 struct block2mtd_dev *dev;
218 struct mtd_partition *part;
220 @@ -220,36 +329,17 @@ static struct block2mtd_dev *add_device(
224 - dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
225 + dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
229 - /* Get a handle on the device */
230 - bdev = blkdev_get_by_path(devname, mode, dev);
232 - if (IS_ERR(bdev)) {
233 + strcpy(dev->devname, devname);
235 - /* We might not have rootfs mounted at this point. Try
236 - to resolve the device name by other means. */
238 - dev_t devt = name_to_dev_t(devname);
240 - bdev = blkdev_get_by_dev(devt, mode, dev);
244 - if (IS_ERR(bdev)) {
245 - ERROR("error: cannot open device %s", devname);
248 - dev->blkdev = bdev;
250 - if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
251 - ERROR("attempting to use an MTD device as a block device");
252 + if (_open_bdev(dev))
256 mutex_init(&dev->write_mutex);
257 + rwlock_init(&dev->bdev_mutex);
259 /* Setup the MTD structure */
260 /* make the name contain the block device in */
261 @@ -274,6 +364,7 @@ static struct block2mtd_dev *add_device(
262 dev->mtd._read = block2mtd_read;
264 dev->mtd.owner = THIS_MODULE;
265 + dev->mtd.refresh_device = block2mtd_refresh;
267 part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);