diff options
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/Makefile | 3 | ||||
-rw-r--r-- | fs/jffs2/erase.c | 13 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 21 | ||||
-rw-r--r-- | fs/jffs2/os-linux.h | 18 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 11 | ||||
-rw-r--r-- | fs/jffs2/wbuf.c | 35 |
6 files changed, 87 insertions, 14 deletions
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile index e3c38ccf9c7d..6c2ebe176b40 100644 --- a/fs/jffs2/Makefile +++ b/fs/jffs2/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the Linux Journalling Flash File System v2 (JFFS2) | 2 | # Makefile for the Linux Journalling Flash File System v2 (JFFS2) |
3 | # | 3 | # |
4 | # $Id: Makefile.common,v 1.7 2004/11/03 12:57:38 jwboyer Exp $ | 4 | # $Id: Makefile.common,v 1.8 2005/02/09 09:17:40 pavlov Exp $ |
5 | # | 5 | # |
6 | 6 | ||
7 | obj-$(CONFIG_JFFS2_FS) += jffs2.o | 7 | obj-$(CONFIG_JFFS2_FS) += jffs2.o |
@@ -13,6 +13,7 @@ jffs2-y += super.o | |||
13 | 13 | ||
14 | jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o | 14 | jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o |
15 | jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o | 15 | jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o |
16 | jffs2-$(CONFIG_JFFS2_FS_DATAFLASH) += wbuf.o | ||
16 | jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o | 17 | jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o |
17 | jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o | 18 | jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o |
18 | jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o | 19 | jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o |
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index ae858f878875..a3c6cc150497 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: erase.c,v 1.70 2005/02/09 09:09:01 pavlov Exp $ | 10 | * $Id: erase.c,v 1.71 2005/02/09 09:17:40 pavlov Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -310,7 +310,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb | |||
310 | int ret; | 310 | int ret; |
311 | uint32_t bad_offset; | 311 | uint32_t bad_offset; |
312 | 312 | ||
313 | if (!jffs2_cleanmarker_oob(c)) { | 313 | if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) { |
314 | marker_ref = jffs2_alloc_raw_node_ref(); | 314 | marker_ref = jffs2_alloc_raw_node_ref(); |
315 | if (!marker_ref) { | 315 | if (!marker_ref) { |
316 | printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n"); | 316 | printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n"); |
@@ -351,7 +351,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb | |||
351 | bad_offset += i; | 351 | bad_offset += i; |
352 | printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset); | 352 | printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset); |
353 | bad: | 353 | bad: |
354 | if (!jffs2_cleanmarker_oob(c)) | 354 | if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) |
355 | jffs2_free_raw_node_ref(marker_ref); | 355 | jffs2_free_raw_node_ref(marker_ref); |
356 | kfree(ebuf); | 356 | kfree(ebuf); |
357 | bad2: | 357 | bad2: |
@@ -387,6 +387,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb | |||
387 | jeb->used_size = 0; | 387 | jeb->used_size = 0; |
388 | jeb->dirty_size = 0; | 388 | jeb->dirty_size = 0; |
389 | jeb->wasted_size = 0; | 389 | jeb->wasted_size = 0; |
390 | } else if (c->cleanmarker_size == 0) { | ||
391 | jeb->first_node = jeb->last_node = NULL; | ||
392 | |||
393 | jeb->free_size = c->sector_size; | ||
394 | jeb->used_size = 0; | ||
395 | jeb->dirty_size = 0; | ||
396 | jeb->wasted_size = 0; | ||
390 | } else { | 397 | } else { |
391 | struct kvec vecs[1]; | 398 | struct kvec vecs[1]; |
392 | struct jffs2_unknown_node marker = { | 399 | struct jffs2_unknown_node marker = { |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 30ab233fe423..5b7c960a0475 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: fs.c,v 1.51 2004/11/28 12:19:37 dedekind Exp $ | 10 | * $Id: fs.c,v 1.52 2005/02/09 09:17:40 pavlov Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -456,6 +456,12 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | |||
456 | return -EINVAL; | 456 | return -EINVAL; |
457 | } | 457 | } |
458 | #endif | 458 | #endif |
459 | #ifndef CONFIG_JFFS2_FS_DATAFLASH | ||
460 | if (c->mtd->type == MTD_DATAFLASH) { | ||
461 | printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n"); | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | #endif | ||
459 | 465 | ||
460 | c->flash_size = c->mtd->size; | 466 | c->flash_size = c->mtd->size; |
461 | 467 | ||
@@ -661,6 +667,14 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) { | |||
661 | if (ret) | 667 | if (ret) |
662 | return ret; | 668 | return ret; |
663 | } | 669 | } |
670 | |||
671 | /* and Dataflash */ | ||
672 | if (jffs2_dataflash(c)) { | ||
673 | ret = jffs2_dataflash_setup(c); | ||
674 | if (ret) | ||
675 | return ret; | ||
676 | } | ||
677 | |||
664 | return ret; | 678 | return ret; |
665 | } | 679 | } |
666 | 680 | ||
@@ -674,4 +688,9 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) { | |||
674 | if (jffs2_nor_ecc(c)) { | 688 | if (jffs2_nor_ecc(c)) { |
675 | jffs2_nor_ecc_flash_cleanup(c); | 689 | jffs2_nor_ecc_flash_cleanup(c); |
676 | } | 690 | } |
691 | |||
692 | /* and DataFlash */ | ||
693 | if (jffs2_dataflash(c)) { | ||
694 | jffs2_dataflash_cleanup(c); | ||
695 | } | ||
677 | } | 696 | } |
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 0412416d1f2d..af27b84007a1 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: os-linux.h,v 1.52 2005/02/09 09:09:01 pavlov Exp $ | 10 | * $Id: os-linux.h,v 1.53 2005/02/09 09:17:41 pavlov Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -97,12 +97,16 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) | |||
97 | #endif | 97 | #endif |
98 | } | 98 | } |
99 | 99 | ||
100 | #ifdef CONFIG_JFFS2_FS_DATAFLASH | ||
101 | #define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size ) | ||
102 | #else | ||
100 | #define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) ) | 103 | #define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) ) |
104 | #endif | ||
101 | 105 | ||
102 | #define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) | 106 | #define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) |
103 | #define jffs2_is_writebuffered(c) (c->wbuf != NULL) | 107 | #define jffs2_is_writebuffered(c) (c->wbuf != NULL) |
104 | 108 | ||
105 | #if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC) | 109 | #if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC && !defined CONFIG_JFFS2_FS_DATAFLASH) |
106 | #define jffs2_can_mark_obsolete(c) (1) | 110 | #define jffs2_can_mark_obsolete(c) (1) |
107 | #define jffs2_cleanmarker_oob(c) (0) | 111 | #define jffs2_cleanmarker_oob(c) (0) |
108 | #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) | 112 | #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) |
@@ -119,6 +123,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) | |||
119 | #define jffs2_wbuf_timeout NULL | 123 | #define jffs2_wbuf_timeout NULL |
120 | #define jffs2_wbuf_process NULL | 124 | #define jffs2_wbuf_process NULL |
121 | #define jffs2_nor_ecc(c) (0) | 125 | #define jffs2_nor_ecc(c) (0) |
126 | #define jffs2_dataflash(c) (0) | ||
122 | #define jffs2_nor_ecc_flash_setup(c) (0) | 127 | #define jffs2_nor_ecc_flash_setup(c) (0) |
123 | #define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) | 128 | #define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) |
124 | 129 | ||
@@ -154,6 +159,15 @@ void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c); | |||
154 | #define jffs2_nor_ecc_flash_setup(c) (0) | 159 | #define jffs2_nor_ecc_flash_setup(c) (0) |
155 | #define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) | 160 | #define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) |
156 | #endif /* NOR ECC */ | 161 | #endif /* NOR ECC */ |
162 | #ifdef CONFIG_JFFS2_FS_DATAFLASH | ||
163 | #define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH) | ||
164 | int jffs2_dataflash_setup(struct jffs2_sb_info *c); | ||
165 | void jffs2_dataflash_cleanup(struct jffs2_sb_info *c); | ||
166 | #else | ||
167 | #define jffs2_dataflash(c) (0) | ||
168 | #define jffs2_dataflash_setup(c) (0) | ||
169 | #define jffs2_dataflash_cleanup(c) do {} while (0) | ||
170 | #endif /* DATAFLASH */ | ||
157 | #endif /* NAND */ | 171 | #endif /* NAND */ |
158 | 172 | ||
159 | /* erase.c */ | 173 | /* erase.c */ |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 76859ff53437..e8c43746c82e 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: scan.c,v 1.116 2005/02/09 09:09:02 pavlov Exp $ | 10 | * $Id: scan.c,v 1.117 2005/02/09 09:17:41 pavlov Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
@@ -68,7 +68,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
68 | static inline int min_free(struct jffs2_sb_info *c) | 68 | static inline int min_free(struct jffs2_sb_info *c) |
69 | { | 69 | { |
70 | uint32_t min = 2 * sizeof(struct jffs2_raw_inode); | 70 | uint32_t min = 2 * sizeof(struct jffs2_raw_inode); |
71 | #if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC | 71 | #if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC || defined CONFIG_JFFS2_FS_DATAFLASH |
72 | if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize) | 72 | if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize) |
73 | return c->wbuf_pagesize; | 73 | return c->wbuf_pagesize; |
74 | #endif | 74 | #endif |
@@ -228,7 +228,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
228 | c->dirty_size -= c->nextblock->dirty_size; | 228 | c->dirty_size -= c->nextblock->dirty_size; |
229 | c->nextblock->dirty_size = 0; | 229 | c->nextblock->dirty_size = 0; |
230 | } | 230 | } |
231 | #if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC | 231 | #if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC || defined CONFIG_JFFS2_FS_DATAFLASH |
232 | if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { | 232 | if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { |
233 | /* If we're going to start writing into a block which already | 233 | /* If we're going to start writing into a block which already |
234 | contains data, and the end of the data isn't page-aligned, | 234 | contains data, and the end of the data isn't page-aligned, |
@@ -351,7 +351,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
351 | } | 351 | } |
352 | #endif | 352 | #endif |
353 | D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); | 353 | D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); |
354 | return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ | 354 | if (c->cleanmarker_size == 0) |
355 | return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */ | ||
356 | else | ||
357 | return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ | ||
355 | } | 358 | } |
356 | if (ofs) { | 359 | if (ofs) { |
357 | D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, | 360 | D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 894dea88678d..a35e007e5bf8 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * For licensing information, see the file 'LICENCE' in this directory. | 10 | * For licensing information, see the file 'LICENCE' in this directory. |
11 | * | 11 | * |
12 | * $Id: wbuf.c,v 1.87 2005/02/09 09:09:02 pavlov Exp $ | 12 | * $Id: wbuf.c,v 1.88 2005/02/09 09:17:41 pavlov Exp $ |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
@@ -435,7 +435,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) | |||
435 | if we have a switch to next page, we will not have | 435 | if we have a switch to next page, we will not have |
436 | enough remaining space for this. | 436 | enough remaining space for this. |
437 | */ | 437 | */ |
438 | if (pad) { | 438 | if (pad && !jffs2_dataflash(c)) { |
439 | c->wbuf_len = PAD(c->wbuf_len); | 439 | c->wbuf_len = PAD(c->wbuf_len); |
440 | 440 | ||
441 | /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR | 441 | /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR |
@@ -486,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) | |||
486 | spin_lock(&c->erase_completion_lock); | 486 | spin_lock(&c->erase_completion_lock); |
487 | 487 | ||
488 | /* Adjust free size of the block if we padded. */ | 488 | /* Adjust free size of the block if we padded. */ |
489 | if (pad) { | 489 | if (pad && !jffs2_dataflash(c)) { |
490 | struct jffs2_eraseblock *jeb; | 490 | struct jffs2_eraseblock *jeb; |
491 | 491 | ||
492 | jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; | 492 | jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; |
@@ -604,8 +604,14 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c) | |||
604 | return ret; | 604 | return ret; |
605 | } | 605 | } |
606 | 606 | ||
607 | #ifdef CONFIG_JFFS2_FS_DATAFLASH | ||
608 | #define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) ) | ||
609 | #define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) ) | ||
610 | #else | ||
607 | #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) | 611 | #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) |
608 | #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) | 612 | #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) |
613 | #endif | ||
614 | |||
609 | int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) | 615 | int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) |
610 | { | 616 | { |
611 | struct kvec outvecs[3]; | 617 | struct kvec outvecs[3]; |
@@ -1192,6 +1198,29 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) | |||
1192 | kfree(c->wbuf); | 1198 | kfree(c->wbuf); |
1193 | } | 1199 | } |
1194 | 1200 | ||
1201 | #ifdef CONFIG_JFFS2_FS_DATAFLASH | ||
1202 | int jffs2_dataflash_setup(struct jffs2_sb_info *c) { | ||
1203 | c->cleanmarker_size = 0; /* No cleanmarkers needed */ | ||
1204 | |||
1205 | /* Initialize write buffer */ | ||
1206 | init_rwsem(&c->wbuf_sem); | ||
1207 | c->wbuf_pagesize = c->sector_size; | ||
1208 | c->wbuf_ofs = 0xFFFFFFFF; | ||
1209 | |||
1210 | c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); | ||
1211 | if (!c->wbuf) | ||
1212 | return -ENOMEM; | ||
1213 | |||
1214 | printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize); | ||
1215 | |||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) { | ||
1220 | kfree(c->wbuf); | ||
1221 | } | ||
1222 | #endif | ||
1223 | |||
1195 | #ifdef CONFIG_JFFS2_FS_NOR_ECC | 1224 | #ifdef CONFIG_JFFS2_FS_NOR_ECC |
1196 | int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { | 1225 | int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { |
1197 | /* Cleanmarker is actually larger on the flashes */ | 1226 | /* Cleanmarker is actually larger on the flashes */ |