Blame view

fs/jffs2/debug.c 25.6 KB
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
1
2
3
  /*
   * JFFS2 -- Journalling Flash File System, Version 2.
   *
c00c310ea   David Woodhouse   [JFFS2] Tidy up l...
4
   * Copyright © 2001-2007 Red Hat, Inc.
6088c0587   David Woodhouse   jffs2: Update cop...
5
   * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
6
7
8
9
10
   *
   * Created by David Woodhouse <dwmw2@infradead.org>
   *
   * For licensing information, see the file 'LICENCE' in this directory.
   *
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
11
   */
c00c310ea   David Woodhouse   [JFFS2] Tidy up l...
12

730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
13
  #include <linux/kernel.h>
737b7661e   Andrew Lunn   [JFFS2] Fix up ne...
14
  #include <linux/types.h>
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
15
  #include <linux/pagemap.h>
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
16
17
  #include <linux/crc32.h>
  #include <linux/jffs2.h>
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
18
  #include <linux/mtd/mtd.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
19
  #include <linux/slab.h>
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
20
21
  #include "nodelist.h"
  #include "debug.h"
45ca1b509   Artem B. Bityutskiy   [JFFS2] Debug cod...
22
23
24
25
26
27
28
29
30
31
32
  #ifdef JFFS2_DBG_SANITY_CHECKS
  
  void
  __jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
  				     struct jffs2_eraseblock *jeb)
  {
  	if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
  			jeb->free_size + jeb->wasted_size +
  			jeb->unchecked_size != c->sector_size)) {
  		JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.
  ", jeb->offset);
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
33
34
35
  		JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.
  ",
  			jeb->free_size, jeb->dirty_size, jeb->used_size,
45ca1b509   Artem B. Bityutskiy   [JFFS2] Debug cod...
36
37
38
39
40
41
42
43
  			jeb->wasted_size, jeb->unchecked_size, c->sector_size);
  		BUG();
  	}
  
  	if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
  				+ c->wasted_size + c->unchecked_size != c->flash_size)) {
  		JFFS2_ERROR("eeep, space accounting superblock info is screwed.
  ");
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
44
45
  		JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.
  ",
45ca1b509   Artem B. Bityutskiy   [JFFS2] Debug cod...
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  			c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
  			c->wasted_size, c->unchecked_size, c->flash_size);
  		BUG();
  	}
  }
  
  void
  __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
  			      struct jffs2_eraseblock *jeb)
  {
  	spin_lock(&c->erase_completion_lock);
  	jffs2_dbg_acct_sanity_check_nolock(c, jeb);
  	spin_unlock(&c->erase_completion_lock);
  }
  
  #endif /* JFFS2_DBG_SANITY_CHECKS */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
62
  #ifdef JFFS2_DBG_PARANOIA_CHECKS
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
63
64
65
  /*
   * Check the fragtree.
   */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
66
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
67
68
  __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
  {
ced220703   David Woodhouse   [JFFS2] semaphore...
69
  	mutex_lock(&f->sem);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
70
  	__jffs2_dbg_fragtree_paranoia_check_nolock(f);
ced220703   David Woodhouse   [JFFS2] semaphore...
71
  	mutex_unlock(&f->sem);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
72
  }
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
73

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
74
75
  void
  __jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
76
77
78
79
80
81
82
83
84
85
86
87
  {
  	struct jffs2_node_frag *frag;
  	int bitched = 0;
  
  	for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
  		struct jffs2_full_dnode *fn = frag->node;
  
  		if (!fn || !fn->raw)
  			continue;
  
  		if (ref_flags(fn->raw) == REF_PRISTINE) {
  			if (fn->frags > 1) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
88
89
  				JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.
  ",
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
90
  					ref_offset(fn->raw), fn->frags);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
91
92
93
94
95
96
97
98
99
100
  				bitched = 1;
  			}
  
  			/* A hole node which isn't multi-page should be garbage-collected
  			   and merged anyway, so we just check for the frag size here,
  			   rather than mucking around with actually reading the node
  			   and checking the compression type, which is the real way
  			   to tell a hole node. */
  			if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
  					&& frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
101
102
103
  				JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.
  ",
  					ref_offset(fn->raw));
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
104
105
106
107
108
  				bitched = 1;
  			}
  
  			if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
  					&& frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
109
110
111
  				JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.
  ",
  				       ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
112
113
114
115
116
117
  				bitched = 1;
  			}
  		}
  	}
  
  	if (bitched) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
118
119
120
  		JFFS2_ERROR("fragtree is corrupted.
  ");
  		__jffs2_dbg_dump_fragtree_nolock(f);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
121
122
123
124
125
126
127
128
  		BUG();
  	}
  }
  
  /*
   * Check if the flash contains all 0xFF before we start writing.
   */
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
129
130
  __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
  				    uint32_t ofs, int len)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
131
132
133
134
135
136
137
138
139
140
141
  {
  	size_t retlen;
  	int ret, i;
  	unsigned char *buf;
  
  	buf = kmalloc(len, GFP_KERNEL);
  	if (!buf)
  		return;
  
  	ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
  	if (ret || (retlen != len)) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
142
143
144
  		JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.
  ",
  				len, ret, retlen);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
145
146
147
148
149
150
151
152
153
154
  		kfree(buf);
  		return;
  	}
  
  	ret = 0;
  	for (i = 0; i < len; i++)
  		if (buf[i] != 0xff)
  			ret = 1;
  
  	if (ret) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
155
156
157
  		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.
  ",
  			ofs, ofs + i);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
158
  		__jffs2_dbg_dump_buffer(buf, len, ofs);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
159
160
161
162
163
164
  		kfree(buf);
  		BUG();
  	}
  
  	kfree(buf);
  }
85a62db62   David Woodhouse   [JFFS2] Add paran...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
  {
  	struct jffs2_eraseblock *jeb;
  	uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
  		erasing = 0, bad = 0, unchecked = 0;
  	int nr_counted = 0;
  	int dump = 0;
  
  	if (c->gcblock) {
  		nr_counted++;
  		free += c->gcblock->free_size;
  		dirty += c->gcblock->dirty_size;
  		used += c->gcblock->used_size;
  		wasted += c->gcblock->wasted_size;
  		unchecked += c->gcblock->unchecked_size;
  	}
  	if (c->nextblock) {
  		nr_counted++;
  		free += c->nextblock->free_size;
  		dirty += c->nextblock->dirty_size;
  		used += c->nextblock->used_size;
  		wasted += c->nextblock->wasted_size;
  		unchecked += c->nextblock->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->clean_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->very_dirty_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->dirty_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->erasable_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->erase_pending_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->free_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  	list_for_each_entry(jeb, &c->bad_used_list, list) {
  		nr_counted++;
  		free += jeb->free_size;
  		dirty += jeb->dirty_size;
  		used += jeb->used_size;
  		wasted += jeb->wasted_size;
  		unchecked += jeb->unchecked_size;
  	}
  
  	list_for_each_entry(jeb, &c->erasing_list, list) {
  		nr_counted++;
  		erasing += c->sector_size;
  	}
e2bc322bf   David Woodhouse   [JFFS2] Add erase...
258
259
260
261
  	list_for_each_entry(jeb, &c->erase_checking_list, list) {
  		nr_counted++;
  		erasing += c->sector_size;
  	}
85a62db62   David Woodhouse   [JFFS2] Add paran...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  	list_for_each_entry(jeb, &c->erase_complete_list, list) {
  		nr_counted++;
  		erasing += c->sector_size;
  	}
  	list_for_each_entry(jeb, &c->bad_list, list) {
  		nr_counted++;
  		bad += c->sector_size;
  	}
  
  #define check(sz) \
  	if (sz != c->sz##_size) {			\
  		printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x
  ", \
  		       sz, c->sz##_size);		\
  		dump = 1;				\
  	}
  	check(free);
  	check(dirty);
  	check(used);
  	check(wasted);
  	check(unchecked);
  	check(bad);
  	check(erasing);
  #undef check
  
  	if (nr_counted != c->nr_blocks) {
  		printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?
  ",
  		       __func__, nr_counted, c->nr_blocks);
  		dump = 1;
  	}
  
  	if (dump) {
  		__jffs2_dbg_dump_block_lists_nolock(c);
  		BUG();
  	}
  }
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
299
300
301
302
  /*
   * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
   */
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
303
304
305
306
307
308
309
  __jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
  				struct jffs2_eraseblock *jeb)
  {
  	spin_lock(&c->erase_completion_lock);
  	__jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
  	spin_unlock(&c->erase_completion_lock);
  }
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
310

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
311
312
313
  void
  __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
  				       struct jffs2_eraseblock *jeb)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
314
315
316
317
318
319
320
321
  {
  	uint32_t my_used_size = 0;
  	uint32_t my_unchecked_size = 0;
  	uint32_t my_dirty_size = 0;
  	struct jffs2_raw_node_ref *ref2 = jeb->first_node;
  
  	while (ref2) {
  		uint32_t totlen = ref_totlen(c, jeb, ref2);
abb536e7a   Kyungmin Park   [JFFS2] use the r...
322
323
  		if (ref_offset(ref2) < jeb->offset ||
  				ref_offset(ref2) > jeb->offset + c->sector_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
324
325
  			JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
326
  				ref_offset(ref2), jeb->offset);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
327
  			goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
328
329
330
331
332
333
334
335
  
  		}
  		if (ref_flags(ref2) == REF_UNCHECKED)
  			my_unchecked_size += totlen;
  		else if (!ref_obsolete(ref2))
  			my_used_size += totlen;
  		else
  			my_dirty_size += totlen;
99988f7bb   David Woodhouse   [JFFS2] Introduce...
336
337
338
339
340
  		if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
  			JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).
  ",
  				    ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
  				    ref_offset(jeb->last_node), jeb->last_node);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
341
  			goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
342
  		}
99988f7bb   David Woodhouse   [JFFS2] Introduce...
343
  		ref2 = ref_next(ref2);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
344
345
346
  	}
  
  	if (my_used_size != jeb->used_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
347
348
349
350
  		JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.
  ",
  			my_used_size, jeb->used_size);
  		goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
351
352
353
  	}
  
  	if (my_unchecked_size != jeb->unchecked_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
354
355
356
357
  		JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.
  ",
  			my_unchecked_size, jeb->unchecked_size);
  		goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
358
  	}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
359
360
  #if 0
  	/* This should work when we implement ref->__totlen elemination */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
361
  	if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
362
363
  		JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
364
  			my_dirty_size, jeb->dirty_size + jeb->wasted_size);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
365
  		goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
366
367
368
369
  	}
  
  	if (jeb->free_size == 0
  		&& my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
370
371
  		JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
372
373
  			my_used_size + my_unchecked_size + my_dirty_size,
  			c->sector_size);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
374
  		goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
375
  	}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
376
  #endif
85a62db62   David Woodhouse   [JFFS2] Add paran...
377
378
  	if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
  		__jffs2_dbg_superblock_counts(c);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
379
380
381
382
383
384
385
  	return;
  
  error:
  	__jffs2_dbg_dump_node_refs_nolock(c, jeb);
  	__jffs2_dbg_dump_jeb_nolock(jeb);
  	__jffs2_dbg_dump_block_lists_nolock(c);
  	BUG();
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
386

730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
387
  }
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
388
  #endif /* JFFS2_DBG_PARANOIA_CHECKS */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
389

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
390
  #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
391
392
393
394
  /*
   * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
   */
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
395
396
397
398
399
400
401
402
403
404
405
  __jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
  			   struct jffs2_eraseblock *jeb)
  {
  	spin_lock(&c->erase_completion_lock);
  	__jffs2_dbg_dump_node_refs_nolock(c, jeb);
  	spin_unlock(&c->erase_completion_lock);
  }
  
  void
  __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
  				  struct jffs2_eraseblock *jeb)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
406
407
408
  {
  	struct jffs2_raw_node_ref *ref;
  	int i = 0;
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
409
410
  	printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x
  ", jeb->offset);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
411
  	if (!jeb->first_node) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
412
413
  		printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x
  ", jeb->offset);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
414
415
  		return;
  	}
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
416
  	printk(JFFS2_DBG);
99988f7bb   David Woodhouse   [JFFS2] Introduce...
417
  	for (ref = jeb->first_node; ; ref = ref_next(ref)) {
27e6b8e38   David Woodhouse   [JFFS2] Honour TE...
418
419
420
421
  		printk("%#08x", ref_offset(ref));
  #ifdef TEST_TOTLEN
  		printk("(%x)", ref->__totlen);
  #endif
99988f7bb   David Woodhouse   [JFFS2] Introduce...
422
  		if (ref_next(ref))
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
423
424
425
426
427
  			printk("->");
  		else
  			break;
  		if (++i == 4) {
  			i = 0;
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
428
429
  			printk("
  " JFFS2_DBG);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
430
431
432
433
434
  		}
  	}
  	printk("
  ");
  }
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
435
436
437
438
439
440
441
442
443
444
  /*
   * Dump an eraseblock's space accounting.
   */
  void
  __jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
  {
  	spin_lock(&c->erase_completion_lock);
  	__jffs2_dbg_dump_jeb_nolock(jeb);
  	spin_unlock(&c->erase_completion_lock);
  }
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
445
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
446
  __jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
447
  {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
448
449
  	if (!jeb)
  		return;
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
450
451
  	printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
452
  			jeb->offset);
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
453
454
455
456
457
458
459
460
461
462
  	printk(JFFS2_DBG "used_size: %#08x
  ",		jeb->used_size);
  	printk(JFFS2_DBG "dirty_size: %#08x
  ",		jeb->dirty_size);
  	printk(JFFS2_DBG "wasted_size: %#08x
  ",	jeb->wasted_size);
  	printk(JFFS2_DBG "unchecked_size: %#08x
  ",	jeb->unchecked_size);
  	printk(JFFS2_DBG "free_size: %#08x
  ",		jeb->free_size);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
463
464
465
466
467
468
469
470
471
472
473
474
475
  }
  
  void
  __jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
  {
  	spin_lock(&c->erase_completion_lock);
  	__jffs2_dbg_dump_block_lists_nolock(c);
  	spin_unlock(&c->erase_completion_lock);
  }
  
  void
  __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
  {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
476
477
  	printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:
  ");
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
478

81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
  	printk(JFFS2_DBG "flash_size: %#08x
  ",		c->flash_size);
  	printk(JFFS2_DBG "used_size: %#08x
  ",		c->used_size);
  	printk(JFFS2_DBG "dirty_size: %#08x
  ",		c->dirty_size);
  	printk(JFFS2_DBG "wasted_size: %#08x
  ",	c->wasted_size);
  	printk(JFFS2_DBG "unchecked_size: %#08x
  ",	c->unchecked_size);
  	printk(JFFS2_DBG "free_size: %#08x
  ",		c->free_size);
  	printk(JFFS2_DBG "erasing_size: %#08x
  ",	c->erasing_size);
  	printk(JFFS2_DBG "bad_size: %#08x
  ",		c->bad_size);
  	printk(JFFS2_DBG "sector_size: %#08x
  ",	c->sector_size);
  	printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
499
500
501
  				c->sector_size * c->resv_blocks_write);
  
  	if (c->nextblock)
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
502
503
  		printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
504
505
506
  			c->nextblock->offset, c->nextblock->used_size,
  			c->nextblock->dirty_size, c->nextblock->wasted_size,
  			c->nextblock->unchecked_size, c->nextblock->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
507
  	else
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
508
509
  		printk(JFFS2_DBG "nextblock: NULL
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
510
511
  
  	if (c->gcblock)
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
512
513
  		printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
514
515
  			c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
  			c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
516
  	else
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
517
518
  		printk(JFFS2_DBG "gcblock: NULL
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
519
520
  
  	if (list_empty(&c->clean_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
521
522
  		printk(JFFS2_DBG "clean_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
523
524
525
526
527
528
529
530
531
532
  	} else {
  		struct list_head *this;
  		int numblocks = 0;
  		uint32_t dirty = 0;
  
  		list_for_each(this, &c->clean_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  			numblocks ++;
  			dirty += jeb->wasted_size;
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
533
534
  				printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
535
536
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
537
538
  			}
  		}
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
539
540
  		printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
541
  			numblocks, dirty, dirty / numblocks);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
542
543
544
  	}
  
  	if (list_empty(&c->very_dirty_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
545
546
  		printk(JFFS2_DBG "very_dirty_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
547
548
549
550
551
552
553
554
555
556
557
  	} else {
  		struct list_head *this;
  		int numblocks = 0;
  		uint32_t dirty = 0;
  
  		list_for_each(this, &c->very_dirty_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			numblocks ++;
  			dirty += jeb->dirty_size;
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
558
559
  				printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
560
561
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
562
563
  			}
  		}
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
564
565
  		printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
566
  			numblocks, dirty, dirty / numblocks);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
567
568
569
  	}
  
  	if (list_empty(&c->dirty_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
570
571
  		printk(JFFS2_DBG "dirty_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
572
573
574
575
576
577
578
579
580
581
582
  	} else {
  		struct list_head *this;
  		int numblocks = 0;
  		uint32_t dirty = 0;
  
  		list_for_each(this, &c->dirty_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			numblocks ++;
  			dirty += jeb->dirty_size;
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
583
584
  				printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
585
586
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
587
588
  			}
  		}
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
589
590
  		printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
591
592
593
594
  			numblocks, dirty, dirty / numblocks);
  	}
  
  	if (list_empty(&c->erasable_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
595
596
  		printk(JFFS2_DBG "erasable_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
597
598
599
600
601
602
603
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->erasable_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
604
605
  				printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
606
607
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
608
609
610
611
612
  			}
  		}
  	}
  
  	if (list_empty(&c->erasing_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
613
614
  		printk(JFFS2_DBG "erasing_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
615
616
617
618
619
620
621
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->erasing_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
622
623
  				printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
624
625
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
626
627
628
  			}
  		}
  	}
e2bc322bf   David Woodhouse   [JFFS2] Add erase...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  	if (list_empty(&c->erase_checking_list)) {
  		printk(JFFS2_DBG "erase_checking_list: empty
  ");
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->erase_checking_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
  				printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
  			}
  		}
  	}
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
646
647
  
  	if (list_empty(&c->erase_pending_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
648
649
  		printk(JFFS2_DBG "erase_pending_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
650
651
652
653
654
655
656
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->erase_pending_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
657
658
  				printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
659
660
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
661
662
663
664
665
  			}
  		}
  	}
  
  	if (list_empty(&c->erasable_pending_wbuf_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
666
667
  		printk(JFFS2_DBG "erasable_pending_wbuf_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
668
669
670
671
672
673
674
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->erasable_pending_wbuf_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
675
676
  				printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
677
678
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
679
680
681
682
683
  			}
  		}
  	}
  
  	if (list_empty(&c->free_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
684
685
  		printk(JFFS2_DBG "free_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
686
687
688
689
690
691
692
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->free_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
693
694
  				printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
695
696
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
697
698
699
700
701
  			}
  		}
  	}
  
  	if (list_empty(&c->bad_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
702
703
  		printk(JFFS2_DBG "bad_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
704
705
706
707
708
709
710
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->bad_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
711
712
  				printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
713
714
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
715
716
717
718
719
  			}
  		}
  	}
  
  	if (list_empty(&c->bad_used_list)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
720
721
  		printk(JFFS2_DBG "bad_used_list: empty
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
722
723
724
725
726
727
728
  	} else {
  		struct list_head *this;
  
  		list_for_each(this, &c->bad_used_list) {
  			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
  
  			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
729
730
  				printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
731
732
  					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
  					jeb->unchecked_size, jeb->free_size);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
733
734
735
736
737
738
  			}
  		}
  	}
  }
  
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
739
740
  __jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
  {
ced220703   David Woodhouse   [JFFS2] semaphore...
741
  	mutex_lock(&f->sem);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
742
  	jffs2_dbg_dump_fragtree_nolock(f);
ced220703   David Woodhouse   [JFFS2] semaphore...
743
  	mutex_unlock(&f->sem);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
744
745
746
747
  }
  
  void
  __jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
748
749
750
751
  {
  	struct jffs2_node_frag *this = frag_first(&f->fragtree);
  	uint32_t lastofs = 0;
  	int buggy = 0;
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
752
753
  	printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u
  ", f->inocache->ino);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
754
755
  	while(this) {
  		if (this->node)
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
756
757
  			printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
758
759
760
  				this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
  				ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
  				frag_parent(this));
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
761
  		else
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
762
763
  			printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
764
765
  				this->ofs, this->ofs+this->size, this, frag_left(this),
  				frag_right(this), frag_parent(this));
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
766
767
768
769
770
771
772
  		if (this->ofs != lastofs)
  			buggy = 1;
  		lastofs = this->ofs + this->size;
  		this = frag_next(this);
  	}
  
  	if (f->metadata)
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
773
774
  		printk(JFFS2_DBG "metadata at 0x%08x
  ", ref_offset(f->metadata->raw));
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
775
776
  
  	if (buggy) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
777
778
  		JFFS2_ERROR("frag tree got a hole in it.
  ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
779
780
781
  		BUG();
  	}
  }
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
782
  #define JFFS2_BUFDUMP_BYTES_PER_LINE	32
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
783
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
784
  __jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
785
  {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
786
787
  	int skip;
  	int i;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
788

81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
789
790
  	printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
791
792
793
  		offs, offs + len, len);
  	i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
  	offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
794

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
795
  	if (skip != 0)
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
796
  		printk(JFFS2_DBG "%#08x: ", offs);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
797

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
798
799
  	while (skip--)
  		printk("   ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
800
801
  
  	while (i < len) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
802
803
804
805
806
  		if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
  			if (i != 0)
  				printk("
  ");
  			offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
807
  			printk(JFFS2_DBG "%0#8x: ", offs);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
808
  		}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
809
  		printk("%02x ", buf[i]);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
810

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
  		i += 1;
  	}
  
  	printk("
  ");
  }
  
  /*
   * Dump a JFFS2 node.
   */
  void
  __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
  {
  	union jffs2_node_union node;
  	int len = sizeof(union jffs2_node_union);
  	size_t retlen;
  	uint32_t crc;
  	int ret;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
829

81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
830
831
  	printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.
  ", ofs);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
832
833
834
835
836
837
838
839
  
  	ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
  	if (ret || (retlen != len)) {
  		JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.
  ",
  			len, ret, retlen);
  		return;
  	}
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
840
841
842
843
844
845
846
847
  	printk(JFFS2_DBG "magic:\t%#04x
  ", je16_to_cpu(node.u.magic));
  	printk(JFFS2_DBG "nodetype:\t%#04x
  ", je16_to_cpu(node.u.nodetype));
  	printk(JFFS2_DBG "totlen:\t%#08x
  ", je32_to_cpu(node.u.totlen));
  	printk(JFFS2_DBG "hdr_crc:\t%#08x
  ", je32_to_cpu(node.u.hdr_crc));
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
848

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
849
850
851
852
853
854
  	crc = crc32(0, &node.u, sizeof(node.u) - 4);
  	if (crc != je32_to_cpu(node.u.hdr_crc)) {
  		JFFS2_ERROR("wrong common header CRC.
  ");
  		return;
  	}
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
855

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
856
857
858
859
860
861
862
863
864
865
866
867
  	if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
  		je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
  	{
  		JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.
  ",
  			je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
  		return;
  	}
  
  	switch(je16_to_cpu(node.u.nodetype)) {
  
  	case JFFS2_NODETYPE_INODE:
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
  		printk(JFFS2_DBG "the node is inode node
  ");
  		printk(JFFS2_DBG "ino:\t%#08x
  ", je32_to_cpu(node.i.ino));
  		printk(JFFS2_DBG "version:\t%#08x
  ", je32_to_cpu(node.i.version));
  		printk(JFFS2_DBG "mode:\t%#08x
  ", node.i.mode.m);
  		printk(JFFS2_DBG "uid:\t%#04x
  ", je16_to_cpu(node.i.uid));
  		printk(JFFS2_DBG "gid:\t%#04x
  ", je16_to_cpu(node.i.gid));
  		printk(JFFS2_DBG "isize:\t%#08x
  ", je32_to_cpu(node.i.isize));
  		printk(JFFS2_DBG "atime:\t%#08x
  ", je32_to_cpu(node.i.atime));
  		printk(JFFS2_DBG "mtime:\t%#08x
  ", je32_to_cpu(node.i.mtime));
  		printk(JFFS2_DBG "ctime:\t%#08x
  ", je32_to_cpu(node.i.ctime));
  		printk(JFFS2_DBG "offset:\t%#08x
  ", je32_to_cpu(node.i.offset));
  		printk(JFFS2_DBG "csize:\t%#08x
  ", je32_to_cpu(node.i.csize));
  		printk(JFFS2_DBG "dsize:\t%#08x
  ", je32_to_cpu(node.i.dsize));
  		printk(JFFS2_DBG "compr:\t%#02x
  ", node.i.compr);
  		printk(JFFS2_DBG "usercompr:\t%#02x
  ", node.i.usercompr);
  		printk(JFFS2_DBG "flags:\t%#04x
  ", je16_to_cpu(node.i.flags));
  		printk(JFFS2_DBG "data_crc:\t%#08x
  ", je32_to_cpu(node.i.data_crc));
  		printk(JFFS2_DBG "node_crc:\t%#08x
  ", je32_to_cpu(node.i.node_crc));
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
904
  		crc = crc32(0, &node.i, sizeof(node.i) - 8);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
905
906
907
908
909
910
911
912
  		if (crc != je32_to_cpu(node.i.node_crc)) {
  			JFFS2_ERROR("wrong node header CRC.
  ");
  			return;
  		}
  		break;
  
  	case JFFS2_NODETYPE_DIRENT:
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
  		printk(JFFS2_DBG "the node is dirent node
  ");
  		printk(JFFS2_DBG "pino:\t%#08x
  ", je32_to_cpu(node.d.pino));
  		printk(JFFS2_DBG "version:\t%#08x
  ", je32_to_cpu(node.d.version));
  		printk(JFFS2_DBG "ino:\t%#08x
  ", je32_to_cpu(node.d.ino));
  		printk(JFFS2_DBG "mctime:\t%#08x
  ", je32_to_cpu(node.d.mctime));
  		printk(JFFS2_DBG "nsize:\t%#02x
  ", node.d.nsize);
  		printk(JFFS2_DBG "type:\t%#02x
  ", node.d.type);
  		printk(JFFS2_DBG "node_crc:\t%#08x
  ", je32_to_cpu(node.d.node_crc));
  		printk(JFFS2_DBG "name_crc:\t%#08x
  ", je32_to_cpu(node.d.name_crc));
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
931

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
932
  		node.d.name[node.d.nsize] = '\0';
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
933
934
  		printk(JFFS2_DBG "name:\t\"%s\"
  ", node.d.name);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
935

182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
936
  		crc = crc32(0, &node.d, sizeof(node.d) - 8);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
937
938
939
940
  		if (crc != je32_to_cpu(node.d.node_crc)) {
  			JFFS2_ERROR("wrong node header CRC.
  ");
  			return;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
941
  		}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
942
  		break;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
943

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
944
  	default:
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
945
946
  		printk(JFFS2_DBG "node type is unknown
  ");
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
947
  		break;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
948
949
  	}
  }
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
950
  #endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */