aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r--fs/jffs2/scan.c300
1 files changed, 163 insertions, 137 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index b63160f83ba..0e7456ec99f 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.119 2005/02/17 17:51:13 dedekind Exp $ 10 * $Id: scan.c,v 1.125 2005/09/30 13:59:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -18,22 +18,11 @@
18#include <linux/crc32.h> 18#include <linux/crc32.h>
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include "nodelist.h" 20#include "nodelist.h"
21#include "summary.h"
22#include "debug.h"
21 23
22#define DEFAULT_EMPTY_SCAN_SIZE 1024 24#define DEFAULT_EMPTY_SCAN_SIZE 1024
23 25
24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
25 c->free_size -= _x; c->dirty_size += _x; \
26 jeb->free_size -= _x ; jeb->dirty_size += _x; \
27 }while(0)
28#define USED_SPACE(x) do { typeof(x) _x = (x); \
29 c->free_size -= _x; c->used_size += _x; \
30 jeb->free_size -= _x ; jeb->used_size += _x; \
31 }while(0)
32#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
33 c->free_size -= _x; c->unchecked_size += _x; \
34 jeb->free_size -= _x ; jeb->unchecked_size += _x; \
35 }while(0)
36
37#define noisy_printk(noise, args...) do { \ 26#define noisy_printk(noise, args...) do { \
38 if (*(noise)) { \ 27 if (*(noise)) { \
39 printk(KERN_NOTICE args); \ 28 printk(KERN_NOTICE args); \
@@ -47,23 +36,16 @@
47static uint32_t pseudo_random; 36static uint32_t pseudo_random;
48 37
49static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 38static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
50 unsigned char *buf, uint32_t buf_size); 39 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s);
51 40
52/* These helper functions _must_ increase ofs and also do the dirty/used space accounting. 41/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
53 * Returning an error will abort the mount - bad checksums etc. should just mark the space 42 * Returning an error will abort the mount - bad checksums etc. should just mark the space
54 * as dirty. 43 * as dirty.
55 */ 44 */
56static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 45static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
57 struct jffs2_raw_inode *ri, uint32_t ofs); 46 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s);
58static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 47static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
59 struct jffs2_raw_dirent *rd, uint32_t ofs); 48 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s);
60
61#define BLK_STATE_ALLFF 0
62#define BLK_STATE_CLEAN 1
63#define BLK_STATE_PARTDIRTY 2
64#define BLK_STATE_CLEANMARKER 3
65#define BLK_STATE_ALLDIRTY 4
66#define BLK_STATE_BADBLOCK 5
67 49
68static inline int min_free(struct jffs2_sb_info *c) 50static inline int min_free(struct jffs2_sb_info *c)
69{ 51{
@@ -89,6 +71,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
89 uint32_t empty_blocks = 0, bad_blocks = 0; 71 uint32_t empty_blocks = 0, bad_blocks = 0;
90 unsigned char *flashbuf = NULL; 72 unsigned char *flashbuf = NULL;
91 uint32_t buf_size = 0; 73 uint32_t buf_size = 0;
74 struct jffs2_summary *s = NULL; /* summary info collected by the scan process */
92#ifndef __ECOS 75#ifndef __ECOS
93 size_t pointlen; 76 size_t pointlen;
94 77
@@ -122,21 +105,34 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
122 return -ENOMEM; 105 return -ENOMEM;
123 } 106 }
124 107
108 if (jffs2_sum_active()) {
109 s = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
110 if (!s) {
111 JFFS2_WARNING("Can't allocate memory for summary\n");
112 return -ENOMEM;
113 }
114 memset(s, 0, sizeof(struct jffs2_summary));
115 }
116
125 for (i=0; i<c->nr_blocks; i++) { 117 for (i=0; i<c->nr_blocks; i++) {
126 struct jffs2_eraseblock *jeb = &c->blocks[i]; 118 struct jffs2_eraseblock *jeb = &c->blocks[i];
127 119
128 ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size); 120 /* reset summary info for next eraseblock scan */
121 jffs2_sum_reset_collected(s);
122
123 ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
124 buf_size, s);
129 125
130 if (ret < 0) 126 if (ret < 0)
131 goto out; 127 goto out;
132 128
133 ACCT_PARANOIA_CHECK(jeb); 129 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
134 130
135 /* Now decide which list to put it on */ 131 /* Now decide which list to put it on */
136 switch(ret) { 132 switch(ret) {
137 case BLK_STATE_ALLFF: 133 case BLK_STATE_ALLFF:
138 /* 134 /*
139 * Empty block. Since we can't be sure it 135 * Empty block. Since we can't be sure it
140 * was entirely erased, we just queue it for erase 136 * was entirely erased, we just queue it for erase
141 * again. It will be marked as such when the erase 137 * again. It will be marked as such when the erase
142 * is complete. Meanwhile we still count it as empty 138 * is complete. Meanwhile we still count it as empty
@@ -162,18 +158,18 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
162 break; 158 break;
163 159
164 case BLK_STATE_CLEAN: 160 case BLK_STATE_CLEAN:
165 /* Full (or almost full) of clean data. Clean list */ 161 /* Full (or almost full) of clean data. Clean list */
166 list_add(&jeb->list, &c->clean_list); 162 list_add(&jeb->list, &c->clean_list);
167 break; 163 break;
168 164
169 case BLK_STATE_PARTDIRTY: 165 case BLK_STATE_PARTDIRTY:
170 /* Some data, but not full. Dirty list. */ 166 /* Some data, but not full. Dirty list. */
171 /* We want to remember the block with most free space 167 /* We want to remember the block with most free space
172 and stick it in the 'nextblock' position to start writing to it. */ 168 and stick it in the 'nextblock' position to start writing to it. */
173 if (jeb->free_size > min_free(c) && 169 if (jeb->free_size > min_free(c) &&
174 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) { 170 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
175 /* Better candidate for the next writes to go to */ 171 /* Better candidate for the next writes to go to */
176 if (c->nextblock) { 172 if (c->nextblock) {
177 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 173 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
178 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 174 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
179 c->free_size -= c->nextblock->free_size; 175 c->free_size -= c->nextblock->free_size;
@@ -184,9 +180,14 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
184 } else { 180 } else {
185 list_add(&c->nextblock->list, &c->dirty_list); 181 list_add(&c->nextblock->list, &c->dirty_list);
186 } 182 }
183 /* deleting summary information of the old nextblock */
184 jffs2_sum_reset_collected(c->summary);
187 } 185 }
188 c->nextblock = jeb; 186 /* update collected summary infromation for the current nextblock */
189 } else { 187 jffs2_sum_move_collected(c, s);
188 D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset));
189 c->nextblock = jeb;
190 } else {
190 jeb->dirty_size += jeb->free_size + jeb->wasted_size; 191 jeb->dirty_size += jeb->free_size + jeb->wasted_size;
191 c->dirty_size += jeb->free_size + jeb->wasted_size; 192 c->dirty_size += jeb->free_size + jeb->wasted_size;
192 c->free_size -= jeb->free_size; 193 c->free_size -= jeb->free_size;
@@ -197,30 +198,33 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
197 } else { 198 } else {
198 list_add(&jeb->list, &c->dirty_list); 199 list_add(&jeb->list, &c->dirty_list);
199 } 200 }
200 } 201 }
201 break; 202 break;
202 203
203 case BLK_STATE_ALLDIRTY: 204 case BLK_STATE_ALLDIRTY:
204 /* Nothing valid - not even a clean marker. Needs erasing. */ 205 /* Nothing valid - not even a clean marker. Needs erasing. */
205 /* For now we just put it on the erasing list. We'll start the erases later */ 206 /* For now we just put it on the erasing list. We'll start the erases later */
206 D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset)); 207 D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));
207 list_add(&jeb->list, &c->erase_pending_list); 208 list_add(&jeb->list, &c->erase_pending_list);
208 c->nr_erasing_blocks++; 209 c->nr_erasing_blocks++;
209 break; 210 break;
210 211
211 case BLK_STATE_BADBLOCK: 212 case BLK_STATE_BADBLOCK:
212 D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset)); 213 D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
213 list_add(&jeb->list, &c->bad_list); 214 list_add(&jeb->list, &c->bad_list);
214 c->bad_size += c->sector_size; 215 c->bad_size += c->sector_size;
215 c->free_size -= c->sector_size; 216 c->free_size -= c->sector_size;
216 bad_blocks++; 217 bad_blocks++;
217 break; 218 break;
218 default: 219 default:
219 printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n"); 220 printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
220 BUG(); 221 BUG();
221 } 222 }
222 } 223 }
223 224
225 if (jffs2_sum_active() && s)
226 kfree(s);
227
224 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */ 228 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
225 if (c->nextblock && (c->nextblock->dirty_size)) { 229 if (c->nextblock && (c->nextblock->dirty_size)) {
226 c->nextblock->wasted_size += c->nextblock->dirty_size; 230 c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -229,12 +233,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
229 c->nextblock->dirty_size = 0; 233 c->nextblock->dirty_size = 0;
230 } 234 }
231#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 235#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
232 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { 236 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) {
233 /* If we're going to start writing into a block which already 237 /* 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, 238 contains data, and the end of the data isn't page-aligned,
235 skip a little and align it. */ 239 skip a little and align it. */
236 240
237 uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); 241 uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize;
238 242
239 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", 243 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
240 skip)); 244 skip));
@@ -246,7 +250,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
246 } 250 }
247#endif 251#endif
248 if (c->nr_erasing_blocks) { 252 if (c->nr_erasing_blocks) {
249 if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { 253 if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
250 printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n"); 254 printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
251 printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks); 255 printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
252 ret = -EIO; 256 ret = -EIO;
@@ -259,13 +263,13 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
259 if (buf_size) 263 if (buf_size)
260 kfree(flashbuf); 264 kfree(flashbuf);
261#ifndef __ECOS 265#ifndef __ECOS
262 else 266 else
263 c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); 267 c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
264#endif 268#endif
265 return ret; 269 return ret;
266} 270}
267 271
268static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf, 272int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
269 uint32_t ofs, uint32_t len) 273 uint32_t ofs, uint32_t len)
270{ 274{
271 int ret; 275 int ret;
@@ -286,14 +290,36 @@ static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
286 return 0; 290 return 0;
287} 291}
288 292
293int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
294{
295 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
296 && (!jeb->first_node || !jeb->first_node->next_phys) )
297 return BLK_STATE_CLEANMARKER;
298
299 /* move blocks with max 4 byte dirty space to cleanlist */
300 else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
301 c->dirty_size -= jeb->dirty_size;
302 c->wasted_size += jeb->dirty_size;
303 jeb->wasted_size += jeb->dirty_size;
304 jeb->dirty_size = 0;
305 return BLK_STATE_CLEAN;
306 } else if (jeb->used_size || jeb->unchecked_size)
307 return BLK_STATE_PARTDIRTY;
308 else
309 return BLK_STATE_ALLDIRTY;
310}
311
289static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 312static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
290 unsigned char *buf, uint32_t buf_size) { 313 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
291 struct jffs2_unknown_node *node; 314 struct jffs2_unknown_node *node;
292 struct jffs2_unknown_node crcnode; 315 struct jffs2_unknown_node crcnode;
316 struct jffs2_sum_marker *sm;
293 uint32_t ofs, prevofs; 317 uint32_t ofs, prevofs;
294 uint32_t hdr_crc, buf_ofs, buf_len; 318 uint32_t hdr_crc, buf_ofs, buf_len;
295 int err; 319 int err;
296 int noise = 0; 320 int noise = 0;
321
322
297#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 323#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
298 int cleanmarkerfound = 0; 324 int cleanmarkerfound = 0;
299#endif 325#endif
@@ -319,17 +345,53 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
319 } 345 }
320 } 346 }
321#endif 347#endif
348
349 if (jffs2_sum_active()) {
350 sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL);
351 if (!sm) {
352 return -ENOMEM;
353 }
354
355 err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -
356 sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));
357 if (err) {
358 kfree(sm);
359 return err;
360 }
361
362 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) {
363 err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random);
364 if (err) {
365 kfree(sm);
366 return err;
367 }
368 }
369
370 kfree(sm);
371
372 ofs = jeb->offset;
373 prevofs = jeb->offset - 1;
374 }
375
322 buf_ofs = jeb->offset; 376 buf_ofs = jeb->offset;
323 377
324 if (!buf_size) { 378 if (!buf_size) {
325 buf_len = c->sector_size; 379 buf_len = c->sector_size;
380
381 if (jffs2_sum_active()) {
382 /* must reread because of summary test */
383 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
384 if (err)
385 return err;
386 }
387
326 } else { 388 } else {
327 buf_len = EMPTY_SCAN_SIZE(c->sector_size); 389 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
328 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 390 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
329 if (err) 391 if (err)
330 return err; 392 return err;
331 } 393 }
332 394
333 /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ 395 /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
334 ofs = 0; 396 ofs = 0;
335 397
@@ -367,10 +429,12 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
367 429
368 noise = 10; 430 noise = 10;
369 431
370scan_more: 432 dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
433
434scan_more:
371 while(ofs < jeb->offset + c->sector_size) { 435 while(ofs < jeb->offset + c->sector_size) {
372 436
373 D1(ACCT_PARANOIA_CHECK(jeb)); 437 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
374 438
375 cond_resched(); 439 cond_resched();
376 440
@@ -432,7 +496,7 @@ scan_more:
432 496
433 /* If we're only checking the beginning of a block with a cleanmarker, 497 /* If we're only checking the beginning of a block with a cleanmarker,
434 bail now */ 498 bail now */
435 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 499 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
436 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) { 500 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
437 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); 501 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
438 return BLK_STATE_CLEANMARKER; 502 return BLK_STATE_CLEANMARKER;
@@ -441,7 +505,7 @@ scan_more:
441 /* See how much more there is to read in this eraseblock... */ 505 /* See how much more there is to read in this eraseblock... */
442 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); 506 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
443 if (!buf_len) { 507 if (!buf_len) {
444 /* No more to read. Break out of main loop without marking 508 /* No more to read. Break out of main loop without marking
445 this range of empty space as dirty (because it's not) */ 509 this range of empty space as dirty (because it's not) */
446 D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n", 510 D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",
447 empty_start)); 511 empty_start));
@@ -476,8 +540,8 @@ scan_more:
476 } 540 }
477 if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { 541 if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
478 /* OK. We're out of possibilities. Whinge and move on */ 542 /* OK. We're out of possibilities. Whinge and move on */
479 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", 543 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
480 JFFS2_MAGIC_BITMASK, ofs, 544 JFFS2_MAGIC_BITMASK, ofs,
481 je16_to_cpu(node->magic)); 545 je16_to_cpu(node->magic));
482 DIRTY_SPACE(4); 546 DIRTY_SPACE(4);
483 ofs += 4; 547 ofs += 4;
@@ -492,7 +556,7 @@ scan_more:
492 if (hdr_crc != je32_to_cpu(node->hdr_crc)) { 556 if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
493 noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", 557 noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
494 ofs, je16_to_cpu(node->magic), 558 ofs, je16_to_cpu(node->magic),
495 je16_to_cpu(node->nodetype), 559 je16_to_cpu(node->nodetype),
496 je32_to_cpu(node->totlen), 560 je32_to_cpu(node->totlen),
497 je32_to_cpu(node->hdr_crc), 561 je32_to_cpu(node->hdr_crc),
498 hdr_crc); 562 hdr_crc);
@@ -501,7 +565,7 @@ scan_more:
501 continue; 565 continue;
502 } 566 }
503 567
504 if (ofs + je32_to_cpu(node->totlen) > 568 if (ofs + je32_to_cpu(node->totlen) >
505 jeb->offset + c->sector_size) { 569 jeb->offset + c->sector_size) {
506 /* Eep. Node goes over the end of the erase block. */ 570 /* Eep. Node goes over the end of the erase block. */
507 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", 571 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
@@ -532,11 +596,11 @@ scan_more:
532 buf_ofs = ofs; 596 buf_ofs = ofs;
533 node = (void *)buf; 597 node = (void *)buf;
534 } 598 }
535 err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs); 599 err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs, s);
536 if (err) return err; 600 if (err) return err;
537 ofs += PAD(je32_to_cpu(node->totlen)); 601 ofs += PAD(je32_to_cpu(node->totlen));
538 break; 602 break;
539 603
540 case JFFS2_NODETYPE_DIRENT: 604 case JFFS2_NODETYPE_DIRENT:
541 if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { 605 if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
542 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); 606 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
@@ -548,7 +612,7 @@ scan_more:
548 buf_ofs = ofs; 612 buf_ofs = ofs;
549 node = (void *)buf; 613 node = (void *)buf;
550 } 614 }
551 err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs); 615 err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs, s);
552 if (err) return err; 616 if (err) return err;
553 ofs += PAD(je32_to_cpu(node->totlen)); 617 ofs += PAD(je32_to_cpu(node->totlen));
554 break; 618 break;
@@ -556,7 +620,7 @@ scan_more:
556 case JFFS2_NODETYPE_CLEANMARKER: 620 case JFFS2_NODETYPE_CLEANMARKER:
557 D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); 621 D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
558 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { 622 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
559 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", 623 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
560 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); 624 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
561 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); 625 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
562 ofs += PAD(sizeof(struct jffs2_unknown_node)); 626 ofs += PAD(sizeof(struct jffs2_unknown_node));
@@ -575,13 +639,15 @@ scan_more:
575 marker_ref->flash_offset = ofs | REF_NORMAL; 639 marker_ref->flash_offset = ofs | REF_NORMAL;
576 marker_ref->__totlen = c->cleanmarker_size; 640 marker_ref->__totlen = c->cleanmarker_size;
577 jeb->first_node = jeb->last_node = marker_ref; 641 jeb->first_node = jeb->last_node = marker_ref;
578 642
579 USED_SPACE(PAD(c->cleanmarker_size)); 643 USED_SPACE(PAD(c->cleanmarker_size));
580 ofs += PAD(c->cleanmarker_size); 644 ofs += PAD(c->cleanmarker_size);
581 } 645 }
582 break; 646 break;
583 647
584 case JFFS2_NODETYPE_PADDING: 648 case JFFS2_NODETYPE_PADDING:
649 if (jffs2_sum_active())
650 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));
585 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 651 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
586 ofs += PAD(je32_to_cpu(node->totlen)); 652 ofs += PAD(je32_to_cpu(node->totlen));
587 break; 653 break;
@@ -616,8 +682,15 @@ scan_more:
616 } 682 }
617 } 683 }
618 684
685 if (jffs2_sum_active()) {
686 if (PAD(s->sum_size + JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size) {
687 dbg_summary("There is not enough space for "
688 "summary information, disabling for this jeb!\n");
689 jffs2_sum_disable_collecting(s);
690 }
691 }
619 692
620 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, 693 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
621 jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size)); 694 jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
622 695
623 /* mark_node_obsolete can add to wasted !! */ 696 /* mark_node_obsolete can add to wasted !! */
@@ -628,24 +701,10 @@ scan_more:
628 jeb->wasted_size = 0; 701 jeb->wasted_size = 0;
629 } 702 }
630 703
631 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 704 return jffs2_scan_classify_jeb(c, jeb);
632 && (!jeb->first_node || !jeb->first_node->next_phys) )
633 return BLK_STATE_CLEANMARKER;
634
635 /* move blocks with max 4 byte dirty space to cleanlist */
636 else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
637 c->dirty_size -= jeb->dirty_size;
638 c->wasted_size += jeb->dirty_size;
639 jeb->wasted_size += jeb->dirty_size;
640 jeb->dirty_size = 0;
641 return BLK_STATE_CLEAN;
642 } else if (jeb->used_size || jeb->unchecked_size)
643 return BLK_STATE_PARTDIRTY;
644 else
645 return BLK_STATE_ALLDIRTY;
646} 705}
647 706
648static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) 707struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
649{ 708{
650 struct jffs2_inode_cache *ic; 709 struct jffs2_inode_cache *ic;
651 710
@@ -671,8 +730,8 @@ static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info
671 return ic; 730 return ic;
672} 731}
673 732
674static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 733static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
675 struct jffs2_raw_inode *ri, uint32_t ofs) 734 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
676{ 735{
677 struct jffs2_raw_node_ref *raw; 736 struct jffs2_raw_node_ref *raw;
678 struct jffs2_inode_cache *ic; 737 struct jffs2_inode_cache *ic;
@@ -681,11 +740,11 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
681 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); 740 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
682 741
683 /* We do very little here now. Just check the ino# to which we should attribute 742 /* We do very little here now. Just check the ino# to which we should attribute
684 this node; we can do all the CRC checking etc. later. There's a tradeoff here -- 743 this node; we can do all the CRC checking etc. later. There's a tradeoff here --
685 we used to scan the flash once only, reading everything we want from it into 744 we used to scan the flash once only, reading everything we want from it into
686 memory, then building all our in-core data structures and freeing the extra 745 memory, then building all our in-core data structures and freeing the extra
687 information. Now we allow the first part of the mount to complete a lot quicker, 746 information. Now we allow the first part of the mount to complete a lot quicker,
688 but we have to go _back_ to the flash in order to finish the CRC checking, etc. 747 but we have to go _back_ to the flash in order to finish the CRC checking, etc.
689 Which means that the _full_ amount of time to get to proper write mode with GC 748 Which means that the _full_ amount of time to get to proper write mode with GC
690 operational may actually be _longer_ than before. Sucks to be me. */ 749 operational may actually be _longer_ than before. Sucks to be me. */
691 750
@@ -731,7 +790,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
731 jeb->last_node->next_phys = raw; 790 jeb->last_node->next_phys = raw;
732 jeb->last_node = raw; 791 jeb->last_node = raw;
733 792
734 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 793 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
735 je32_to_cpu(ri->ino), je32_to_cpu(ri->version), 794 je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
736 je32_to_cpu(ri->offset), 795 je32_to_cpu(ri->offset),
737 je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize))); 796 je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
@@ -739,11 +798,16 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
739 pseudo_random += je32_to_cpu(ri->version); 798 pseudo_random += je32_to_cpu(ri->version);
740 799
741 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen))); 800 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
801
802 if (jffs2_sum_active()) {
803 jffs2_sum_add_inode_mem(s, ri, ofs - jeb->offset);
804 }
805
742 return 0; 806 return 0;
743} 807}
744 808
745static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 809static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
746 struct jffs2_raw_dirent *rd, uint32_t ofs) 810 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
747{ 811{
748 struct jffs2_raw_node_ref *raw; 812 struct jffs2_raw_node_ref *raw;
749 struct jffs2_full_dirent *fd; 813 struct jffs2_full_dirent *fd;
@@ -776,7 +840,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
776 crc = crc32(0, fd->name, rd->nsize); 840 crc = crc32(0, fd->name, rd->nsize);
777 if (crc != je32_to_cpu(rd->name_crc)) { 841 if (crc != je32_to_cpu(rd->name_crc)) {
778 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 842 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
779 ofs, je32_to_cpu(rd->name_crc), crc); 843 ofs, je32_to_cpu(rd->name_crc), crc);
780 D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino))); 844 D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
781 jffs2_free_full_dirent(fd); 845 jffs2_free_full_dirent(fd);
782 /* FIXME: Why do we believe totlen? */ 846 /* FIXME: Why do we believe totlen? */
@@ -796,7 +860,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
796 jffs2_free_raw_node_ref(raw); 860 jffs2_free_raw_node_ref(raw);
797 return -ENOMEM; 861 return -ENOMEM;
798 } 862 }
799 863
800 raw->__totlen = PAD(je32_to_cpu(rd->totlen)); 864 raw->__totlen = PAD(je32_to_cpu(rd->totlen));
801 raw->flash_offset = ofs | REF_PRISTINE; 865 raw->flash_offset = ofs | REF_PRISTINE;
802 raw->next_phys = NULL; 866 raw->next_phys = NULL;
@@ -817,6 +881,10 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
817 USED_SPACE(PAD(je32_to_cpu(rd->totlen))); 881 USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
818 jffs2_add_fd_to_list(c, fd, &ic->scan_dents); 882 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
819 883
884 if (jffs2_sum_active()) {
885 jffs2_sum_add_dirent_mem(s, rd, ofs - jeb->offset);
886 }
887
820 return 0; 888 return 0;
821} 889}
822 890
@@ -852,76 +920,34 @@ void jffs2_rotate_lists(struct jffs2_sb_info *c)
852 x = count_list(&c->clean_list); 920 x = count_list(&c->clean_list);
853 if (x) { 921 if (x) {
854 rotateby = pseudo_random % x; 922 rotateby = pseudo_random % x;
855 D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby));
856
857 rotate_list((&c->clean_list), rotateby); 923 rotate_list((&c->clean_list), rotateby);
858
859 D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n",
860 list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset));
861 } else {
862 D1(printk(KERN_DEBUG "Not rotating empty clean_list\n"));
863 } 924 }
864 925
865 x = count_list(&c->very_dirty_list); 926 x = count_list(&c->very_dirty_list);
866 if (x) { 927 if (x) {
867 rotateby = pseudo_random % x; 928 rotateby = pseudo_random % x;
868 D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby));
869
870 rotate_list((&c->very_dirty_list), rotateby); 929 rotate_list((&c->very_dirty_list), rotateby);
871
872 D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n",
873 list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset));
874 } else {
875 D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n"));
876 } 930 }
877 931
878 x = count_list(&c->dirty_list); 932 x = count_list(&c->dirty_list);
879 if (x) { 933 if (x) {
880 rotateby = pseudo_random % x; 934 rotateby = pseudo_random % x;
881 D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby));
882
883 rotate_list((&c->dirty_list), rotateby); 935 rotate_list((&c->dirty_list), rotateby);
884
885 D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n",
886 list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset));
887 } else {
888 D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n"));
889 } 936 }
890 937
891 x = count_list(&c->erasable_list); 938 x = count_list(&c->erasable_list);
892 if (x) { 939 if (x) {
893 rotateby = pseudo_random % x; 940 rotateby = pseudo_random % x;
894 D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby));
895
896 rotate_list((&c->erasable_list), rotateby); 941 rotate_list((&c->erasable_list), rotateby);
897
898 D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n",
899 list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset));
900 } else {
901 D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n"));
902 } 942 }
903 943
904 if (c->nr_erasing_blocks) { 944 if (c->nr_erasing_blocks) {
905 rotateby = pseudo_random % c->nr_erasing_blocks; 945 rotateby = pseudo_random % c->nr_erasing_blocks;
906 D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby));
907
908 rotate_list((&c->erase_pending_list), rotateby); 946 rotate_list((&c->erase_pending_list), rotateby);
909
910 D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n",
911 list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset));
912 } else {
913 D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n"));
914 } 947 }
915 948
916 if (c->nr_free_blocks) { 949 if (c->nr_free_blocks) {
917 rotateby = pseudo_random % c->nr_free_blocks; 950 rotateby = pseudo_random % c->nr_free_blocks;
918 D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby));
919
920 rotate_list((&c->free_list), rotateby); 951 rotate_list((&c->free_list), rotateby);
921
922 D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n",
923 list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset));
924 } else {
925 D1(printk(KERN_DEBUG "Not rotating empty free_list\n"));
926 } 952 }
927} 953}