441-block2mtd_refresh.patch 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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;
  5. struct mtd_info mtd;
  6. struct mutex write_mutex;
  7. + rwlock_t bdev_mutex;
  8. + char devname[0];
  9. };
  10. @@ -80,6 +82,12 @@ static int block2mtd_erase(struct mtd_in
  11. size_t len = instr->len;
  12. int err;
  13. + read_lock(&dev->bdev_mutex);
  14. + if (!dev->blkdev) {
  15. + err = -EINVAL;
  16. + goto done;
  17. + }
  18. +
  19. instr->state = MTD_ERASING;
  20. mutex_lock(&dev->write_mutex);
  21. err = _block2mtd_erase(dev, from, len);
  22. @@ -91,6 +99,10 @@ static int block2mtd_erase(struct mtd_in
  23. instr->state = MTD_ERASE_DONE;
  24. mtd_erase_callback(instr);
  25. +
  26. +done:
  27. + read_unlock(&dev->bdev_mutex);
  28. +
  29. return err;
  30. }
  31. @@ -102,7 +114,13 @@ static int block2mtd_read(struct mtd_inf
  32. struct page *page;
  33. int index = from >> PAGE_SHIFT;
  34. int offset = from & (PAGE_SIZE-1);
  35. - int cpylen;
  36. + int cpylen, err = 0;
  37. +
  38. + read_lock(&dev->bdev_mutex);
  39. + if (!dev->blkdev || (from > mtd->size)) {
  40. + err = -EINVAL;
  41. + goto done;
  42. + }
  43. while (len) {
  44. if ((offset + len) > PAGE_SIZE)
  45. @@ -112,8 +130,10 @@ static int block2mtd_read(struct mtd_inf
  46. len = len - cpylen;
  47. page = page_read(dev->blkdev->bd_inode->i_mapping, index);
  48. - if (IS_ERR(page))
  49. - return PTR_ERR(page);
  50. + if (IS_ERR(page)) {
  51. + err = PTR_ERR(page);
  52. + goto done;
  53. + }
  54. memcpy(buf, page_address(page) + offset, cpylen);
  55. page_cache_release(page);
  56. @@ -124,7 +144,10 @@ static int block2mtd_read(struct mtd_inf
  57. offset = 0;
  58. index++;
  59. }
  60. - return 0;
  61. +
  62. +done:
  63. + read_unlock(&dev->bdev_mutex);
  64. + return err;
  65. }
  66. @@ -173,13 +196,22 @@ static int block2mtd_write(struct mtd_in
  67. size_t *retlen, const u_char *buf)
  68. {
  69. struct block2mtd_dev *dev = mtd->priv;
  70. - int err;
  71. + int err = 0;
  72. +
  73. + read_lock(&dev->bdev_mutex);
  74. + if (!dev->blkdev) {
  75. + err = -EINVAL;
  76. + goto done;
  77. + }
  78. mutex_lock(&dev->write_mutex);
  79. err = _block2mtd_write(dev, buf, to, len, retlen);
  80. mutex_unlock(&dev->write_mutex);
  81. if (err > 0)
  82. err = 0;
  83. +
  84. +done:
  85. + read_unlock(&dev->bdev_mutex);
  86. return err;
  87. }
  88. @@ -188,33 +220,110 @@ static int block2mtd_write(struct mtd_in
  89. static void block2mtd_sync(struct mtd_info *mtd)
  90. {
  91. struct block2mtd_dev *dev = mtd->priv;
  92. + read_lock(&dev->bdev_mutex);
  93. + if (dev->blkdev)
  94. sync_blockdev(dev->blkdev);
  95. + read_unlock(&dev->bdev_mutex);
  96. +
  97. return;
  98. }
  99. +static int _open_bdev(struct block2mtd_dev *dev)
  100. +{
  101. + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
  102. + struct block_device *bdev;
  103. +
  104. + /* Get a handle on the device */
  105. + bdev = blkdev_get_by_path(dev->devname, mode, dev);
  106. +#ifndef MODULE
  107. + if (IS_ERR(bdev)) {
  108. + dev_t devt;
  109. +
  110. + /* We might not have rootfs mounted at this point. Try
  111. + to resolve the device name by other means. */
  112. +
  113. + devt = name_to_dev_t(dev->devname);
  114. + if (devt)
  115. + bdev = blkdev_get_by_dev(devt, mode, dev);
  116. + }
  117. +#endif
  118. +
  119. + if (IS_ERR(bdev)) {
  120. + ERROR("error: cannot open device %s", dev->devname);
  121. + return 1;
  122. + }
  123. + dev->blkdev = bdev;
  124. +
  125. + if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
  126. + ERROR("attempting to use an MTD device as a block device");
  127. + return 1;
  128. + }
  129. +
  130. + return 0;
  131. +}
  132. +
  133. +static void _close_bdev(struct block2mtd_dev *dev)
  134. +{
  135. + struct block_device *bdev;
  136. +
  137. + if (!dev->blkdev)
  138. + return;
  139. +
  140. + bdev = dev->blkdev;
  141. + invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
  142. + blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
  143. + dev->blkdev = NULL;
  144. +}
  145. +
  146. static void block2mtd_free_device(struct block2mtd_dev *dev)
  147. {
  148. if (!dev)
  149. return;
  150. kfree(dev->mtd.name);
  151. -
  152. - if (dev->blkdev) {
  153. - invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
  154. - 0, -1);
  155. - blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
  156. - }
  157. -
  158. + _close_bdev(dev);
  159. kfree(dev);
  160. }
  161. -/* FIXME: ensure that mtd->size % erase_size == 0 */
  162. -static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
  163. +static int block2mtd_refresh(struct mtd_info *mtd)
  164. {
  165. - const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
  166. + struct block2mtd_dev *dev = mtd->priv;
  167. struct block_device *bdev;
  168. + dev_t devt;
  169. + int err = 0;
  170. +
  171. + /* no other mtd function can run at this point */
  172. + write_lock(&dev->bdev_mutex);
  173. +
  174. + /* get the device number for the whole disk */
  175. + devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
  176. +
  177. + /* close the old block device */
  178. + _close_bdev(dev);
  179. +
  180. + /* open the whole disk, issue a partition rescan, then */
  181. + bdev = blkdev_get_by_dev(devt, FMODE_WRITE | FMODE_READ, mtd);
  182. + if (!bdev || !bdev->bd_disk)
  183. + err = -EINVAL;
  184. +#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
  185. + else
  186. + err = rescan_partitions(bdev->bd_disk, bdev);
  187. +#endif
  188. + if (bdev)
  189. + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
  190. +
  191. + /* try to open the partition block device again */
  192. + _open_bdev(dev);
  193. + write_unlock(&dev->bdev_mutex);
  194. +
  195. + return err;
  196. +}
  197. +
  198. +/* FIXME: ensure that mtd->size % erase_size == 0 */
  199. +static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
  200. +{
  201. struct block2mtd_dev *dev;
  202. struct mtd_partition *part;
  203. char *name;
  204. @@ -222,36 +331,17 @@ static struct block2mtd_dev *add_device(
  205. if (!devname)
  206. return NULL;
  207. - dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
  208. + dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
  209. if (!dev)
  210. return NULL;
  211. - /* Get a handle on the device */
  212. - bdev = blkdev_get_by_path(devname, mode, dev);
  213. -#ifndef MODULE
  214. - if (IS_ERR(bdev)) {
  215. -
  216. - /* We might not have rootfs mounted at this point. Try
  217. - to resolve the device name by other means. */
  218. -
  219. - dev_t devt = name_to_dev_t(devname);
  220. - if (devt)
  221. - bdev = blkdev_get_by_dev(devt, mode, dev);
  222. - }
  223. -#endif
  224. -
  225. - if (IS_ERR(bdev)) {
  226. - ERROR("error: cannot open device %s", devname);
  227. - goto devinit_err;
  228. - }
  229. - dev->blkdev = bdev;
  230. + strcpy(dev->devname, devname);
  231. - if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
  232. - ERROR("attempting to use an MTD device as a block device");
  233. + if (_open_bdev(dev))
  234. goto devinit_err;
  235. - }
  236. mutex_init(&dev->write_mutex);
  237. + rwlock_init(&dev->bdev_mutex);
  238. /* Setup the MTD structure */
  239. /* make the name contain the block device in */
  240. @@ -276,6 +366,7 @@ static struct block2mtd_dev *add_device(
  241. dev->mtd._read = block2mtd_read;
  242. dev->mtd.priv = dev;
  243. dev->mtd.owner = THIS_MODULE;
  244. + dev->mtd.refresh_device = block2mtd_refresh;
  245. part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
  246. part->name = name;