diff options
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index ded53584a897..b63160f83bab 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.119 2005/02/17 17:51:13 dedekind 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; \ |
@@ -68,13 +68,21 @@ 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 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER |
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 |
75 | return min; | 75 | return min; |
76 | 76 | ||
77 | } | 77 | } |
78 | |||
79 | static 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 | |||
78 | int jffs2_scan_medium(struct jffs2_sb_info *c) | 86 | int jffs2_scan_medium(struct jffs2_sb_info *c) |
79 | { | 87 | { |
80 | int i, ret; | 88 | int i, ret; |
@@ -220,7 +228,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
220 | c->dirty_size -= c->nextblock->dirty_size; | 228 | c->dirty_size -= c->nextblock->dirty_size; |
221 | c->nextblock->dirty_size = 0; | 229 | c->nextblock->dirty_size = 0; |
222 | } | 230 | } |
223 | #if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC | 231 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER |
224 | 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))) { |
225 | /* 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 |
226 | 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, |
@@ -286,7 +294,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
286 | uint32_t hdr_crc, buf_ofs, buf_len; | 294 | uint32_t hdr_crc, buf_ofs, buf_len; |
287 | int err; | 295 | int err; |
288 | int noise = 0; | 296 | int noise = 0; |
289 | #ifdef CONFIG_JFFS2_FS_NAND | 297 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER |
290 | int cleanmarkerfound = 0; | 298 | int cleanmarkerfound = 0; |
291 | #endif | 299 | #endif |
292 | 300 | ||
@@ -295,7 +303,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
295 | 303 | ||
296 | D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); | 304 | D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); |
297 | 305 | ||
298 | #ifdef CONFIG_JFFS2_FS_NAND | 306 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER |
299 | if (jffs2_cleanmarker_oob(c)) { | 307 | if (jffs2_cleanmarker_oob(c)) { |
300 | int ret = jffs2_check_nand_cleanmarker(c, jeb); | 308 | int ret = jffs2_check_nand_cleanmarker(c, jeb); |
301 | D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); | 309 | D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",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,11 +334,11 @@ 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_WRITEBUFFER |
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 */ |
336 | int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); | 344 | int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); |
@@ -343,7 +351,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
343 | } | 351 | } |
344 | #endif | 352 | #endif |
345 | 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)); |
346 | 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 */ | ||
347 | } | 358 | } |
348 | if (ofs) { | 359 | if (ofs) { |
349 | 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, |
@@ -422,8 +433,8 @@ scan_more: | |||
422 | /* If we're only checking the beginning of a block with a cleanmarker, | 433 | /* If we're only checking the beginning of a block with a cleanmarker, |
423 | bail now */ | 434 | bail now */ |
424 | if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && | 435 | 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) { | 436 | c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) { |
426 | D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE)); | 437 | 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; | 438 | return BLK_STATE_CLEANMARKER; |
428 | } | 439 | } |
429 | 440 | ||
@@ -618,7 +629,7 @@ scan_more: | |||
618 | } | 629 | } |
619 | 630 | ||
620 | if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size | 631 | if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size |
621 | && (!jeb->first_node || !jeb->first_node->next_in_ino) ) | 632 | && (!jeb->first_node || !jeb->first_node->next_phys) ) |
622 | return BLK_STATE_CLEANMARKER; | 633 | return BLK_STATE_CLEANMARKER; |
623 | 634 | ||
624 | /* move blocks with max 4 byte dirty space to cleanlist */ | 635 | /* move blocks with max 4 byte dirty space to cleanlist */ |