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 @@ -80,6 +82,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 @@ -91,6 +99,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 @@ -102,7 +114,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 @@ -112,8 +130,10 @@ static int block2mtd_read(struct mtd_inf
54 page = page_read(dev->blkdev->bd_inode->i_mapping, index);
56 - return PTR_ERR(page);
58 + err = PTR_ERR(page);
62 memcpy(buf, page_address(page) + offset, cpylen);
63 page_cache_release(page);
64 @@ -124,7 +144,10 @@ static int block2mtd_read(struct mtd_inf
71 + read_unlock(&dev->bdev_mutex);
76 @@ -173,13 +196,22 @@ static int block2mtd_write(struct mtd_in
77 size_t *retlen, const u_char *buf)
79 struct block2mtd_dev *dev = mtd->priv;
83 + read_lock(&dev->bdev_mutex);
89 mutex_lock(&dev->write_mutex);
90 err = _block2mtd_write(dev, buf, to, len, retlen);
91 mutex_unlock(&dev->write_mutex);
96 + read_unlock(&dev->bdev_mutex);
100 @@ -188,33 +220,110 @@ static int block2mtd_write(struct mtd_in
101 static void block2mtd_sync(struct mtd_info *mtd)
103 struct block2mtd_dev *dev = mtd->priv;
104 + read_lock(&dev->bdev_mutex);
106 sync_blockdev(dev->blkdev);
107 + read_unlock(&dev->bdev_mutex);
113 +static int _open_bdev(struct block2mtd_dev *dev)
115 + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
116 + struct block_device *bdev;
118 + /* Get a handle on the device */
119 + bdev = blkdev_get_by_path(dev->devname, mode, dev);
121 + if (IS_ERR(bdev)) {
124 + /* We might not have rootfs mounted at this point. Try
125 + to resolve the device name by other means. */
127 + devt = name_to_dev_t(dev->devname);
129 + bdev = blkdev_get_by_dev(devt, mode, dev);
133 + if (IS_ERR(bdev)) {
134 + ERROR("error: cannot open device %s", dev->devname);
137 + dev->blkdev = bdev;
139 + if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
140 + ERROR("attempting to use an MTD device as a block device");
147 +static void _close_bdev(struct block2mtd_dev *dev)
149 + struct block_device *bdev;
154 + bdev = dev->blkdev;
155 + invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
156 + blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
157 + dev->blkdev = NULL;
160 static void block2mtd_free_device(struct block2mtd_dev *dev)
165 kfree(dev->mtd.name);
168 - invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
170 - blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
178 -/* FIXME: ensure that mtd->size % erase_size == 0 */
179 -static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
180 +static int block2mtd_refresh(struct mtd_info *mtd)
182 - const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
183 + struct block2mtd_dev *dev = mtd->priv;
184 struct block_device *bdev;
188 + /* no other mtd function can run at this point */
189 + write_lock(&dev->bdev_mutex);
191 + /* get the device number for the whole disk */
192 + devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
194 + /* close the old block device */
197 + /* open the whole disk, issue a partition rescan, then */
198 + bdev = blkdev_get_by_dev(devt, FMODE_WRITE | FMODE_READ, mtd);
199 + if (!bdev || !bdev->bd_disk)
201 +#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
203 + err = rescan_partitions(bdev->bd_disk, bdev);
206 + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
208 + /* try to open the partition block device again */
210 + write_unlock(&dev->bdev_mutex);
215 +/* FIXME: ensure that mtd->size % erase_size == 0 */
216 +static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
218 struct block2mtd_dev *dev;
219 struct mtd_partition *part;
221 @@ -222,36 +331,17 @@ static struct block2mtd_dev *add_device(
225 - dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
226 + dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
230 - /* Get a handle on the device */
231 - bdev = blkdev_get_by_path(devname, mode, dev);
233 - if (IS_ERR(bdev)) {
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;
249 + strcpy(dev->devname, devname);
251 - if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
252 - ERROR("attempting to use an MTD device as a block device");
253 + if (_open_bdev(dev))
257 mutex_init(&dev->write_mutex);
258 + rwlock_init(&dev->bdev_mutex);
260 /* Setup the MTD structure */
261 /* make the name contain the block device in */
262 @@ -276,6 +366,7 @@ static struct block2mtd_dev *add_device(
263 dev->mtd._read = block2mtd_read;
265 dev->mtd.owner = THIS_MODULE;
266 + dev->mtd.refresh_device = block2mtd_refresh;
268 part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);