2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright © 2001-2007 Red Hat, Inc.
6 * Created by David Woodhouse <dwmw2@infradead.org>
8 * For licensing information, see the file 'LICENCE' in this directory.
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/pagemap.h>
15 #include <linux/crc32.h>
16 #include <linux/jffs2.h>
17 #include <linux/mtd/mtd.h>
21 #ifdef JFFS2_DBG_SANITY_CHECKS
24 __jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info
*c
,
25 struct jffs2_eraseblock
*jeb
)
27 if (unlikely(jeb
&& jeb
->used_size
+ jeb
->dirty_size
+
28 jeb
->free_size
+ jeb
->wasted_size
+
29 jeb
->unchecked_size
!= c
->sector_size
)) {
30 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb
->offset
);
31 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
32 jeb
->free_size
, jeb
->dirty_size
, jeb
->used_size
,
33 jeb
->wasted_size
, jeb
->unchecked_size
, c
->sector_size
);
37 if (unlikely(c
->used_size
+ c
->dirty_size
+ c
->free_size
+ c
->erasing_size
+ c
->bad_size
38 + c
->wasted_size
+ c
->unchecked_size
!= c
->flash_size
)) {
39 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
40 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
41 c
->free_size
, c
->dirty_size
, c
->used_size
, c
->erasing_size
, c
->bad_size
,
42 c
->wasted_size
, c
->unchecked_size
, c
->flash_size
);
48 __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info
*c
,
49 struct jffs2_eraseblock
*jeb
)
51 spin_lock(&c
->erase_completion_lock
);
52 jffs2_dbg_acct_sanity_check_nolock(c
, jeb
);
53 spin_unlock(&c
->erase_completion_lock
);
56 #endif /* JFFS2_DBG_SANITY_CHECKS */
58 #ifdef JFFS2_DBG_PARANOIA_CHECKS
63 __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info
*f
)
66 __jffs2_dbg_fragtree_paranoia_check_nolock(f
);
71 __jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info
*f
)
73 struct jffs2_node_frag
*frag
;
76 for (frag
= frag_first(&f
->fragtree
); frag
; frag
= frag_next(frag
)) {
77 struct jffs2_full_dnode
*fn
= frag
->node
;
82 if (ref_flags(fn
->raw
) == REF_PRISTINE
) {
84 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
85 ref_offset(fn
->raw
), fn
->frags
);
89 /* A hole node which isn't multi-page should be garbage-collected
90 and merged anyway, so we just check for the frag size here,
91 rather than mucking around with actually reading the node
92 and checking the compression type, which is the real way
93 to tell a hole node. */
94 if (frag
->ofs
& (PAGE_CACHE_SIZE
-1) && frag_prev(frag
)
95 && frag_prev(frag
)->size
< PAGE_CACHE_SIZE
&& frag_prev(frag
)->node
) {
96 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
101 if ((frag
->ofs
+frag
->size
) & (PAGE_CACHE_SIZE
-1) && frag_next(frag
)
102 && frag_next(frag
)->size
< PAGE_CACHE_SIZE
&& frag_next(frag
)->node
) {
103 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
104 ref_offset(fn
->raw
), frag
->ofs
, frag
->ofs
+frag
->size
);
111 JFFS2_ERROR("fragtree is corrupted.\n");
112 __jffs2_dbg_dump_fragtree_nolock(f
);
118 * Check if the flash contains all 0xFF before we start writing.
121 __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info
*c
,
122 uint32_t ofs
, int len
)
128 buf
= kmalloc(len
, GFP_KERNEL
);
132 ret
= jffs2_flash_read(c
, ofs
, len
, &retlen
, buf
);
133 if (ret
|| (retlen
!= len
)) {
134 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
141 for (i
= 0; i
< len
; i
++)
146 JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n",
148 __jffs2_dbg_dump_buffer(buf
, len
, ofs
);
157 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
160 __jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info
*c
,
161 struct jffs2_eraseblock
*jeb
)
163 spin_lock(&c
->erase_completion_lock
);
164 __jffs2_dbg_acct_paranoia_check_nolock(c
, jeb
);
165 spin_unlock(&c
->erase_completion_lock
);
169 __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info
*c
,
170 struct jffs2_eraseblock
*jeb
)
172 uint32_t my_used_size
= 0;
173 uint32_t my_unchecked_size
= 0;
174 uint32_t my_dirty_size
= 0;
175 struct jffs2_raw_node_ref
*ref2
= jeb
->first_node
;
178 uint32_t totlen
= ref_totlen(c
, jeb
, ref2
);
180 if (ref_offset(ref2
) < jeb
->offset
||
181 ref_offset(ref2
) > jeb
->offset
+ c
->sector_size
) {
182 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
183 ref_offset(ref2
), jeb
->offset
);
187 if (ref_flags(ref2
) == REF_UNCHECKED
)
188 my_unchecked_size
+= totlen
;
189 else if (!ref_obsolete(ref2
))
190 my_used_size
+= totlen
;
192 my_dirty_size
+= totlen
;
194 if ((!ref_next(ref2
)) != (ref2
== jeb
->last_node
)) {
195 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
196 ref_offset(ref2
), ref2
, ref_offset(ref_next(ref2
)), ref_next(ref2
),
197 ref_offset(jeb
->last_node
), jeb
->last_node
);
200 ref2
= ref_next(ref2
);
203 if (my_used_size
!= jeb
->used_size
) {
204 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
205 my_used_size
, jeb
->used_size
);
209 if (my_unchecked_size
!= jeb
->unchecked_size
) {
210 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
211 my_unchecked_size
, jeb
->unchecked_size
);
216 /* This should work when we implement ref->__totlen elemination */
217 if (my_dirty_size
!= jeb
->dirty_size
+ jeb
->wasted_size
) {
218 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
219 my_dirty_size
, jeb
->dirty_size
+ jeb
->wasted_size
);
223 if (jeb
->free_size
== 0
224 && my_used_size
+ my_unchecked_size
+ my_dirty_size
!= c
->sector_size
) {
225 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
226 my_used_size
+ my_unchecked_size
+ my_dirty_size
,
235 __jffs2_dbg_dump_node_refs_nolock(c
, jeb
);
236 __jffs2_dbg_dump_jeb_nolock(jeb
);
237 __jffs2_dbg_dump_block_lists_nolock(c
);
241 #endif /* JFFS2_DBG_PARANOIA_CHECKS */
243 #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
245 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
248 __jffs2_dbg_dump_node_refs(struct jffs2_sb_info
*c
,
249 struct jffs2_eraseblock
*jeb
)
251 spin_lock(&c
->erase_completion_lock
);
252 __jffs2_dbg_dump_node_refs_nolock(c
, jeb
);
253 spin_unlock(&c
->erase_completion_lock
);
257 __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info
*c
,
258 struct jffs2_eraseblock
*jeb
)
260 struct jffs2_raw_node_ref
*ref
;
263 printk(JFFS2_DBG_MSG_PREFIX
" Dump node_refs of the eraseblock %#08x\n", jeb
->offset
);
264 if (!jeb
->first_node
) {
265 printk(JFFS2_DBG_MSG_PREFIX
" no nodes in the eraseblock %#08x\n", jeb
->offset
);
270 for (ref
= jeb
->first_node
; ; ref
= ref_next(ref
)) {
271 printk("%#08x(%#x)", ref_offset(ref
), ref
->__totlen
);
278 printk("\n" JFFS2_DBG
);
285 * Dump an eraseblock's space accounting.
288 __jffs2_dbg_dump_jeb(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
)
290 spin_lock(&c
->erase_completion_lock
);
291 __jffs2_dbg_dump_jeb_nolock(jeb
);
292 spin_unlock(&c
->erase_completion_lock
);
296 __jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock
*jeb
)
301 printk(JFFS2_DBG_MSG_PREFIX
" dump space accounting for the eraseblock at %#08x:\n",
304 printk(JFFS2_DBG
"used_size: %#08x\n", jeb
->used_size
);
305 printk(JFFS2_DBG
"dirty_size: %#08x\n", jeb
->dirty_size
);
306 printk(JFFS2_DBG
"wasted_size: %#08x\n", jeb
->wasted_size
);
307 printk(JFFS2_DBG
"unchecked_size: %#08x\n", jeb
->unchecked_size
);
308 printk(JFFS2_DBG
"free_size: %#08x\n", jeb
->free_size
);
312 __jffs2_dbg_dump_block_lists(struct jffs2_sb_info
*c
)
314 spin_lock(&c
->erase_completion_lock
);
315 __jffs2_dbg_dump_block_lists_nolock(c
);
316 spin_unlock(&c
->erase_completion_lock
);
320 __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info
*c
)
322 printk(JFFS2_DBG_MSG_PREFIX
" dump JFFS2 blocks lists:\n");
324 printk(JFFS2_DBG
"flash_size: %#08x\n", c
->flash_size
);
325 printk(JFFS2_DBG
"used_size: %#08x\n", c
->used_size
);
326 printk(JFFS2_DBG
"dirty_size: %#08x\n", c
->dirty_size
);
327 printk(JFFS2_DBG
"wasted_size: %#08x\n", c
->wasted_size
);
328 printk(JFFS2_DBG
"unchecked_size: %#08x\n", c
->unchecked_size
);
329 printk(JFFS2_DBG
"free_size: %#08x\n", c
->free_size
);
330 printk(JFFS2_DBG
"erasing_size: %#08x\n", c
->erasing_size
);
331 printk(JFFS2_DBG
"bad_size: %#08x\n", c
->bad_size
);
332 printk(JFFS2_DBG
"sector_size: %#08x\n", c
->sector_size
);
333 printk(JFFS2_DBG
"jffs2_reserved_blocks size: %#08x\n",
334 c
->sector_size
* c
->resv_blocks_write
);
337 printk(JFFS2_DBG
"nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
338 c
->nextblock
->offset
, c
->nextblock
->used_size
,
339 c
->nextblock
->dirty_size
, c
->nextblock
->wasted_size
,
340 c
->nextblock
->unchecked_size
, c
->nextblock
->free_size
);
342 printk(JFFS2_DBG
"nextblock: NULL\n");
345 printk(JFFS2_DBG
"gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
346 c
->gcblock
->offset
, c
->gcblock
->used_size
, c
->gcblock
->dirty_size
,
347 c
->gcblock
->wasted_size
, c
->gcblock
->unchecked_size
, c
->gcblock
->free_size
);
349 printk(JFFS2_DBG
"gcblock: NULL\n");
351 if (list_empty(&c
->clean_list
)) {
352 printk(JFFS2_DBG
"clean_list: empty\n");
354 struct list_head
*this;
358 list_for_each(this, &c
->clean_list
) {
359 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
361 dirty
+= jeb
->wasted_size
;
362 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
363 printk(JFFS2_DBG
"clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
364 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
365 jeb
->unchecked_size
, jeb
->free_size
);
369 printk (JFFS2_DBG
"Contains %d blocks with total wasted size %u, average wasted size: %u\n",
370 numblocks
, dirty
, dirty
/ numblocks
);
373 if (list_empty(&c
->very_dirty_list
)) {
374 printk(JFFS2_DBG
"very_dirty_list: empty\n");
376 struct list_head
*this;
380 list_for_each(this, &c
->very_dirty_list
) {
381 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
384 dirty
+= jeb
->dirty_size
;
385 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
386 printk(JFFS2_DBG
"very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
387 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
388 jeb
->unchecked_size
, jeb
->free_size
);
392 printk (JFFS2_DBG
"Contains %d blocks with total dirty size %u, average dirty size: %u\n",
393 numblocks
, dirty
, dirty
/ numblocks
);
396 if (list_empty(&c
->dirty_list
)) {
397 printk(JFFS2_DBG
"dirty_list: empty\n");
399 struct list_head
*this;
403 list_for_each(this, &c
->dirty_list
) {
404 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
407 dirty
+= jeb
->dirty_size
;
408 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
409 printk(JFFS2_DBG
"dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
410 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
411 jeb
->unchecked_size
, jeb
->free_size
);
415 printk (JFFS2_DBG
"contains %d blocks with total dirty size %u, average dirty size: %u\n",
416 numblocks
, dirty
, dirty
/ numblocks
);
419 if (list_empty(&c
->erasable_list
)) {
420 printk(JFFS2_DBG
"erasable_list: empty\n");
422 struct list_head
*this;
424 list_for_each(this, &c
->erasable_list
) {
425 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
427 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
428 printk(JFFS2_DBG
"erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
429 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
430 jeb
->unchecked_size
, jeb
->free_size
);
435 if (list_empty(&c
->erasing_list
)) {
436 printk(JFFS2_DBG
"erasing_list: empty\n");
438 struct list_head
*this;
440 list_for_each(this, &c
->erasing_list
) {
441 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
443 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
444 printk(JFFS2_DBG
"erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
445 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
446 jeb
->unchecked_size
, jeb
->free_size
);
451 if (list_empty(&c
->erase_pending_list
)) {
452 printk(JFFS2_DBG
"erase_pending_list: empty\n");
454 struct list_head
*this;
456 list_for_each(this, &c
->erase_pending_list
) {
457 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
459 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
460 printk(JFFS2_DBG
"erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
461 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
462 jeb
->unchecked_size
, jeb
->free_size
);
467 if (list_empty(&c
->erasable_pending_wbuf_list
)) {
468 printk(JFFS2_DBG
"erasable_pending_wbuf_list: empty\n");
470 struct list_head
*this;
472 list_for_each(this, &c
->erasable_pending_wbuf_list
) {
473 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
475 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
476 printk(JFFS2_DBG
"erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
477 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
478 jeb
->unchecked_size
, jeb
->free_size
);
483 if (list_empty(&c
->free_list
)) {
484 printk(JFFS2_DBG
"free_list: empty\n");
486 struct list_head
*this;
488 list_for_each(this, &c
->free_list
) {
489 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
491 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
492 printk(JFFS2_DBG
"free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
493 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
494 jeb
->unchecked_size
, jeb
->free_size
);
499 if (list_empty(&c
->bad_list
)) {
500 printk(JFFS2_DBG
"bad_list: empty\n");
502 struct list_head
*this;
504 list_for_each(this, &c
->bad_list
) {
505 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
507 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
508 printk(JFFS2_DBG
"bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
509 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
510 jeb
->unchecked_size
, jeb
->free_size
);
515 if (list_empty(&c
->bad_used_list
)) {
516 printk(JFFS2_DBG
"bad_used_list: empty\n");
518 struct list_head
*this;
520 list_for_each(this, &c
->bad_used_list
) {
521 struct jffs2_eraseblock
*jeb
= list_entry(this, struct jffs2_eraseblock
, list
);
523 if (!(jeb
->used_size
== 0 && jeb
->dirty_size
== 0 && jeb
->wasted_size
== 0)) {
524 printk(JFFS2_DBG
"bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
525 jeb
->offset
, jeb
->used_size
, jeb
->dirty_size
, jeb
->wasted_size
,
526 jeb
->unchecked_size
, jeb
->free_size
);
533 __jffs2_dbg_dump_fragtree(struct jffs2_inode_info
*f
)
536 jffs2_dbg_dump_fragtree_nolock(f
);
541 __jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info
*f
)
543 struct jffs2_node_frag
*this = frag_first(&f
->fragtree
);
544 uint32_t lastofs
= 0;
547 printk(JFFS2_DBG_MSG_PREFIX
" dump fragtree of ino #%u\n", f
->inocache
->ino
);
550 printk(JFFS2_DBG
"frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
551 this->ofs
, this->ofs
+this->size
, ref_offset(this->node
->raw
),
552 ref_flags(this->node
->raw
), this, frag_left(this), frag_right(this),
555 printk(JFFS2_DBG
"frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
556 this->ofs
, this->ofs
+this->size
, this, frag_left(this),
557 frag_right(this), frag_parent(this));
558 if (this->ofs
!= lastofs
)
560 lastofs
= this->ofs
+ this->size
;
561 this = frag_next(this);
565 printk(JFFS2_DBG
"metadata at 0x%08x\n", ref_offset(f
->metadata
->raw
));
568 JFFS2_ERROR("frag tree got a hole in it.\n");
573 #define JFFS2_BUFDUMP_BYTES_PER_LINE 32
575 __jffs2_dbg_dump_buffer(unsigned char *buf
, int len
, uint32_t offs
)
580 printk(JFFS2_DBG_MSG_PREFIX
" dump from offset %#08x to offset %#08x (%x bytes).\n",
581 offs
, offs
+ len
, len
);
582 i
= skip
= offs
% JFFS2_BUFDUMP_BYTES_PER_LINE
;
583 offs
= offs
& ~(JFFS2_BUFDUMP_BYTES_PER_LINE
- 1);
586 printk(JFFS2_DBG
"%#08x: ", offs
);
592 if ((i
% JFFS2_BUFDUMP_BYTES_PER_LINE
) == 0 && i
!= len
-1) {
595 offs
+= JFFS2_BUFDUMP_BYTES_PER_LINE
;
596 printk(JFFS2_DBG
"%0#8x: ", offs
);
599 printk("%02x ", buf
[i
]);
611 __jffs2_dbg_dump_node(struct jffs2_sb_info
*c
, uint32_t ofs
)
613 union jffs2_node_union node
;
614 int len
= sizeof(union jffs2_node_union
);
619 printk(JFFS2_DBG_MSG_PREFIX
" dump node at offset %#08x.\n", ofs
);
621 ret
= jffs2_flash_read(c
, ofs
, len
, &retlen
, (unsigned char *)&node
);
622 if (ret
|| (retlen
!= len
)) {
623 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
628 printk(JFFS2_DBG
"magic:\t%#04x\n", je16_to_cpu(node
.u
.magic
));
629 printk(JFFS2_DBG
"nodetype:\t%#04x\n", je16_to_cpu(node
.u
.nodetype
));
630 printk(JFFS2_DBG
"totlen:\t%#08x\n", je32_to_cpu(node
.u
.totlen
));
631 printk(JFFS2_DBG
"hdr_crc:\t%#08x\n", je32_to_cpu(node
.u
.hdr_crc
));
633 crc
= crc32(0, &node
.u
, sizeof(node
.u
) - 4);
634 if (crc
!= je32_to_cpu(node
.u
.hdr_crc
)) {
635 JFFS2_ERROR("wrong common header CRC.\n");
639 if (je16_to_cpu(node
.u
.magic
) != JFFS2_MAGIC_BITMASK
&&
640 je16_to_cpu(node
.u
.magic
) != JFFS2_OLD_MAGIC_BITMASK
)
642 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
643 je16_to_cpu(node
.u
.magic
), JFFS2_MAGIC_BITMASK
);
647 switch(je16_to_cpu(node
.u
.nodetype
)) {
649 case JFFS2_NODETYPE_INODE
:
651 printk(JFFS2_DBG
"the node is inode node\n");
652 printk(JFFS2_DBG
"ino:\t%#08x\n", je32_to_cpu(node
.i
.ino
));
653 printk(JFFS2_DBG
"version:\t%#08x\n", je32_to_cpu(node
.i
.version
));
654 printk(JFFS2_DBG
"mode:\t%#08x\n", node
.i
.mode
.m
);
655 printk(JFFS2_DBG
"uid:\t%#04x\n", je16_to_cpu(node
.i
.uid
));
656 printk(JFFS2_DBG
"gid:\t%#04x\n", je16_to_cpu(node
.i
.gid
));
657 printk(JFFS2_DBG
"isize:\t%#08x\n", je32_to_cpu(node
.i
.isize
));
658 printk(JFFS2_DBG
"atime:\t%#08x\n", je32_to_cpu(node
.i
.atime
));
659 printk(JFFS2_DBG
"mtime:\t%#08x\n", je32_to_cpu(node
.i
.mtime
));
660 printk(JFFS2_DBG
"ctime:\t%#08x\n", je32_to_cpu(node
.i
.ctime
));
661 printk(JFFS2_DBG
"offset:\t%#08x\n", je32_to_cpu(node
.i
.offset
));
662 printk(JFFS2_DBG
"csize:\t%#08x\n", je32_to_cpu(node
.i
.csize
));
663 printk(JFFS2_DBG
"dsize:\t%#08x\n", je32_to_cpu(node
.i
.dsize
));
664 printk(JFFS2_DBG
"compr:\t%#02x\n", node
.i
.compr
);
665 printk(JFFS2_DBG
"usercompr:\t%#02x\n", node
.i
.usercompr
);
666 printk(JFFS2_DBG
"flags:\t%#04x\n", je16_to_cpu(node
.i
.flags
));
667 printk(JFFS2_DBG
"data_crc:\t%#08x\n", je32_to_cpu(node
.i
.data_crc
));
668 printk(JFFS2_DBG
"node_crc:\t%#08x\n", je32_to_cpu(node
.i
.node_crc
));
670 crc
= crc32(0, &node
.i
, sizeof(node
.i
) - 8);
671 if (crc
!= je32_to_cpu(node
.i
.node_crc
)) {
672 JFFS2_ERROR("wrong node header CRC.\n");
677 case JFFS2_NODETYPE_DIRENT
:
679 printk(JFFS2_DBG
"the node is dirent node\n");
680 printk(JFFS2_DBG
"pino:\t%#08x\n", je32_to_cpu(node
.d
.pino
));
681 printk(JFFS2_DBG
"version:\t%#08x\n", je32_to_cpu(node
.d
.version
));
682 printk(JFFS2_DBG
"ino:\t%#08x\n", je32_to_cpu(node
.d
.ino
));
683 printk(JFFS2_DBG
"mctime:\t%#08x\n", je32_to_cpu(node
.d
.mctime
));
684 printk(JFFS2_DBG
"nsize:\t%#02x\n", node
.d
.nsize
);
685 printk(JFFS2_DBG
"type:\t%#02x\n", node
.d
.type
);
686 printk(JFFS2_DBG
"node_crc:\t%#08x\n", je32_to_cpu(node
.d
.node_crc
));
687 printk(JFFS2_DBG
"name_crc:\t%#08x\n", je32_to_cpu(node
.d
.name_crc
));
689 node
.d
.name
[node
.d
.nsize
] = '\0';
690 printk(JFFS2_DBG
"name:\t\"%s\"\n", node
.d
.name
);
692 crc
= crc32(0, &node
.d
, sizeof(node
.d
) - 8);
693 if (crc
!= je32_to_cpu(node
.d
.node_crc
)) {
694 JFFS2_ERROR("wrong node header CRC.\n");
700 printk(JFFS2_DBG
"node type is unknown\n");
704 #endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */