aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 16:45:22 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 16:45:22 -0500
commit7b3480f8b701170c046e1ed362946f5f0d005e13 (patch)
treebd25e05b4f35699689b485480dddf24f840f80af /fs
parent1c8106528aa6bf16b3f457de80df1cf7462a49a4 (diff)
parentb60ef99c1164a8ad346cf41f9e71acfffb6d25a6 (diff)
Merge tag 'for-linus-3.3' of git://git.infradead.org/mtd-2.6
MTD pull for 3.3 * tag 'for-linus-3.3' of git://git.infradead.org/mtd-2.6: (113 commits) mtd: Fix dependency for MTD_DOC200x mtd: do not use mtd->block_markbad directly logfs: do not use 'mtd->block_isbad' directly mtd: introduce mtd_can_have_bb helper mtd: do not use mtd->suspend and mtd->resume directly mtd: do not use mtd->lock, unlock and is_locked directly mtd: do not use mtd->sync directly mtd: harmonize mtd_writev usage mtd: do not use mtd->lock_user_prot_reg directly mtd: mtd->write_user_prot_reg directly mtd: do not use mtd->read_*_prot_reg directly mtd: do not use mtd->get_*_prot_info directly mtd: do not use mtd->read_oob directly mtd: mtdoops: do not use mtd->panic_write directly romfs: do not use mtd->get_unmapped_area directly mtd: do not use mtd->get_unmapped_area directly mtd: do use mtd->point directly mtd: introduce mtd_has_oob helper mtd: mtdcore: export symbols cleanup mtd: clean-up the default_mtd_writev function ... Fix up trivial edit/remove conflict in drivers/staging/spectra/lld_mtd.c
Diffstat (limited to 'fs')
-rw-r--r--fs/jffs2/erase.c17
-rw-r--r--fs/jffs2/fs.c1
-rw-r--r--fs/jffs2/readinode.c22
-rw-r--r--fs/jffs2/scan.c12
-rw-r--r--fs/jffs2/super.c4
-rw-r--r--fs/jffs2/wbuf.c38
-rw-r--r--fs/jffs2/writev.c32
-rw-r--r--fs/logfs/dev_mtd.c78
-rw-r--r--fs/romfs/mmap-nommu.c28
9 files changed, 98 insertions, 134 deletions
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index e513f1913c15..a01cdad6aad1 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -74,7 +74,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
74 ((struct erase_priv_struct *)instr->priv)->jeb = jeb; 74 ((struct erase_priv_struct *)instr->priv)->jeb = jeb;
75 ((struct erase_priv_struct *)instr->priv)->c = c; 75 ((struct erase_priv_struct *)instr->priv)->c = c;
76 76
77 ret = c->mtd->erase(c->mtd, instr); 77 ret = mtd_erase(c->mtd, instr);
78 if (!ret) 78 if (!ret)
79 return; 79 return;
80 80
@@ -336,12 +336,11 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
336 uint32_t ofs; 336 uint32_t ofs;
337 size_t retlen; 337 size_t retlen;
338 int ret = -EIO; 338 int ret = -EIO;
339 unsigned long *wordebuf;
339 340
340 if (c->mtd->point) { 341 ret = mtd_point(c->mtd, jeb->offset, c->sector_size, &retlen,
341 unsigned long *wordebuf; 342 &ebuf, NULL);
342 343 if (ret != -EOPNOTSUPP) {
343 ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size,
344 &retlen, &ebuf, NULL);
345 if (ret) { 344 if (ret) {
346 D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); 345 D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
347 goto do_flash_read; 346 goto do_flash_read;
@@ -349,7 +348,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
349 if (retlen < c->sector_size) { 348 if (retlen < c->sector_size) {
350 /* Don't muck about if it won't let us point to the whole erase sector */ 349 /* Don't muck about if it won't let us point to the whole erase sector */
351 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); 350 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
352 c->mtd->unpoint(c->mtd, jeb->offset, retlen); 351 mtd_unpoint(c->mtd, jeb->offset, retlen);
353 goto do_flash_read; 352 goto do_flash_read;
354 } 353 }
355 wordebuf = ebuf-sizeof(*wordebuf); 354 wordebuf = ebuf-sizeof(*wordebuf);
@@ -358,7 +357,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
358 if (*++wordebuf != ~0) 357 if (*++wordebuf != ~0)
359 break; 358 break;
360 } while(--retlen); 359 } while(--retlen);
361 c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size); 360 mtd_unpoint(c->mtd, jeb->offset, c->sector_size);
362 if (retlen) { 361 if (retlen) {
363 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n", 362 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
364 *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf)); 363 *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));
@@ -381,7 +380,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
381 380
382 *bad_offset = ofs; 381 *bad_offset = ofs;
383 382
384 ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf); 383 ret = mtd_read(c->mtd, ofs, readlen, &retlen, ebuf);
385 if (ret) { 384 if (ret) {
386 printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); 385 printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
387 ret = -EIO; 386 ret = -EIO;
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 4b8afe39a87f..2e0123867cb1 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -466,7 +466,6 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r
466 466
467 if (insert_inode_locked(inode) < 0) { 467 if (insert_inode_locked(inode) < 0) {
468 make_bad_inode(inode); 468 make_bad_inode(inode);
469 unlock_new_inode(inode);
470 iput(inode); 469 iput(inode);
471 return ERR_PTR(-EINVAL); 470 return ERR_PTR(-EINVAL);
472 } 471 }
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index ee57bac1ba6d..3093ac4fb24c 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -62,17 +62,15 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
62#ifndef __ECOS 62#ifndef __ECOS
63 /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), 63 /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
64 * adding and jffs2_flash_read_end() interface. */ 64 * adding and jffs2_flash_read_end() interface. */
65 if (c->mtd->point) { 65 err = mtd_point(c->mtd, ofs, len, &retlen, (void **)&buffer, NULL);
66 err = c->mtd->point(c->mtd, ofs, len, &retlen, 66 if (!err && retlen < len) {
67 (void **)&buffer, NULL); 67 JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
68 if (!err && retlen < len) { 68 mtd_unpoint(c->mtd, ofs, retlen);
69 JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); 69 } else if (err) {
70 c->mtd->unpoint(c->mtd, ofs, retlen); 70 if (err != -EOPNOTSUPP)
71 } else if (err)
72 JFFS2_WARNING("MTD point failed: error code %d.\n", err); 71 JFFS2_WARNING("MTD point failed: error code %d.\n", err);
73 else 72 } else
74 pointed = 1; /* succefully pointed to device */ 73 pointed = 1; /* succefully pointed to device */
75 }
76#endif 74#endif
77 75
78 if (!pointed) { 76 if (!pointed) {
@@ -101,7 +99,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
101 kfree(buffer); 99 kfree(buffer);
102#ifndef __ECOS 100#ifndef __ECOS
103 else 101 else
104 c->mtd->unpoint(c->mtd, ofs, len); 102 mtd_unpoint(c->mtd, ofs, len);
105#endif 103#endif
106 104
107 if (crc != tn->data_crc) { 105 if (crc != tn->data_crc) {
@@ -137,7 +135,7 @@ free_out:
137 kfree(buffer); 135 kfree(buffer);
138#ifndef __ECOS 136#ifndef __ECOS
139 else 137 else
140 c->mtd->unpoint(c->mtd, ofs, len); 138 mtd_unpoint(c->mtd, ofs, len);
141#endif 139#endif
142 return err; 140 return err;
143} 141}
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 28107ca136e4..f99464833bb2 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -97,15 +97,15 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
97 size_t pointlen, try_size; 97 size_t pointlen, try_size;
98 98
99 if (c->mtd->point) { 99 if (c->mtd->point) {
100 ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen, 100 ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen,
101 (void **)&flashbuf, NULL); 101 (void **)&flashbuf, NULL);
102 if (!ret && pointlen < c->mtd->size) { 102 if (!ret && pointlen < c->mtd->size) {
103 /* Don't muck about if it won't let us point to the whole flash */ 103 /* Don't muck about if it won't let us point to the whole flash */
104 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); 104 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
105 c->mtd->unpoint(c->mtd, 0, pointlen); 105 mtd_unpoint(c->mtd, 0, pointlen);
106 flashbuf = NULL; 106 flashbuf = NULL;
107 } 107 }
108 if (ret) 108 if (ret && ret != -EOPNOTSUPP)
109 D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); 109 D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
110 } 110 }
111#endif 111#endif
@@ -273,7 +273,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
273 kfree(flashbuf); 273 kfree(flashbuf);
274#ifndef __ECOS 274#ifndef __ECOS
275 else 275 else
276 c->mtd->unpoint(c->mtd, 0, c->mtd->size); 276 mtd_unpoint(c->mtd, 0, c->mtd->size);
277#endif 277#endif
278 kfree(s); 278 kfree(s);
279 return ret; 279 return ret;
@@ -455,7 +455,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
455 if (jffs2_cleanmarker_oob(c)) { 455 if (jffs2_cleanmarker_oob(c)) {
456 int ret; 456 int ret;
457 457
458 if (c->mtd->block_isbad(c->mtd, jeb->offset)) 458 if (mtd_block_isbad(c->mtd, jeb->offset))
459 return BLK_STATE_BADBLOCK; 459 return BLK_STATE_BADBLOCK;
460 460
461 ret = jffs2_check_nand_cleanmarker(c, jeb); 461 ret = jffs2_check_nand_cleanmarker(c, jeb);
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 8be4925296cf..f2d96b5e64f6 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -335,9 +335,7 @@ static void jffs2_put_super (struct super_block *sb)
335 jffs2_flash_cleanup(c); 335 jffs2_flash_cleanup(c);
336 kfree(c->inocache_list); 336 kfree(c->inocache_list);
337 jffs2_clear_xattr_subsystem(c); 337 jffs2_clear_xattr_subsystem(c);
338 if (c->mtd->sync) 338 mtd_sync(c->mtd);
339 c->mtd->sync(c->mtd);
340
341 D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); 339 D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
342} 340}
343 341
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index b09e51d2f81f..30e8f47e8a23 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -228,7 +228,7 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
228 size_t retlen; 228 size_t retlen;
229 char *eccstr; 229 char *eccstr;
230 230
231 ret = c->mtd->read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify); 231 ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
232 if (ret && ret != -EUCLEAN && ret != -EBADMSG) { 232 if (ret && ret != -EUCLEAN && ret != -EBADMSG) {
233 printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x failed: %d\n", c->wbuf_ofs, ret); 233 printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x failed: %d\n", c->wbuf_ofs, ret);
234 return ret; 234 return ret;
@@ -337,7 +337,8 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
337 } 337 }
338 338
339 /* Do the read... */ 339 /* Do the read... */
340 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf); 340 ret = mtd_read(c->mtd, start, c->wbuf_ofs - start, &retlen,
341 buf);
341 342
342 /* ECC recovered ? */ 343 /* ECC recovered ? */
343 if ((ret == -EUCLEAN || ret == -EBADMSG) && 344 if ((ret == -EUCLEAN || ret == -EBADMSG) &&
@@ -413,13 +414,12 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
413 if (breakme++ == 20) { 414 if (breakme++ == 20) {
414 printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs); 415 printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs);
415 breakme = 0; 416 breakme = 0;
416 c->mtd->write(c->mtd, ofs, towrite, &retlen, 417 mtd_write(c->mtd, ofs, towrite, &retlen, brokenbuf);
417 brokenbuf);
418 ret = -EIO; 418 ret = -EIO;
419 } else 419 } else
420#endif 420#endif
421 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, 421 ret = mtd_write(c->mtd, ofs, towrite, &retlen,
422 rewrite_buf); 422 rewrite_buf);
423 423
424 if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) { 424 if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) {
425 /* Argh. We tried. Really we did. */ 425 /* Argh. We tried. Really we did. */
@@ -619,13 +619,14 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
619 if (breakme++ == 20) { 619 if (breakme++ == 20) {
620 printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs); 620 printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs);
621 breakme = 0; 621 breakme = 0;
622 c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, 622 mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen,
623 brokenbuf); 623 brokenbuf);
624 ret = -EIO; 624 ret = -EIO;
625 } else 625 } else
626#endif 626#endif
627 627
628 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf); 628 ret = mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
629 &retlen, c->wbuf);
629 630
630 if (ret) { 631 if (ret) {
631 printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n", ret); 632 printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n", ret);
@@ -861,8 +862,8 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs,
861 v += wbuf_retlen; 862 v += wbuf_retlen;
862 863
863 if (vlen >= c->wbuf_pagesize) { 864 if (vlen >= c->wbuf_pagesize) {
864 ret = c->mtd->write(c->mtd, outvec_to, PAGE_DIV(vlen), 865 ret = mtd_write(c->mtd, outvec_to, PAGE_DIV(vlen),
865 &wbuf_retlen, v); 866 &wbuf_retlen, v);
866 if (ret < 0 || wbuf_retlen != PAGE_DIV(vlen)) 867 if (ret < 0 || wbuf_retlen != PAGE_DIV(vlen))
867 goto outfile; 868 goto outfile;
868 869
@@ -948,11 +949,11 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
948 int ret; 949 int ret;
949 950
950 if (!jffs2_is_writebuffered(c)) 951 if (!jffs2_is_writebuffered(c))
951 return c->mtd->read(c->mtd, ofs, len, retlen, buf); 952 return mtd_read(c->mtd, ofs, len, retlen, buf);
952 953
953 /* Read flash */ 954 /* Read flash */
954 down_read(&c->wbuf_sem); 955 down_read(&c->wbuf_sem);
955 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf); 956 ret = mtd_read(c->mtd, ofs, len, retlen, buf);
956 957
957 if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) { 958 if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) {
958 if (ret == -EBADMSG) 959 if (ret == -EBADMSG)
@@ -1031,7 +1032,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
1031 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; 1032 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1032 ops.datbuf = NULL; 1033 ops.datbuf = NULL;
1033 1034
1034 ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops); 1035 ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
1035 if (ret || ops.oobretlen != ops.ooblen) { 1036 if (ret || ops.oobretlen != ops.ooblen) {
1036 printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd" 1037 printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
1037 " bytes, read %zd bytes, error %d\n", 1038 " bytes, read %zd bytes, error %d\n",
@@ -1074,7 +1075,7 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
1074 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; 1075 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1075 ops.datbuf = NULL; 1076 ops.datbuf = NULL;
1076 1077
1077 ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops); 1078 ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
1078 if (ret || ops.oobretlen != ops.ooblen) { 1079 if (ret || ops.oobretlen != ops.ooblen) {
1079 printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd" 1080 printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
1080 " bytes, read %zd bytes, error %d\n", 1081 " bytes, read %zd bytes, error %d\n",
@@ -1100,7 +1101,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1100 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; 1101 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1101 ops.datbuf = NULL; 1102 ops.datbuf = NULL;
1102 1103
1103 ret = c->mtd->write_oob(c->mtd, jeb->offset, &ops); 1104 ret = mtd_write_oob(c->mtd, jeb->offset, &ops);
1104 if (ret || ops.oobretlen != ops.ooblen) { 1105 if (ret || ops.oobretlen != ops.ooblen) {
1105 printk(KERN_ERR "cannot write OOB for EB at %08x, requested %zd" 1106 printk(KERN_ERR "cannot write OOB for EB at %08x, requested %zd"
1106 " bytes, read %zd bytes, error %d\n", 1107 " bytes, read %zd bytes, error %d\n",
@@ -1129,11 +1130,8 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
1129 if( ++jeb->bad_count < MAX_ERASE_FAILURES) 1130 if( ++jeb->bad_count < MAX_ERASE_FAILURES)
1130 return 0; 1131 return 0;
1131 1132
1132 if (!c->mtd->block_markbad)
1133 return 1; // What else can we do?
1134
1135 printk(KERN_WARNING "JFFS2: marking eraseblock at %08x\n as bad", bad_offset); 1133 printk(KERN_WARNING "JFFS2: marking eraseblock at %08x\n as bad", bad_offset);
1136 ret = c->mtd->block_markbad(c->mtd, bad_offset); 1134 ret = mtd_block_markbad(c->mtd, bad_offset);
1137 1135
1138 if (ret) { 1136 if (ret) {
1139 D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); 1137 D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
diff --git a/fs/jffs2/writev.c b/fs/jffs2/writev.c
index b9276b11bac6..a1bda9dab3f8 100644
--- a/fs/jffs2/writev.c
+++ b/fs/jffs2/writev.c
@@ -13,30 +13,6 @@
13#include <linux/mtd/mtd.h> 13#include <linux/mtd/mtd.h>
14#include "nodelist.h" 14#include "nodelist.h"
15 15
16/* This ought to be in core MTD code. All registered MTD devices
17 without writev should have this put in place. Bug the MTD
18 maintainer */
19static inline int mtd_fake_writev(struct mtd_info *mtd, const struct kvec *vecs,
20 unsigned long count, loff_t to, size_t *retlen)
21{
22 unsigned long i;
23 size_t totlen = 0, thislen;
24 int ret = 0;
25
26 for (i=0; i<count; i++) {
27 if (!vecs[i].iov_len)
28 continue;
29 ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
30 totlen += thislen;
31 if (ret || thislen != vecs[i].iov_len)
32 break;
33 to += vecs[i].iov_len;
34 }
35 if (retlen)
36 *retlen = totlen;
37 return ret;
38}
39
40int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs, 16int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
41 unsigned long count, loff_t to, size_t *retlen) 17 unsigned long count, loff_t to, size_t *retlen)
42{ 18{
@@ -50,18 +26,14 @@ int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
50 } 26 }
51 } 27 }
52 28
53 if (c->mtd->writev) 29 return mtd_writev(c->mtd, vecs, count, to, retlen);
54 return c->mtd->writev(c->mtd, vecs, count, to, retlen);
55 else {
56 return mtd_fake_writev(c->mtd, vecs, count, to, retlen);
57 }
58} 30}
59 31
60int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, 32int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
61 size_t *retlen, const u_char *buf) 33 size_t *retlen, const u_char *buf)
62{ 34{
63 int ret; 35 int ret;
64 ret = c->mtd->write(c->mtd, ofs, len, retlen, buf); 36 ret = mtd_write(c->mtd, ofs, len, retlen, buf);
65 37
66 if (jffs2_sum_active()) { 38 if (jffs2_sum_active()) {
67 struct kvec vecs[1]; 39 struct kvec vecs[1];
diff --git a/fs/logfs/dev_mtd.c b/fs/logfs/dev_mtd.c
index 339e17e9133d..e97404d611e0 100644
--- a/fs/logfs/dev_mtd.c
+++ b/fs/logfs/dev_mtd.c
@@ -13,13 +13,14 @@
13 13
14#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) 14#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
15 15
16static int mtd_read(struct super_block *sb, loff_t ofs, size_t len, void *buf) 16static int logfs_mtd_read(struct super_block *sb, loff_t ofs, size_t len,
17 void *buf)
17{ 18{
18 struct mtd_info *mtd = logfs_super(sb)->s_mtd; 19 struct mtd_info *mtd = logfs_super(sb)->s_mtd;
19 size_t retlen; 20 size_t retlen;
20 int ret; 21 int ret;
21 22
22 ret = mtd->read(mtd, ofs, len, &retlen, buf); 23 ret = mtd_read(mtd, ofs, len, &retlen, buf);
23 BUG_ON(ret == -EINVAL); 24 BUG_ON(ret == -EINVAL);
24 if (ret) 25 if (ret)
25 return ret; 26 return ret;
@@ -31,7 +32,8 @@ static int mtd_read(struct super_block *sb, loff_t ofs, size_t len, void *buf)
31 return 0; 32 return 0;
32} 33}
33 34
34static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf) 35static int loffs_mtd_write(struct super_block *sb, loff_t ofs, size_t len,
36 void *buf)
35{ 37{
36 struct logfs_super *super = logfs_super(sb); 38 struct logfs_super *super = logfs_super(sb);
37 struct mtd_info *mtd = super->s_mtd; 39 struct mtd_info *mtd = super->s_mtd;
@@ -47,7 +49,7 @@ static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf)
47 BUG_ON(len > PAGE_CACHE_SIZE); 49 BUG_ON(len > PAGE_CACHE_SIZE);
48 page_start = ofs & PAGE_CACHE_MASK; 50 page_start = ofs & PAGE_CACHE_MASK;
49 page_end = PAGE_CACHE_ALIGN(ofs + len) - 1; 51 page_end = PAGE_CACHE_ALIGN(ofs + len) - 1;
50 ret = mtd->write(mtd, ofs, len, &retlen, buf); 52 ret = mtd_write(mtd, ofs, len, &retlen, buf);
51 if (ret || (retlen != len)) 53 if (ret || (retlen != len))
52 return -EIO; 54 return -EIO;
53 55
@@ -60,14 +62,15 @@ static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf)
60 * asynchronous properties. So just to prevent the first implementor of such 62 * asynchronous properties. So just to prevent the first implementor of such
61 * a thing from breaking logfs in 2350, we do the usual pointless dance to 63 * a thing from breaking logfs in 2350, we do the usual pointless dance to
62 * declare a completion variable and wait for completion before returning 64 * declare a completion variable and wait for completion before returning
63 * from mtd_erase(). What an exercise in futility! 65 * from logfs_mtd_erase(). What an exercise in futility!
64 */ 66 */
65static void logfs_erase_callback(struct erase_info *ei) 67static void logfs_erase_callback(struct erase_info *ei)
66{ 68{
67 complete((struct completion *)ei->priv); 69 complete((struct completion *)ei->priv);
68} 70}
69 71
70static int mtd_erase_mapping(struct super_block *sb, loff_t ofs, size_t len) 72static int logfs_mtd_erase_mapping(struct super_block *sb, loff_t ofs,
73 size_t len)
71{ 74{
72 struct logfs_super *super = logfs_super(sb); 75 struct logfs_super *super = logfs_super(sb);
73 struct address_space *mapping = super->s_mapping_inode->i_mapping; 76 struct address_space *mapping = super->s_mapping_inode->i_mapping;
@@ -84,7 +87,7 @@ static int mtd_erase_mapping(struct super_block *sb, loff_t ofs, size_t len)
84 return 0; 87 return 0;
85} 88}
86 89
87static int mtd_erase(struct super_block *sb, loff_t ofs, size_t len, 90static int logfs_mtd_erase(struct super_block *sb, loff_t ofs, size_t len,
88 int ensure_write) 91 int ensure_write)
89{ 92{
90 struct mtd_info *mtd = logfs_super(sb)->s_mtd; 93 struct mtd_info *mtd = logfs_super(sb)->s_mtd;
@@ -102,30 +105,29 @@ static int mtd_erase(struct super_block *sb, loff_t ofs, size_t len,
102 ei.len = len; 105 ei.len = len;
103 ei.callback = logfs_erase_callback; 106 ei.callback = logfs_erase_callback;
104 ei.priv = (long)&complete; 107 ei.priv = (long)&complete;
105 ret = mtd->erase(mtd, &ei); 108 ret = mtd_erase(mtd, &ei);
106 if (ret) 109 if (ret)
107 return -EIO; 110 return -EIO;
108 111
109 wait_for_completion(&complete); 112 wait_for_completion(&complete);
110 if (ei.state != MTD_ERASE_DONE) 113 if (ei.state != MTD_ERASE_DONE)
111 return -EIO; 114 return -EIO;
112 return mtd_erase_mapping(sb, ofs, len); 115 return logfs_mtd_erase_mapping(sb, ofs, len);
113} 116}
114 117
115static void mtd_sync(struct super_block *sb) 118static void logfs_mtd_sync(struct super_block *sb)
116{ 119{
117 struct mtd_info *mtd = logfs_super(sb)->s_mtd; 120 struct mtd_info *mtd = logfs_super(sb)->s_mtd;
118 121
119 if (mtd->sync) 122 mtd_sync(mtd);
120 mtd->sync(mtd);
121} 123}
122 124
123static int mtd_readpage(void *_sb, struct page *page) 125static int logfs_mtd_readpage(void *_sb, struct page *page)
124{ 126{
125 struct super_block *sb = _sb; 127 struct super_block *sb = _sb;
126 int err; 128 int err;
127 129
128 err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE, 130 err = logfs_mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
129 page_address(page)); 131 page_address(page));
130 if (err == -EUCLEAN || err == -EBADMSG) { 132 if (err == -EUCLEAN || err == -EBADMSG) {
131 /* -EBADMSG happens regularly on power failures */ 133 /* -EBADMSG happens regularly on power failures */
@@ -143,18 +145,18 @@ static int mtd_readpage(void *_sb, struct page *page)
143 return err; 145 return err;
144} 146}
145 147
146static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs) 148static struct page *logfs_mtd_find_first_sb(struct super_block *sb, u64 *ofs)
147{ 149{
148 struct logfs_super *super = logfs_super(sb); 150 struct logfs_super *super = logfs_super(sb);
149 struct address_space *mapping = super->s_mapping_inode->i_mapping; 151 struct address_space *mapping = super->s_mapping_inode->i_mapping;
150 filler_t *filler = mtd_readpage; 152 filler_t *filler = logfs_mtd_readpage;
151 struct mtd_info *mtd = super->s_mtd; 153 struct mtd_info *mtd = super->s_mtd;
152 154
153 if (!mtd->block_isbad) 155 if (!mtd_can_have_bb(mtd))
154 return NULL; 156 return NULL;
155 157
156 *ofs = 0; 158 *ofs = 0;
157 while (mtd->block_isbad(mtd, *ofs)) { 159 while (mtd_block_isbad(mtd, *ofs)) {
158 *ofs += mtd->erasesize; 160 *ofs += mtd->erasesize;
159 if (*ofs >= mtd->size) 161 if (*ofs >= mtd->size)
160 return NULL; 162 return NULL;
@@ -163,18 +165,18 @@ static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs)
163 return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb); 165 return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
164} 166}
165 167
166static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs) 168static struct page *logfs_mtd_find_last_sb(struct super_block *sb, u64 *ofs)
167{ 169{
168 struct logfs_super *super = logfs_super(sb); 170 struct logfs_super *super = logfs_super(sb);
169 struct address_space *mapping = super->s_mapping_inode->i_mapping; 171 struct address_space *mapping = super->s_mapping_inode->i_mapping;
170 filler_t *filler = mtd_readpage; 172 filler_t *filler = logfs_mtd_readpage;
171 struct mtd_info *mtd = super->s_mtd; 173 struct mtd_info *mtd = super->s_mtd;
172 174
173 if (!mtd->block_isbad) 175 if (!mtd_can_have_bb(mtd))
174 return NULL; 176 return NULL;
175 177
176 *ofs = mtd->size - mtd->erasesize; 178 *ofs = mtd->size - mtd->erasesize;
177 while (mtd->block_isbad(mtd, *ofs)) { 179 while (mtd_block_isbad(mtd, *ofs)) {
178 *ofs -= mtd->erasesize; 180 *ofs -= mtd->erasesize;
179 if (*ofs <= 0) 181 if (*ofs <= 0)
180 return NULL; 182 return NULL;
@@ -184,7 +186,7 @@ static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs)
184 return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb); 186 return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
185} 187}
186 188
187static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, 189static int __logfs_mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
188 size_t nr_pages) 190 size_t nr_pages)
189{ 191{
190 struct logfs_super *super = logfs_super(sb); 192 struct logfs_super *super = logfs_super(sb);
@@ -196,8 +198,8 @@ static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
196 page = find_lock_page(mapping, index + i); 198 page = find_lock_page(mapping, index + i);
197 BUG_ON(!page); 199 BUG_ON(!page);
198 200
199 err = mtd_write(sb, page->index << PAGE_SHIFT, PAGE_SIZE, 201 err = loffs_mtd_write(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
200 page_address(page)); 202 page_address(page));
201 unlock_page(page); 203 unlock_page(page);
202 page_cache_release(page); 204 page_cache_release(page);
203 if (err) 205 if (err)
@@ -206,7 +208,7 @@ static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
206 return 0; 208 return 0;
207} 209}
208 210
209static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len) 211static void logfs_mtd_writeseg(struct super_block *sb, u64 ofs, size_t len)
210{ 212{
211 struct logfs_super *super = logfs_super(sb); 213 struct logfs_super *super = logfs_super(sb);
212 int head; 214 int head;
@@ -227,15 +229,15 @@ static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len)
227 len += head; 229 len += head;
228 } 230 }
229 len = PAGE_ALIGN(len); 231 len = PAGE_ALIGN(len);
230 __mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT); 232 __logfs_mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
231} 233}
232 234
233static void mtd_put_device(struct logfs_super *s) 235static void logfs_mtd_put_device(struct logfs_super *s)
234{ 236{
235 put_mtd_device(s->s_mtd); 237 put_mtd_device(s->s_mtd);
236} 238}
237 239
238static int mtd_can_write_buf(struct super_block *sb, u64 ofs) 240static int logfs_mtd_can_write_buf(struct super_block *sb, u64 ofs)
239{ 241{
240 struct logfs_super *super = logfs_super(sb); 242 struct logfs_super *super = logfs_super(sb);
241 void *buf; 243 void *buf;
@@ -244,7 +246,7 @@ static int mtd_can_write_buf(struct super_block *sb, u64 ofs)
244 buf = kmalloc(super->s_writesize, GFP_KERNEL); 246 buf = kmalloc(super->s_writesize, GFP_KERNEL);
245 if (!buf) 247 if (!buf)
246 return -ENOMEM; 248 return -ENOMEM;
247 err = mtd_read(sb, ofs, super->s_writesize, buf); 249 err = logfs_mtd_read(sb, ofs, super->s_writesize, buf);
248 if (err) 250 if (err)
249 goto out; 251 goto out;
250 if (memchr_inv(buf, 0xff, super->s_writesize)) 252 if (memchr_inv(buf, 0xff, super->s_writesize))
@@ -255,14 +257,14 @@ out:
255} 257}
256 258
257static const struct logfs_device_ops mtd_devops = { 259static const struct logfs_device_ops mtd_devops = {
258 .find_first_sb = mtd_find_first_sb, 260 .find_first_sb = logfs_mtd_find_first_sb,
259 .find_last_sb = mtd_find_last_sb, 261 .find_last_sb = logfs_mtd_find_last_sb,
260 .readpage = mtd_readpage, 262 .readpage = logfs_mtd_readpage,
261 .writeseg = mtd_writeseg, 263 .writeseg = logfs_mtd_writeseg,
262 .erase = mtd_erase, 264 .erase = logfs_mtd_erase,
263 .can_write_buf = mtd_can_write_buf, 265 .can_write_buf = logfs_mtd_can_write_buf,
264 .sync = mtd_sync, 266 .sync = logfs_mtd_sync,
265 .put_device = mtd_put_device, 267 .put_device = logfs_mtd_put_device,
266}; 268};
267 269
268int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) 270int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr)
diff --git a/fs/romfs/mmap-nommu.c b/fs/romfs/mmap-nommu.c
index eed99428f104..e1a7779dd3cb 100644
--- a/fs/romfs/mmap-nommu.c
+++ b/fs/romfs/mmap-nommu.c
@@ -28,9 +28,10 @@ static unsigned long romfs_get_unmapped_area(struct file *file,
28 struct inode *inode = file->f_mapping->host; 28 struct inode *inode = file->f_mapping->host;
29 struct mtd_info *mtd = inode->i_sb->s_mtd; 29 struct mtd_info *mtd = inode->i_sb->s_mtd;
30 unsigned long isize, offset, maxpages, lpages; 30 unsigned long isize, offset, maxpages, lpages;
31 int ret;
31 32
32 if (!mtd) 33 if (!mtd)
33 goto cant_map_directly; 34 return (unsigned long) -ENOSYS;
34 35
35 /* the mapping mustn't extend beyond the EOF */ 36 /* the mapping mustn't extend beyond the EOF */
36 lpages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 37 lpages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -41,23 +42,20 @@ static unsigned long romfs_get_unmapped_area(struct file *file,
41 if ((pgoff >= maxpages) || (maxpages - pgoff < lpages)) 42 if ((pgoff >= maxpages) || (maxpages - pgoff < lpages))
42 return (unsigned long) -EINVAL; 43 return (unsigned long) -EINVAL;
43 44
44 /* we need to call down to the MTD layer to do the actual mapping */ 45 if (addr != 0)
45 if (mtd->get_unmapped_area) { 46 return (unsigned long) -EINVAL;
46 if (addr != 0)
47 return (unsigned long) -EINVAL;
48
49 if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
50 return (unsigned long) -EINVAL;
51 47
52 offset += ROMFS_I(inode)->i_dataoffset; 48 if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
53 if (offset > mtd->size - len) 49 return (unsigned long) -EINVAL;
54 return (unsigned long) -EINVAL;
55 50
56 return mtd->get_unmapped_area(mtd, len, offset, flags); 51 offset += ROMFS_I(inode)->i_dataoffset;
57 } 52 if (offset > mtd->size - len)
53 return (unsigned long) -EINVAL;
58 54
59cant_map_directly: 55 ret = mtd_get_unmapped_area(mtd, len, offset, flags);
60 return (unsigned long) -ENOSYS; 56 if (ret == -EOPNOTSUPP)
57 ret = -ENOSYS;
58 return (unsigned long) ret;
61} 59}
62 60
63/* 61/*