aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/erase.c4
-rw-r--r--fs/jffs2/gc.c5
-rw-r--r--fs/jffs2/os-linux.h5
-rw-r--r--fs/jffs2/scan.c20
-rw-r--r--fs/jffs2/wbuf.c63
5 files changed, 53 insertions, 44 deletions
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 41451e8bf361..ae858f878875 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.66 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: erase.c,v 1.70 2005/02/09 09:09:01 pavlov Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -233,7 +233,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
233 continue; 233 continue;
234 } 234 }
235 235
236 if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) { 236 if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
237 /* It's in the block we're erasing */ 237 /* It's in the block we're erasing */
238 struct jffs2_raw_node_ref *this; 238 struct jffs2_raw_node_ref *this;
239 239
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 87ec74ff5930..61ae001eced5 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.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: gc.c,v 1.144 2004/12/21 11:18:50 dwmw2 Exp $ 10 * $Id: gc.c,v 1.145 2005/02/09 09:09:01 pavlov Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -816,8 +816,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
816 816
817 /* Doesn't matter if there's one in the same erase block. We're going to 817 /* Doesn't matter if there's one in the same erase block. We're going to
818 delete it too at the same time. */ 818 delete it too at the same time. */
819 if ((raw->flash_offset & ~(c->sector_size-1)) == 819 if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
820 (fd->raw->flash_offset & ~(c->sector_size-1)))
821 continue; 820 continue;
822 821
823 D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw))); 822 D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw)));
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 03b0acc37b73..0412416d1f2d 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.51 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: os-linux.h,v 1.52 2005/02/09 09:09:01 pavlov Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -97,7 +97,10 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
97#endif 97#endif
98} 98}
99 99
100#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
101
100#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) 102#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
103#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
101 104
102#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC) 105#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC)
103#define jffs2_can_mark_obsolete(c) (1) 106#define jffs2_can_mark_obsolete(c) (1)
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index ded53584a897..76859ff53437 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.115 2004/11/17 12:59:08 dedekind Exp $ 10 * $Id: scan.c,v 1.116 2005/02/09 09:09:02 pavlov Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -19,7 +19,7 @@
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include "nodelist.h" 20#include "nodelist.h"
21 21
22#define EMPTY_SCAN_SIZE 1024 22#define DEFAULT_EMPTY_SCAN_SIZE 1024
23 23
24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \ 24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
25 c->free_size -= _x; c->dirty_size += _x; \ 25 c->free_size -= _x; c->dirty_size += _x; \
@@ -75,6 +75,14 @@ static inline int min_free(struct jffs2_sb_info *c)
75 return min; 75 return min;
76 76
77} 77}
78
79static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
80 if (sector_size < DEFAULT_EMPTY_SCAN_SIZE)
81 return sector_size;
82 else
83 return DEFAULT_EMPTY_SCAN_SIZE;
84}
85
78int jffs2_scan_medium(struct jffs2_sb_info *c) 86int jffs2_scan_medium(struct jffs2_sb_info *c)
79{ 87{
80 int i, ret; 88 int i, ret;
@@ -316,7 +324,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
316 if (!buf_size) { 324 if (!buf_size) {
317 buf_len = c->sector_size; 325 buf_len = c->sector_size;
318 } else { 326 } else {
319 buf_len = EMPTY_SCAN_SIZE; 327 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
320 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 328 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
321 if (err) 329 if (err)
322 return err; 330 return err;
@@ -326,10 +334,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
326 ofs = 0; 334 ofs = 0;
327 335
328 /* Scan only 4KiB of 0xFF before declaring it's empty */ 336 /* Scan only 4KiB of 0xFF before declaring it's empty */
329 while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) 337 while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
330 ofs += 4; 338 ofs += 4;
331 339
332 if (ofs == EMPTY_SCAN_SIZE) { 340 if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
333#ifdef CONFIG_JFFS2_FS_NAND 341#ifdef CONFIG_JFFS2_FS_NAND
334 if (jffs2_cleanmarker_oob(c)) { 342 if (jffs2_cleanmarker_oob(c)) {
335 /* scan oob, take care of cleanmarker */ 343 /* scan oob, take care of cleanmarker */
@@ -423,7 +431,7 @@ scan_more:
423 bail now */ 431 bail now */
424 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 432 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
425 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) { 433 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) {
426 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE)); 434 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
427 return BLK_STATE_CLEANMARKER; 435 return BLK_STATE_CLEANMARKER;
428 } 436 }
429 437
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 79414abadd5e..894dea88678d 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.86 2005/02/05 18:23:37 hammache Exp $ 12 * $Id: wbuf.c,v 1.87 2005/02/09 09:09:02 pavlov Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -415,9 +415,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
415 int ret; 415 int ret;
416 size_t retlen; 416 size_t retlen;
417 417
418 /* Nothing to do if not NAND flash. In particular, we shouldn't 418 /* Nothing to do if not write-buffering the flash. In particular, we shouldn't
419 del_timer() the timer we never initialised. */ 419 del_timer() the timer we never initialised. */
420 if (jffs2_can_mark_obsolete(c)) 420 if (!jffs2_is_writebuffered(c))
421 return 0; 421 return 0;
422 422
423 if (!down_trylock(&c->alloc_sem)) { 423 if (!down_trylock(&c->alloc_sem)) {
@@ -426,7 +426,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
426 BUG(); 426 BUG();
427 } 427 }
428 428
429 if(!c->wbuf || !c->wbuf_len) 429 if (!c->wbuf_len) /* already checked c->wbuf above */
430 return 0; 430 return 0;
431 431
432 /* claim remaining space on the page 432 /* claim remaining space on the page
@@ -620,7 +620,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
620 uint32_t outvec_to = to; 620 uint32_t outvec_to = to;
621 621
622 /* If not NAND flash, don't bother */ 622 /* If not NAND flash, don't bother */
623 if (!c->wbuf) 623 if (!jffs2_is_writebuffered(c))
624 return jffs2_flash_direct_writev(c, invecs, count, to, retlen); 624 return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
625 625
626 down_write(&c->wbuf_sem); 626 down_write(&c->wbuf_sem);
@@ -649,7 +649,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
649 erase block. Anything else, and you die. 649 erase block. Anything else, and you die.
650 New block starts at xxx000c (0-b = block header) 650 New block starts at xxx000c (0-b = block header)
651 */ 651 */
652 if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) { 652 if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
653 /* It's a write to a new block */ 653 /* It's a write to a new block */
654 if (c->wbuf_len) { 654 if (c->wbuf_len) {
655 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs)); 655 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
@@ -847,7 +847,7 @@ int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *r
847{ 847{
848 struct kvec vecs[1]; 848 struct kvec vecs[1];
849 849
850 if (jffs2_can_mark_obsolete(c)) 850 if (!jffs2_is_writebuffered(c))
851 return c->mtd->write(c->mtd, ofs, len, retlen, buf); 851 return c->mtd->write(c->mtd, ofs, len, retlen, buf);
852 852
853 vecs[0].iov_base = (unsigned char *) buf; 853 vecs[0].iov_base = (unsigned char *) buf;
@@ -863,38 +863,37 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
863 loff_t orbf = 0, owbf = 0, lwbf = 0; 863 loff_t orbf = 0, owbf = 0, lwbf = 0;
864 int ret; 864 int ret;
865 865
866 /* Read flash */ 866 if (!jffs2_is_writebuffered(c))
867 if (!jffs2_can_mark_obsolete(c)) {
868
869 if (jffs2_cleanmarker_oob(c))
870 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
871 else
872 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
873
874 if ( (ret == -EBADMSG) && (*retlen == len) ) {
875 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
876 len, ofs);
877 /*
878 * We have the raw data without ECC correction in the buffer, maybe
879 * we are lucky and all data or parts are correct. We check the node.
880 * If data are corrupted node check will sort it out.
881 * We keep this block, it will fail on write or erase and the we
882 * mark it bad. Or should we do that now? But we should give him a chance.
883 * Maybe we had a system crash or power loss before the ecc write or
884 * a erase was completed.
885 * So we return success. :)
886 */
887 ret = 0;
888 }
889 } else
890 return c->mtd->read(c->mtd, ofs, len, retlen, buf); 867 return c->mtd->read(c->mtd, ofs, len, retlen, buf);
891 868
869 /* Read flash */
870 if (jffs2_cleanmarker_oob(c))
871 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
872 else
873 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
874
875 if ( (ret == -EBADMSG) && (*retlen == len) ) {
876 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
877 len, ofs);
878 /*
879 * We have the raw data without ECC correction in the buffer, maybe
880 * we are lucky and all data or parts are correct. We check the node.
881 * If data are corrupted node check will sort it out.
882 * We keep this block, it will fail on write or erase and the we
883 * mark it bad. Or should we do that now? But we should give him a chance.
884 * Maybe we had a system crash or power loss before the ecc write or
885 * a erase was completed.
886 * So we return success. :)
887 */
888 ret = 0;
889 }
890
892 /* if no writebuffer available or write buffer empty, return */ 891 /* if no writebuffer available or write buffer empty, return */
893 if (!c->wbuf_pagesize || !c->wbuf_len) 892 if (!c->wbuf_pagesize || !c->wbuf_len)
894 return ret;; 893 return ret;;
895 894
896 /* if we read in a different block, return */ 895 /* if we read in a different block, return */
897 if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 896 if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs))
898 return ret; 897 return ret;
899 898
900 /* Lock only if we have reason to believe wbuf contains relevant data, 899 /* Lock only if we have reason to believe wbuf contains relevant data,