Blame view

fs/jffs2/debug.c 25.7 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

5a528957e   Joe Perches   jffs2: Use pr_fmt...
13
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
14
  #include <linux/kernel.h>
737b7661e   Andrew Lunn   [JFFS2] Fix up ne...
15
  #include <linux/types.h>
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
16
  #include <linux/pagemap.h>
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
17
18
  #include <linux/crc32.h>
  #include <linux/jffs2.h>
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
19
  #include <linux/mtd/mtd.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
20
  #include <linux/slab.h>
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
21
22
  #include "nodelist.h"
  #include "debug.h"
45ca1b509   Artem B. Bityutskiy   [JFFS2] Debug cod...
23
24
25
26
27
28
29
30
31
32
33
  #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...
34
35
36
  		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...
37
38
39
40
41
42
43
44
  			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...
45
46
  		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...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  			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...
63
  #ifdef JFFS2_DBG_PARANOIA_CHECKS
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
64
65
66
  /*
   * Check the fragtree.
   */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
67
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
68
69
  __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
  {
ced220703   David Woodhouse   [JFFS2] semaphore...
70
  	mutex_lock(&f->sem);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
71
  	__jffs2_dbg_fragtree_paranoia_check_nolock(f);
ced220703   David Woodhouse   [JFFS2] semaphore...
72
  	mutex_unlock(&f->sem);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
73
  }
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
74

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
75
76
  void
  __jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
77
78
79
80
81
82
83
84
85
86
87
88
  {
  	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...
89
90
  				JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.
  ",
81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
91
  					ref_offset(fn->raw), fn->frags);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
92
93
94
95
96
97
98
99
100
101
  				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...
102
103
104
  				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...
105
106
107
108
109
  				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...
110
111
112
  				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...
113
114
115
116
117
118
  				bitched = 1;
  			}
  		}
  	}
  
  	if (bitched) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
119
120
121
  		JFFS2_ERROR("fragtree is corrupted.
  ");
  		__jffs2_dbg_dump_fragtree_nolock(f);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
122
123
124
125
126
127
128
129
  		BUG();
  	}
  }
  
  /*
   * Check if the flash contains all 0xFF before we start writing.
   */
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
130
131
  __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
  				    uint32_t ofs, int len)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
132
133
134
135
136
137
138
139
140
141
142
  {
  	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...
143
144
145
  		JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.
  ",
  				len, ret, retlen);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
146
147
148
149
150
151
152
153
154
155
  		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...
156
157
158
  		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...
159
  		__jffs2_dbg_dump_buffer(buf, len, ofs);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
160
161
162
163
164
165
  		kfree(buf);
  		BUG();
  	}
  
  	kfree(buf);
  }
85a62db62   David Woodhouse   [JFFS2] Add paran...
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
258
  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...
259
260
261
262
  	list_for_each_entry(jeb, &c->erase_checking_list, list) {
  		nr_counted++;
  		erasing += c->sector_size;
  	}
85a62db62   David Woodhouse   [JFFS2] Add paran...
263
264
265
266
267
268
269
270
  	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;
  	}
da320f055   Joe Perches   jffs2: Convert pr...
271
272
273
274
275
  #define check(sz)							\
  do {									\
  	if (sz != c->sz##_size) {					\
  		pr_warn("%s_size mismatch counted 0x%x, c->%s_size 0x%x
  ", \
9bbf29e47   Joe Perches   jffs2: Standardiz...
276
  			#sz, sz, #sz, c->sz##_size);			\
da320f055   Joe Perches   jffs2: Convert pr...
277
278
279
  		dump = 1;						\
  	}								\
  } while (0)
85a62db62   David Woodhouse   [JFFS2] Add paran...
280
281
282
283
284
285
286
  	check(free);
  	check(dirty);
  	check(used);
  	check(wasted);
  	check(unchecked);
  	check(bad);
  	check(erasing);
da320f055   Joe Perches   jffs2: Convert pr...
287

85a62db62   David Woodhouse   [JFFS2] Add paran...
288
289
290
  #undef check
  
  	if (nr_counted != c->nr_blocks) {
da320f055   Joe Perches   jffs2: Convert pr...
291
292
293
  		pr_warn("%s counted only 0x%x blocks of 0x%x. Where are the others?
  ",
  			__func__, nr_counted, c->nr_blocks);
85a62db62   David Woodhouse   [JFFS2] Add paran...
294
295
296
297
298
299
300
301
  		dump = 1;
  	}
  
  	if (dump) {
  		__jffs2_dbg_dump_block_lists_nolock(c);
  		BUG();
  	}
  }
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
302
303
304
305
  /*
   * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
   */
  void
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
306
307
308
309
310
311
312
  __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 ...
313

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
314
315
316
  void
  __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
  				       struct jffs2_eraseblock *jeb)
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
317
318
319
320
321
322
323
324
  {
  	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...
325
326
  		if (ref_offset(ref2) < jeb->offset ||
  				ref_offset(ref2) > jeb->offset + c->sector_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
327
328
  			JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
329
  				ref_offset(ref2), jeb->offset);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
330
  			goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
331
332
333
334
335
336
337
338
  
  		}
  		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...
339
340
341
342
343
  		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...
344
  			goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
345
  		}
99988f7bb   David Woodhouse   [JFFS2] Introduce...
346
  		ref2 = ref_next(ref2);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
347
348
349
  	}
  
  	if (my_used_size != jeb->used_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
350
351
352
353
  		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...
354
355
356
  	}
  
  	if (my_unchecked_size != jeb->unchecked_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
357
358
359
360
  		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...
361
  	}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
362
363
  #if 0
  	/* This should work when we implement ref->__totlen elemination */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
364
  	if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
365
366
  		JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
367
  			my_dirty_size, jeb->dirty_size + jeb->wasted_size);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
368
  		goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
369
370
371
372
  	}
  
  	if (jeb->free_size == 0
  		&& my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
373
374
  		JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)
  ",
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
375
376
  			my_used_size + my_unchecked_size + my_dirty_size,
  			c->sector_size);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
377
  		goto error;
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
378
  	}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
379
  #endif
85a62db62   David Woodhouse   [JFFS2] Add paran...
380
381
  	if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
  		__jffs2_dbg_superblock_counts(c);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
382
383
384
385
386
387
388
  	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 ...
389

730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
390
  }
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
391
  #endif /* JFFS2_DBG_PARANOIA_CHECKS */
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
392

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

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

81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
792
793
  	printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).
  ",
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
794
795
796
  		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 ...
797

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

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
801
802
  	while (skip--)
  		printk("   ");
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
803
804
  
  	while (i < len) {
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
805
806
807
808
809
  		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...
810
  			printk(JFFS2_DBG "%0#8x: ", offs);
730554d94   Artem B. Bityutskiy   [JFFS2] Debug cod...
811
  		}
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
812
  		printk("%02x ", buf[i]);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
813

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
  		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 ...
832

81e39cf02   Artem B. Bityutskiy   [JFFS2] Debug mes...
833
834
  	printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.
  ", ofs);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
835
836
837
838
839
840
841
842
  
  	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...
843
844
845
846
847
848
849
850
  	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 ...
851

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
852
853
854
855
856
857
  	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 ...
858

e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
859
860
861
862
863
864
865
866
867
868
869
870
  	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...
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
904
905
906
  		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 ...
907
  		crc = crc32(0, &node.i, sizeof(node.i) - 8);
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
908
909
910
911
912
913
914
915
  		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...
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
  		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 ...
934

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

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

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