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