1 --- a/drivers/mtd/devices/block2mtd.c
2 +++ b/drivers/mtd/devices/block2mtd.c
3 @@ -30,6 +30,8 @@ struct block2mtd_dev {
4 struct block_device *blkdev;
6 struct mutex write_mutex;
12 @@ -82,6 +84,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 @@ -93,6 +101,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 @@ -104,10 +116,14 @@ 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)) {
49 - if (from > mtd->size)
51 if (from + len > mtd->size)
52 len = mtd->size - from;
54 @@ -122,10 +138,14 @@ static int block2mtd_read(struct mtd_inf
57 page = page_read(dev->blkdev->bd_inode->i_mapping, index);
61 - return PTR_ERR(page);
67 + err = PTR_ERR(page);
71 memcpy(buf, page_address(page) + offset, cpylen);
72 page_cache_release(page);
73 @@ -136,7 +156,10 @@ static int block2mtd_read(struct mtd_inf
80 + read_unlock(&dev->bdev_mutex);
85 @@ -188,12 +211,22 @@ static int block2mtd_write(struct mtd_in
86 size_t *retlen, const u_char *buf)
88 struct block2mtd_dev *dev = mtd->priv;
92 + read_lock(&dev->bdev_mutex);
100 - if (to >= mtd->size)
104 + if (to >= mtd->size) {
109 if (to + len > mtd->size)
110 len = mtd->size - to;
112 @@ -202,6 +235,9 @@ static int block2mtd_write(struct mtd_in
113 mutex_unlock(&dev->write_mutex);
118 + read_unlock(&dev->bdev_mutex);
122 @@ -210,33 +246,110 @@ static int block2mtd_write(struct mtd_in
123 static void block2mtd_sync(struct mtd_info *mtd)
125 struct block2mtd_dev *dev = mtd->priv;
126 + read_lock(&dev->bdev_mutex);
128 sync_blockdev(dev->blkdev);
129 + read_unlock(&dev->bdev_mutex);
135 +static int _open_bdev(struct block2mtd_dev *dev)
137 + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
138 + struct block_device *bdev;
140 + /* Get a handle on the device */
141 + bdev = blkdev_get_by_path(dev->devname, mode, dev);
143 + if (IS_ERR(bdev)) {
146 + /* We might not have rootfs mounted at this point. Try
147 + to resolve the device name by other means. */
149 + devt = name_to_dev_t(dev->devname);
151 + bdev = blkdev_get_by_dev(devt, mode, dev);
155 + if (IS_ERR(bdev)) {
156 + ERROR("error: cannot open device %s", dev->devname);
159 + dev->blkdev = bdev;
161 + if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
162 + ERROR("attempting to use an MTD device as a block device");
169 +static void _close_bdev(struct block2mtd_dev *dev)
171 + struct block_device *bdev;
176 + bdev = dev->blkdev;
177 + invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
178 + blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
179 + dev->blkdev = NULL;
182 static void block2mtd_free_device(struct block2mtd_dev *dev)
187 kfree(dev->mtd.name);
190 - invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
192 - blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
200 -/* FIXME: ensure that mtd->size % erase_size == 0 */
201 -static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
202 +static int block2mtd_refresh(struct mtd_info *mtd)
204 - const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
205 + struct block2mtd_dev *dev = mtd->priv;
206 struct block_device *bdev;
210 + /* no other mtd function can run at this point */
211 + write_lock(&dev->bdev_mutex);
213 + /* get the device number for the whole disk */
214 + devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
216 + /* close the old block device */
219 + /* open the whole disk, issue a partition rescan, then */
220 + bdev = blkdev_get_by_dev(devt, FMODE_WRITE | FMODE_READ, mtd);
221 + if (!bdev || !bdev->bd_disk)
223 +#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
225 + err = rescan_partitions(bdev->bd_disk, bdev);
228 + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
230 + /* try to open the partition block device again */
232 + write_unlock(&dev->bdev_mutex);
237 +/* FIXME: ensure that mtd->size % erase_size == 0 */
238 +static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
240 struct block2mtd_dev *dev;
241 struct mtd_partition *part;
243 @@ -244,36 +357,17 @@ static struct block2mtd_dev *add_device(
247 - dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
248 + dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
252 - /* Get a handle on the device */
253 - bdev = blkdev_get_by_path(devname, mode, dev);
255 - if (IS_ERR(bdev)) {
257 - /* We might not have rootfs mounted at this point. Try
258 - to resolve the device name by other means. */
259 + strcpy(dev->devname, devname);
261 - dev_t devt = name_to_dev_t(devname);
263 - bdev = blkdev_get_by_dev(devt, mode, dev);
267 - if (IS_ERR(bdev)) {
268 - ERROR("error: cannot open device %s", devname);
269 + if (_open_bdev(dev))
272 - dev->blkdev = bdev;
274 - if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
275 - ERROR("attempting to use an MTD device as a block device");
279 mutex_init(&dev->write_mutex);
280 + rwlock_init(&dev->bdev_mutex);
282 /* Setup the MTD structure */
283 /* make the name contain the block device in */
284 @@ -298,6 +392,7 @@ static struct block2mtd_dev *add_device(
285 dev->mtd.read = block2mtd_read;
287 dev->mtd.owner = THIS_MODULE;
288 + dev->mtd.refresh_device = block2mtd_refresh;
290 part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);