diff options
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 300 |
1 files changed, 163 insertions, 137 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index b63160f83bab..0e7456ec99fd 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 @@ | |||
47 | static uint32_t pseudo_random; | 36 | static uint32_t pseudo_random; |
48 | 37 | ||
49 | static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 38 | static 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 | */ |
56 | static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 45 | static 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); |
58 | static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 47 | static 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 | ||
68 | static inline int min_free(struct jffs2_sb_info *c) | 50 | static 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 | ||
268 | static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf, | 272 | int 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 | ||
293 | int 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 | |||
289 | static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 312 | static 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 | ||
370 | scan_more: | 432 | dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset); |
433 | |||
434 | scan_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 | ||
648 | static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) | 707 | struct 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 | ||
674 | static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 733 | static 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 | ||
745 | static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 809 | static 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 | } |