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

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
  				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. */
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
100
101
  			if (frag->ofs & (PAGE_SIZE-1) && frag_prev(frag)
  					&& frag_prev(frag)->size < PAGE_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
  				bitched = 1;
  			}
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
107
108
  			if ((frag->ofs+frag->size) & (PAGE_SIZE-1) && frag_next(frag)
  					&& frag_next(frag)->size < PAGE_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
  	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...
270
271
272
273
274
  #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...
275
  			#sz, sz, #sz, c->sz##_size);			\
da320f055   Joe Perches   jffs2: Convert pr...
276
277
278
  		dump = 1;						\
  	}								\
  } while (0)
85a62db62   David Woodhouse   [JFFS2] Add paran...
279
280
281
282
283
284
285
  	check(free);
  	check(dirty);
  	check(used);
  	check(wasted);
  	check(unchecked);
  	check(bad);
  	check(erasing);
da320f055   Joe Perches   jffs2: Convert pr...
286

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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