Blame view

fs/ubifs/debug.c 83.7 KB
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  /*
   * This file is part of UBIFS.
   *
   * Copyright (C) 2006-2008 Nokia Corporation
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 as published by
   * the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc., 51
   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
   *
   * Authors: Artem Bityutskiy (Битюцкий Артём)
   *          Adrian Hunter
   */
  
  /*
   * This file implements most of the debugging stuff which is compiled in only
   * when it is enabled. But some debugging check functions are implemented in
   * corresponding subsystem, just because they are closely related and utilize
   * various local functions of those subsystems.
   */
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
29
  #include <linux/module.h>
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
30
  #include <linux/debugfs.h>
4d61db4f8   Artem Bityutskiy   UBIFS: use nicer ...
31
  #include <linux/math64.h>
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
32
  #include <linux/uaccess.h>
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
33
  #include <linux/random.h>
e328379a1   Hyunchul Lee   ubifs: Fix debug ...
34
  #include <linux/ctype.h>
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
35
  #include "ubifs.h"
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
36

b06283c7d   Artem Bityutskiy   UBIFS: make the d...
37
  static DEFINE_SPINLOCK(dbg_lock);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
38

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  static const char *get_key_fmt(int fmt)
  {
  	switch (fmt) {
  	case UBIFS_SIMPLE_KEY_FMT:
  		return "simple";
  	default:
  		return "unknown/invalid format";
  	}
  }
  
  static const char *get_key_hash(int hash)
  {
  	switch (hash) {
  	case UBIFS_KEY_HASH_R5:
  		return "R5";
  	case UBIFS_KEY_HASH_TEST:
  		return "test";
  	default:
  		return "unknown/invalid name hash";
  	}
  }
  
  static const char *get_key_type(int type)
  {
  	switch (type) {
  	case UBIFS_INO_KEY:
  		return "inode";
  	case UBIFS_DENT_KEY:
  		return "direntry";
  	case UBIFS_XENT_KEY:
  		return "xentry";
  	case UBIFS_DATA_KEY:
  		return "data";
  	case UBIFS_TRUN_KEY:
  		return "truncate";
  	default:
  		return "unknown/invalid key";
  	}
  }
4315fb407   Artem Bityutskiy   UBIFS: improve in...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  static const char *get_dent_type(int type)
  {
  	switch (type) {
  	case UBIFS_ITYPE_REG:
  		return "file";
  	case UBIFS_ITYPE_DIR:
  		return "dir";
  	case UBIFS_ITYPE_LNK:
  		return "symlink";
  	case UBIFS_ITYPE_BLK:
  		return "blkdev";
  	case UBIFS_ITYPE_CHR:
  		return "char dev";
  	case UBIFS_ITYPE_FIFO:
  		return "fifo";
  	case UBIFS_ITYPE_SOCK:
  		return "socket";
  	default:
  		return "unknown/invalid type";
  	}
  }
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
99
100
  const char *dbg_snprintf_key(const struct ubifs_info *c,
  			     const union ubifs_key *key, char *buffer, int len)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
101
102
103
104
105
106
107
  {
  	char *p = buffer;
  	int type = key_type(c, key);
  
  	if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) {
  		switch (type) {
  		case UBIFS_INO_KEY:
beba00607   Artem Bityutskiy   UBIFS: use snprin...
108
109
110
  			len -= snprintf(p, len, "(%lu, %s)",
  					(unsigned long)key_inum(c, key),
  					get_key_type(type));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
111
112
113
  			break;
  		case UBIFS_DENT_KEY:
  		case UBIFS_XENT_KEY:
beba00607   Artem Bityutskiy   UBIFS: use snprin...
114
115
116
  			len -= snprintf(p, len, "(%lu, %s, %#08x)",
  					(unsigned long)key_inum(c, key),
  					get_key_type(type), key_hash(c, key));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
117
118
  			break;
  		case UBIFS_DATA_KEY:
beba00607   Artem Bityutskiy   UBIFS: use snprin...
119
120
121
  			len -= snprintf(p, len, "(%lu, %s, %u)",
  					(unsigned long)key_inum(c, key),
  					get_key_type(type), key_block(c, key));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
122
123
  			break;
  		case UBIFS_TRUN_KEY:
beba00607   Artem Bityutskiy   UBIFS: use snprin...
124
125
126
  			len -= snprintf(p, len, "(%lu, %s)",
  					(unsigned long)key_inum(c, key),
  					get_key_type(type));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
127
128
  			break;
  		default:
beba00607   Artem Bityutskiy   UBIFS: use snprin...
129
130
  			len -= snprintf(p, len, "(bad key type: %#08x, %#08x)",
  					key->u32[0], key->u32[1]);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
131
132
  		}
  	} else
beba00607   Artem Bityutskiy   UBIFS: use snprin...
133
134
  		len -= snprintf(p, len, "bad key format %d", c->key_fmt);
  	ubifs_assert(len > 0);
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
135
  	return p;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
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
  }
  
  const char *dbg_ntype(int type)
  {
  	switch (type) {
  	case UBIFS_PAD_NODE:
  		return "padding node";
  	case UBIFS_SB_NODE:
  		return "superblock node";
  	case UBIFS_MST_NODE:
  		return "master node";
  	case UBIFS_REF_NODE:
  		return "reference node";
  	case UBIFS_INO_NODE:
  		return "inode node";
  	case UBIFS_DENT_NODE:
  		return "direntry node";
  	case UBIFS_XENT_NODE:
  		return "xentry node";
  	case UBIFS_DATA_NODE:
  		return "data node";
  	case UBIFS_TRUN_NODE:
  		return "truncate node";
  	case UBIFS_IDX_NODE:
  		return "indexing node";
  	case UBIFS_CS_NODE:
  		return "commit start node";
  	case UBIFS_ORPH_NODE:
  		return "orphan node";
  	default:
  		return "unknown node";
  	}
  }
  
  static const char *dbg_gtype(int type)
  {
  	switch (type) {
  	case UBIFS_NO_NODE_GROUP:
  		return "no node group";
  	case UBIFS_IN_NODE_GROUP:
  		return "in node group";
  	case UBIFS_LAST_OF_NODE_GROUP:
  		return "last of node group";
  	default:
  		return "unknown";
  	}
  }
  
  const char *dbg_cstate(int cmt_state)
  {
  	switch (cmt_state) {
  	case COMMIT_RESTING:
  		return "commit resting";
  	case COMMIT_BACKGROUND:
  		return "background commit requested";
  	case COMMIT_REQUIRED:
  		return "commit required";
  	case COMMIT_RUNNING_BACKGROUND:
  		return "BACKGROUND commit running";
  	case COMMIT_RUNNING_REQUIRED:
  		return "commit running and required";
  	case COMMIT_BROKEN:
  		return "broken commit";
  	default:
  		return "unknown commit state";
  	}
  }
77a7ae580   Artem Bityutskiy   UBIFS: improve jo...
203
204
205
206
207
208
209
210
211
212
213
214
215
  const char *dbg_jhead(int jhead)
  {
  	switch (jhead) {
  	case GCHD:
  		return "0 (GC)";
  	case BASEHD:
  		return "1 (base)";
  	case DATAHD:
  		return "2 (data)";
  	default:
  		return "unknown journal head";
  	}
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
216
217
  static void dump_ch(const struct ubifs_ch *ch)
  {
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
218
219
220
221
222
223
  	pr_err("\tmagic          %#x
  ", le32_to_cpu(ch->magic));
  	pr_err("\tcrc            %#x
  ", le32_to_cpu(ch->crc));
  	pr_err("\tnode_type      %d (%s)
  ", ch->node_type,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
224
  	       dbg_ntype(ch->node_type));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
225
226
  	pr_err("\tgroup_type     %d (%s)
  ", ch->group_type,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
227
  	       dbg_gtype(ch->group_type));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
228
229
  	pr_err("\tsqnum          %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
230
  	       (unsigned long long)le64_to_cpu(ch->sqnum));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
231
232
  	pr_err("\tlen            %u
  ", le32_to_cpu(ch->len));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
233
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
234
  void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
235
236
  {
  	const struct ubifs_inode *ui = ubifs_inode(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
237
  	struct fscrypt_name nm = {0};
4315fb407   Artem Bityutskiy   UBIFS: improve in...
238
239
240
  	union ubifs_key key;
  	struct ubifs_dent_node *dent, *pdent = NULL;
  	int count = 2;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
241

6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
242
243
244
245
246
  	pr_err("Dump in-memory inode:");
  	pr_err("\tinode          %lu
  ", inode->i_ino);
  	pr_err("\tsize           %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
247
  	       (unsigned long long)i_size_read(inode));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
248
249
  	pr_err("\tnlink          %u
  ", inode->i_nlink);
782c3fb22   Linus Torvalds   Merge tag 'upstre...
250
251
252
253
  	pr_err("\tuid            %u
  ", (unsigned int)i_uid_read(inode));
  	pr_err("\tgid            %u
  ", (unsigned int)i_gid_read(inode));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
254
255
  	pr_err("\tatime          %u.%u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
256
257
  	       (unsigned int)inode->i_atime.tv_sec,
  	       (unsigned int)inode->i_atime.tv_nsec);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
258
259
  	pr_err("\tmtime          %u.%u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
260
261
  	       (unsigned int)inode->i_mtime.tv_sec,
  	       (unsigned int)inode->i_mtime.tv_nsec);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
262
263
  	pr_err("\tctime          %u.%u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
264
265
  	       (unsigned int)inode->i_ctime.tv_sec,
  	       (unsigned int)inode->i_ctime.tv_nsec);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
266
267
268
269
270
271
272
273
274
275
276
277
  	pr_err("\tcreat_sqnum    %llu
  ", ui->creat_sqnum);
  	pr_err("\txattr_size     %u
  ", ui->xattr_size);
  	pr_err("\txattr_cnt      %u
  ", ui->xattr_cnt);
  	pr_err("\txattr_names    %u
  ", ui->xattr_names);
  	pr_err("\tdirty          %u
  ", ui->dirty);
  	pr_err("\txattr          %u
  ", ui->xattr);
1112018ce   Andreas Gruenbacher   ubifs: ubifs_dump...
278
279
  	pr_err("\tbulk_read      %u
  ", ui->bulk_read);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
280
281
  	pr_err("\tsynced_i_size  %llu
  ",
b5e426e9a   Artem Bityutskiy   UBIFS: update dbg...
282
  	       (unsigned long long)ui->synced_i_size);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
283
284
  	pr_err("\tui_size        %llu
  ",
b5e426e9a   Artem Bityutskiy   UBIFS: update dbg...
285
  	       (unsigned long long)ui->ui_size);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
286
287
288
289
290
291
292
293
294
295
  	pr_err("\tflags          %d
  ", ui->flags);
  	pr_err("\tcompr_type     %d
  ", ui->compr_type);
  	pr_err("\tlast_page_read %lu
  ", ui->last_page_read);
  	pr_err("\tread_in_a_row  %lu
  ", ui->read_in_a_row);
  	pr_err("\tdata_len       %d
  ", ui->data_len);
4315fb407   Artem Bityutskiy   UBIFS: improve in...
296
297
298
  
  	if (!S_ISDIR(inode->i_mode))
  		return;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
299
300
  	pr_err("List of directory entries:
  ");
4315fb407   Artem Bityutskiy   UBIFS: improve in...
301
302
303
304
305
306
307
  	ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
  
  	lowest_dent_key(c, &key, inode->i_ino);
  	while (1) {
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			if (PTR_ERR(dent) != -ENOENT)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
308
309
  				pr_err("error %ld
  ", PTR_ERR(dent));
4315fb407   Artem Bityutskiy   UBIFS: improve in...
310
311
  			break;
  		}
33fda9fa9   Hyunchul Lee   ubifs: Fix debug ...
312
313
314
315
316
  		pr_err("\t%d: inode %llu, type %s, len %d
  ",
  		       count++, (unsigned long long) le64_to_cpu(dent->inum),
  		       get_dent_type(dent->type),
  		       le16_to_cpu(dent->nlen));
4315fb407   Artem Bityutskiy   UBIFS: improve in...
317

f4f61d2cc   Richard Weinberger   ubifs: Implement ...
318
319
  		fname_name(&nm) = dent->name;
  		fname_len(&nm) = le16_to_cpu(dent->nlen);
4315fb407   Artem Bityutskiy   UBIFS: improve in...
320
321
322
323
324
  		kfree(pdent);
  		pdent = dent;
  		key_read(c, &dent->key, &key);
  	}
  	kfree(pdent);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
325
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
326
  void ubifs_dump_node(const struct ubifs_info *c, const void *node)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
327
328
329
330
  {
  	int i, n;
  	union ubifs_key key;
  	const struct ubifs_ch *ch = node;
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
331
  	char key_buf[DBG_KEY_BUF_LEN];
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
332

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
333
334
  	/* If the magic is incorrect, just hexdump the first bytes */
  	if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) {
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
335
  		pr_err("Not a node, first %zu bytes:", UBIFS_CH_SZ);
16c395ca7   Artem Bityutskiy   UBIFS: increase d...
336
  		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 32, 1,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
337
338
339
340
341
342
343
344
345
346
347
  			       (void *)node, UBIFS_CH_SZ, 1);
  		return;
  	}
  
  	spin_lock(&dbg_lock);
  	dump_ch(node);
  
  	switch (ch->node_type) {
  	case UBIFS_PAD_NODE:
  	{
  		const struct ubifs_pad_node *pad = node;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
348
349
  		pr_err("\tpad_len        %u
  ", le32_to_cpu(pad->pad_len));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
350
351
352
353
354
355
  		break;
  	}
  	case UBIFS_SB_NODE:
  	{
  		const struct ubifs_sb_node *sup = node;
  		unsigned int sup_flags = le32_to_cpu(sup->flags);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
356
357
  		pr_err("\tkey_hash       %d (%s)
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
358
  		       (int)sup->key_hash, get_key_hash(sup->key_hash));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
359
360
  		pr_err("\tkey_fmt        %d (%s)
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
361
  		       (int)sup->key_fmt, get_key_fmt(sup->key_fmt));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
362
363
  		pr_err("\tflags          %#x
  ", sup_flags);
4b1a43eab   hujianyang   UBIFS: Align the ...
364
365
  		pr_err("\tbig_lpt        %u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
366
  		       !!(sup_flags & UBIFS_FLG_BIGLPT));
4b1a43eab   hujianyang   UBIFS: Align the ...
367
368
  		pr_err("\tspace_fixup    %u
  ",
9f58d3503   Matthew L. Creech   UBIFS: add a supe...
369
  		       !!(sup_flags & UBIFS_FLG_SPACE_FIXUP));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
370
371
372
373
374
375
376
377
378
379
  		pr_err("\tmin_io_size    %u
  ", le32_to_cpu(sup->min_io_size));
  		pr_err("\tleb_size       %u
  ", le32_to_cpu(sup->leb_size));
  		pr_err("\tleb_cnt        %u
  ", le32_to_cpu(sup->leb_cnt));
  		pr_err("\tmax_leb_cnt    %u
  ", le32_to_cpu(sup->max_leb_cnt));
  		pr_err("\tmax_bud_bytes  %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
380
  		       (unsigned long long)le64_to_cpu(sup->max_bud_bytes));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  		pr_err("\tlog_lebs       %u
  ", le32_to_cpu(sup->log_lebs));
  		pr_err("\tlpt_lebs       %u
  ", le32_to_cpu(sup->lpt_lebs));
  		pr_err("\torph_lebs      %u
  ", le32_to_cpu(sup->orph_lebs));
  		pr_err("\tjhead_cnt      %u
  ", le32_to_cpu(sup->jhead_cnt));
  		pr_err("\tfanout         %u
  ", le32_to_cpu(sup->fanout));
  		pr_err("\tlsave_cnt      %u
  ", le32_to_cpu(sup->lsave_cnt));
  		pr_err("\tdefault_compr  %u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
395
  		       (int)le16_to_cpu(sup->default_compr));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
396
397
  		pr_err("\trp_size        %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
398
  		       (unsigned long long)le64_to_cpu(sup->rp_size));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
399
400
401
402
403
404
405
406
407
408
  		pr_err("\trp_uid         %u
  ", le32_to_cpu(sup->rp_uid));
  		pr_err("\trp_gid         %u
  ", le32_to_cpu(sup->rp_gid));
  		pr_err("\tfmt_version    %u
  ", le32_to_cpu(sup->fmt_version));
  		pr_err("\ttime_gran      %u
  ", le32_to_cpu(sup->time_gran));
  		pr_err("\tUUID           %pUB
  ", sup->uuid);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
409
410
411
412
413
  		break;
  	}
  	case UBIFS_MST_NODE:
  	{
  		const struct ubifs_mst_node *mst = node;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
414
415
  		pr_err("\thighest_inum   %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
416
  		       (unsigned long long)le64_to_cpu(mst->highest_inum));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
417
418
  		pr_err("\tcommit number  %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
419
  		       (unsigned long long)le64_to_cpu(mst->cmt_no));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
  		pr_err("\tflags          %#x
  ", le32_to_cpu(mst->flags));
  		pr_err("\tlog_lnum       %u
  ", le32_to_cpu(mst->log_lnum));
  		pr_err("\troot_lnum      %u
  ", le32_to_cpu(mst->root_lnum));
  		pr_err("\troot_offs      %u
  ", le32_to_cpu(mst->root_offs));
  		pr_err("\troot_len       %u
  ", le32_to_cpu(mst->root_len));
  		pr_err("\tgc_lnum        %u
  ", le32_to_cpu(mst->gc_lnum));
  		pr_err("\tihead_lnum     %u
  ", le32_to_cpu(mst->ihead_lnum));
  		pr_err("\tihead_offs     %u
  ", le32_to_cpu(mst->ihead_offs));
  		pr_err("\tindex_size     %llu
  ",
0ecb9529a   Harvey Harrison   UBIFS: endian han...
438
  		       (unsigned long long)le64_to_cpu(mst->index_size));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  		pr_err("\tlpt_lnum       %u
  ", le32_to_cpu(mst->lpt_lnum));
  		pr_err("\tlpt_offs       %u
  ", le32_to_cpu(mst->lpt_offs));
  		pr_err("\tnhead_lnum     %u
  ", le32_to_cpu(mst->nhead_lnum));
  		pr_err("\tnhead_offs     %u
  ", le32_to_cpu(mst->nhead_offs));
  		pr_err("\tltab_lnum      %u
  ", le32_to_cpu(mst->ltab_lnum));
  		pr_err("\tltab_offs      %u
  ", le32_to_cpu(mst->ltab_offs));
  		pr_err("\tlsave_lnum     %u
  ", le32_to_cpu(mst->lsave_lnum));
  		pr_err("\tlsave_offs     %u
  ", le32_to_cpu(mst->lsave_offs));
  		pr_err("\tlscan_lnum     %u
  ", le32_to_cpu(mst->lscan_lnum));
  		pr_err("\tleb_cnt        %u
  ", le32_to_cpu(mst->leb_cnt));
  		pr_err("\tempty_lebs     %u
  ", le32_to_cpu(mst->empty_lebs));
  		pr_err("\tidx_lebs       %u
  ", le32_to_cpu(mst->idx_lebs));
  		pr_err("\ttotal_free     %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
465
  		       (unsigned long long)le64_to_cpu(mst->total_free));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
466
467
  		pr_err("\ttotal_dirty    %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
468
  		       (unsigned long long)le64_to_cpu(mst->total_dirty));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
469
470
  		pr_err("\ttotal_used     %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
471
  		       (unsigned long long)le64_to_cpu(mst->total_used));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
472
473
  		pr_err("\ttotal_dead     %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
474
  		       (unsigned long long)le64_to_cpu(mst->total_dead));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
475
476
  		pr_err("\ttotal_dark     %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
477
478
479
480
481
482
  		       (unsigned long long)le64_to_cpu(mst->total_dark));
  		break;
  	}
  	case UBIFS_REF_NODE:
  	{
  		const struct ubifs_ref_node *ref = node;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
483
484
485
486
487
488
  		pr_err("\tlnum           %u
  ", le32_to_cpu(ref->lnum));
  		pr_err("\toffs           %u
  ", le32_to_cpu(ref->offs));
  		pr_err("\tjhead          %u
  ", le32_to_cpu(ref->jhead));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
489
490
491
492
493
494
495
  		break;
  	}
  	case UBIFS_INO_NODE:
  	{
  		const struct ubifs_ino_node *ino = node;
  
  		key_read(c, &ino->key, &key);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
496
497
  		pr_err("\tkey            %s
  ",
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
498
  		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
499
500
  		pr_err("\tcreat_sqnum    %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
501
  		       (unsigned long long)le64_to_cpu(ino->creat_sqnum));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
502
503
  		pr_err("\tsize           %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
504
  		       (unsigned long long)le64_to_cpu(ino->size));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
505
506
507
508
  		pr_err("\tnlink          %u
  ", le32_to_cpu(ino->nlink));
  		pr_err("\tatime          %lld.%u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
509
510
  		       (long long)le64_to_cpu(ino->atime_sec),
  		       le32_to_cpu(ino->atime_nsec));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
511
512
  		pr_err("\tmtime          %lld.%u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
513
514
  		       (long long)le64_to_cpu(ino->mtime_sec),
  		       le32_to_cpu(ino->mtime_nsec));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
515
516
  		pr_err("\tctime          %lld.%u
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
517
518
  		       (long long)le64_to_cpu(ino->ctime_sec),
  		       le32_to_cpu(ino->ctime_nsec));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
  		pr_err("\tuid            %u
  ", le32_to_cpu(ino->uid));
  		pr_err("\tgid            %u
  ", le32_to_cpu(ino->gid));
  		pr_err("\tmode           %u
  ", le32_to_cpu(ino->mode));
  		pr_err("\tflags          %#x
  ", le32_to_cpu(ino->flags));
  		pr_err("\txattr_cnt      %u
  ", le32_to_cpu(ino->xattr_cnt));
  		pr_err("\txattr_size     %u
  ", le32_to_cpu(ino->xattr_size));
  		pr_err("\txattr_names    %u
  ", le32_to_cpu(ino->xattr_names));
  		pr_err("\tcompr_type     %#x
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
535
  		       (int)le16_to_cpu(ino->compr_type));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
536
537
  		pr_err("\tdata len       %u
  ", le32_to_cpu(ino->data_len));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
538
539
540
541
542
543
544
545
546
  		break;
  	}
  	case UBIFS_DENT_NODE:
  	case UBIFS_XENT_NODE:
  	{
  		const struct ubifs_dent_node *dent = node;
  		int nlen = le16_to_cpu(dent->nlen);
  
  		key_read(c, &dent->key, &key);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
547
548
  		pr_err("\tkey            %s
  ",
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
549
  		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
550
551
  		pr_err("\tinum           %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
552
  		       (unsigned long long)le64_to_cpu(dent->inum));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
553
554
555
556
557
  		pr_err("\ttype           %d
  ", (int)dent->type);
  		pr_err("\tnlen           %d
  ", nlen);
  		pr_err("\tname           ");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
558
559
  
  		if (nlen > UBIFS_MAX_NLEN)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
560
  			pr_err("(bad name length, not printing, bad or corrupted node)");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
561
562
  		else {
  			for (i = 0; i < nlen && dent->name[i]; i++)
e328379a1   Hyunchul Lee   ubifs: Fix debug ...
563
564
  				pr_cont("%c", isprint(dent->name[i]) ?
  					dent->name[i] : '?');
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
565
  		}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
566
567
  		pr_cont("
  ");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
568
569
570
571
572
573
574
575
576
  
  		break;
  	}
  	case UBIFS_DATA_NODE:
  	{
  		const struct ubifs_data_node *dn = node;
  		int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
  
  		key_read(c, &dn->key, &key);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
577
578
  		pr_err("\tkey            %s
  ",
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
579
  		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
580
581
582
583
  		pr_err("\tsize           %u
  ", le32_to_cpu(dn->size));
  		pr_err("\tcompr_typ      %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
584
  		       (int)le16_to_cpu(dn->compr_type));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
585
586
587
588
  		pr_err("\tdata size      %d
  ", dlen);
  		pr_err("\tdata:
  ");
16c395ca7   Artem Bityutskiy   UBIFS: increase d...
589
  		print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
590
591
592
593
594
595
  			       (void *)&dn->data, dlen, 0);
  		break;
  	}
  	case UBIFS_TRUN_NODE:
  	{
  		const struct ubifs_trun_node *trun = node;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
596
597
598
599
  		pr_err("\tinum           %u
  ", le32_to_cpu(trun->inum));
  		pr_err("\told_size       %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
600
  		       (unsigned long long)le64_to_cpu(trun->old_size));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
601
602
  		pr_err("\tnew_size       %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
603
604
605
606
607
608
609
610
  		       (unsigned long long)le64_to_cpu(trun->new_size));
  		break;
  	}
  	case UBIFS_IDX_NODE:
  	{
  		const struct ubifs_idx_node *idx = node;
  
  		n = le16_to_cpu(idx->child_cnt);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
611
612
613
614
615
616
  		pr_err("\tchild_cnt      %d
  ", n);
  		pr_err("\tlevel          %d
  ", (int)le16_to_cpu(idx->level));
  		pr_err("\tBranches:
  ");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
617
618
619
620
621
622
  
  		for (i = 0; i < n && i < c->fanout - 1; i++) {
  			const struct ubifs_branch *br;
  
  			br = ubifs_idx_branch(c, idx, i);
  			key_read(c, &br->key, &key);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
623
624
  			pr_err("\t%d: LEB %d:%d len %d key %s
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
625
  			       i, le32_to_cpu(br->lnum), le32_to_cpu(br->offs),
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
626
627
628
  			       le32_to_cpu(br->len),
  			       dbg_snprintf_key(c, &key, key_buf,
  						DBG_KEY_BUF_LEN));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
629
630
631
632
633
634
635
636
  		}
  		break;
  	}
  	case UBIFS_CS_NODE:
  		break;
  	case UBIFS_ORPH_NODE:
  	{
  		const struct ubifs_orph_node *orph = node;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
637
638
  		pr_err("\tcommit number  %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
639
640
  		       (unsigned long long)
  				le64_to_cpu(orph->cmt_no) & LLONG_MAX);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
641
642
  		pr_err("\tlast node flag %llu
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
643
644
  		       (unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63);
  		n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
645
646
  		pr_err("\t%d orphan inode numbers:
  ", n);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
647
  		for (i = 0; i < n; i++)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
648
649
  			pr_err("\t  ino %llu
  ",
7424bac82   Alexander Beregalov   UBIFS: fix printk...
650
  			       (unsigned long long)le64_to_cpu(orph->inos[i]));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
651
652
653
  		break;
  	}
  	default:
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
654
655
  		pr_err("node type %d was not recognized
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
656
657
658
659
  		       (int)ch->node_type);
  	}
  	spin_unlock(&dbg_lock);
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
660
  void ubifs_dump_budget_req(const struct ubifs_budget_req *req)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
661
662
  {
  	spin_lock(&dbg_lock);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
663
664
  	pr_err("Budgeting request: new_ino %d, dirtied_ino %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
665
  	       req->new_ino, req->dirtied_ino);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
666
667
  	pr_err("\tnew_ino_d   %d, dirtied_ino_d %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
668
  	       req->new_ino_d, req->dirtied_ino_d);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
669
670
  	pr_err("\tnew_page    %d, dirtied_page %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
671
  	       req->new_page, req->dirtied_page);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
672
673
  	pr_err("\tnew_dent    %d, mod_dent     %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
674
  	       req->new_dent, req->mod_dent);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
675
676
677
678
  	pr_err("\tidx_growth  %d
  ", req->idx_growth);
  	pr_err("\tdata_growth %d dd_growth     %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
679
680
681
  	       req->data_growth, req->dd_growth);
  	spin_unlock(&dbg_lock);
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
682
  void ubifs_dump_lstats(const struct ubifs_lp_stats *lst)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
683
684
  {
  	spin_lock(&dbg_lock);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
685
686
  	pr_err("(pid %d) Lprops statistics: empty_lebs %d, idx_lebs  %d
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
687
  	       current->pid, lst->empty_lebs, lst->idx_lebs);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
688
689
  	pr_err("\ttaken_empty_lebs %d, total_free %lld, total_dirty %lld
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
690
  	       lst->taken_empty_lebs, lst->total_free, lst->total_dirty);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
691
692
  	pr_err("\ttotal_used %lld, total_dark %lld, total_dead %lld
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
693
  	       lst->total_used, lst->total_dark, lst->total_dead);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
694
695
  	spin_unlock(&dbg_lock);
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
696
  void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
697
698
699
700
701
  {
  	int i;
  	struct rb_node *rb;
  	struct ubifs_bud *bud;
  	struct ubifs_gced_idx_leb *idx_gc;
21a602589   Artem Bityutskiy   UBIFS: improve bu...
702
  	long long available, outstanding, free;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
703

8ff83089f   Artem Bityutskiy   UBIFS: simplify d...
704
  	spin_lock(&c->space_lock);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
705
  	spin_lock(&dbg_lock);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
706
707
  	pr_err("(pid %d) Budgeting info: data budget sum %lld, total budget sum %lld
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
708
  	       current->pid, bi->data_growth + bi->dd_growth,
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
709
  	       bi->data_growth + bi->dd_growth + bi->idx_growth);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
710
711
  	pr_err("\tbudg_data_growth %lld, budg_dd_growth %lld, budg_idx_growth %lld
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
712
  	       bi->data_growth, bi->dd_growth, bi->idx_growth);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
713
714
  	pr_err("\tmin_idx_lebs %d, old_idx_sz %llu, uncommitted_idx %lld
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
715
  	       bi->min_idx_lebs, bi->old_idx_sz, bi->uncommitted_idx);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
716
717
  	pr_err("\tpage_budget %d, inode_budget %d, dent_budget %d
  ",
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
718
  	       bi->page_budget, bi->inode_budget, bi->dent_budget);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
719
720
721
722
  	pr_err("\tnospace %u, nospace_rp %u
  ", bi->nospace, bi->nospace_rp);
  	pr_err("\tdark_wm %d, dead_wm %d, max_idx_node_sz %d
  ",
8c3067e44   Artem Bityutskiy   UBIFS: rearrange ...
723
  	       c->dark_wm, c->dead_wm, c->max_idx_node_sz);
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
724
725
726
727
728
729
730
731
  
  	if (bi != &c->bi)
  		/*
  		 * If we are dumping saved budgeting data, do not print
  		 * additional information which is about the current state, not
  		 * the old one which corresponded to the saved budgeting data.
  		 */
  		goto out_unlock;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
732
733
  	pr_err("\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d
  ",
8c3067e44   Artem Bityutskiy   UBIFS: rearrange ...
734
  	       c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
735
736
  	pr_err("\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, clean_zn_cnt %ld
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
737
  	       atomic_long_read(&c->dirty_pg_cnt),
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
738
739
  	       atomic_long_read(&c->dirty_zn_cnt),
  	       atomic_long_read(&c->clean_zn_cnt));
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
740
741
  	pr_err("\tgc_lnum %d, ihead_lnum %d
  ", c->gc_lnum, c->ihead_lnum);
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
742

84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
743
744
745
  	/* If we are in R/O mode, journal heads do not exist */
  	if (c->jheads)
  		for (i = 0; i < c->jhead_cnt; i++)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
746
747
  			pr_err("\tjhead %s\t LEB %d
  ",
77a7ae580   Artem Bityutskiy   UBIFS: improve jo...
748
749
  			       dbg_jhead(c->jheads[i].wbuf.jhead),
  			       c->jheads[i].wbuf.lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
750
751
  	for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
  		bud = rb_entry(rb, struct ubifs_bud, rb);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
752
753
  		pr_err("\tbud LEB %d
  ", bud->lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
754
755
  	}
  	list_for_each_entry(bud, &c->old_buds, list)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
756
757
  		pr_err("\told bud LEB %d
  ", bud->lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
758
  	list_for_each_entry(idx_gc, &c->idx_gc, list)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
759
760
  		pr_err("\tGC'ed idx LEB %d unmap %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
761
  		       idx_gc->lnum, idx_gc->unmap);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
762
763
  	pr_err("\tcommit state %d
  ", c->cmt_state);
21a602589   Artem Bityutskiy   UBIFS: improve bu...
764
765
  
  	/* Print budgeting predictions */
b137545c4   Artem Bityutskiy   UBIFS: introduce ...
766
767
  	available = ubifs_calc_available(c, c->bi.min_idx_lebs);
  	outstanding = c->bi.data_growth + c->bi.dd_growth;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
768
  	free = ubifs_get_free_space_nolock(c);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
769
770
771
772
  	pr_err("Budgeting predictions:
  ");
  	pr_err("\tavailable: %lld, outstanding %lld, free %lld
  ",
21a602589   Artem Bityutskiy   UBIFS: improve bu...
773
  	       available, outstanding, free);
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
774
  out_unlock:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
775
  	spin_unlock(&dbg_lock);
8ff83089f   Artem Bityutskiy   UBIFS: simplify d...
776
  	spin_unlock(&c->space_lock);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
777
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
778
  void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
779
  {
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
780
781
782
783
784
785
786
787
788
789
790
  	int i, spc, dark = 0, dead = 0;
  	struct rb_node *rb;
  	struct ubifs_bud *bud;
  
  	spc = lp->free + lp->dirty;
  	if (spc < c->dead_wm)
  		dead = spc;
  	else
  		dark = ubifs_calc_dark(c, spc);
  
  	if (lp->flags & LPROPS_INDEX)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
791
  		pr_err("LEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d flags %#x (",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
792
793
  		       lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc,
  		       lp->flags);
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
794
  	else
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
795
  		pr_err("LEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d flags %#-4x (",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
796
797
  		       lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc,
  		       dark, dead, (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags);
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
798
799
800
  
  	if (lp->flags & LPROPS_TAKEN) {
  		if (lp->flags & LPROPS_INDEX)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
801
  			pr_cont("index, taken");
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
802
  		else
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
803
  			pr_cont("taken");
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
  	} else {
  		const char *s;
  
  		if (lp->flags & LPROPS_INDEX) {
  			switch (lp->flags & LPROPS_CAT_MASK) {
  			case LPROPS_DIRTY_IDX:
  				s = "dirty index";
  				break;
  			case LPROPS_FRDI_IDX:
  				s = "freeable index";
  				break;
  			default:
  				s = "index";
  			}
  		} else {
  			switch (lp->flags & LPROPS_CAT_MASK) {
  			case LPROPS_UNCAT:
  				s = "not categorized";
  				break;
  			case LPROPS_DIRTY:
  				s = "dirty";
  				break;
  			case LPROPS_FREE:
  				s = "free";
  				break;
  			case LPROPS_EMPTY:
  				s = "empty";
  				break;
  			case LPROPS_FREEABLE:
  				s = "freeable";
  				break;
  			default:
  				s = NULL;
  				break;
  			}
  		}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
840
  		pr_cont("%s", s);
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
841
842
843
844
845
846
847
  	}
  
  	for (rb = rb_first((struct rb_root *)&c->buds); rb; rb = rb_next(rb)) {
  		bud = rb_entry(rb, struct ubifs_bud, rb);
  		if (bud->lnum == lp->lnum) {
  			int head = 0;
  			for (i = 0; i < c->jhead_cnt; i++) {
1321657d8   Artem Bityutskiy   UBIFS: fix oops i...
848
849
850
851
852
853
854
  				/*
  				 * Note, if we are in R/O mode or in the middle
  				 * of mounting/re-mounting, the write-buffers do
  				 * not exist.
  				 */
  				if (c->jheads &&
  				    lp->lnum == c->jheads[i].wbuf.lnum) {
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
855
  					pr_cont(", jhead %s", dbg_jhead(i));
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
856
857
858
859
  					head = 1;
  				}
  			}
  			if (!head)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
860
  				pr_cont(", bud of jhead %s",
be9e62a73   Artem Bityutskiy   UBIFS: improve lp...
861
862
863
864
  				       dbg_jhead(bud->jhead));
  		}
  	}
  	if (lp->lnum == c->gc_lnum)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
865
866
867
  		pr_cont(", GC LEB");
  	pr_cont(")
  ");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
868
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
869
  void ubifs_dump_lprops(struct ubifs_info *c)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
870
871
872
873
  {
  	int lnum, err;
  	struct ubifs_lprops lp;
  	struct ubifs_lp_stats lst;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
874
875
  	pr_err("(pid %d) start dumping LEB properties
  ", current->pid);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
876
  	ubifs_get_lp_stats(c, &lst);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
877
  	ubifs_dump_lstats(&lst);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
878
879
880
  
  	for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) {
  		err = ubifs_read_one_lp(c, lnum, &lp);
dac369814   hujianyang   UBIFS: Fix dump m...
881
  		if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
882
  			ubifs_err(c, "cannot read lprops for LEB %d", lnum);
dac369814   hujianyang   UBIFS: Fix dump m...
883
884
  			continue;
  		}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
885

edf6be245   Artem Bityutskiy   UBIFS: rename dum...
886
  		ubifs_dump_lprop(c, &lp);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
887
  	}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
888
889
  	pr_err("(pid %d) finish dumping LEB properties
  ", current->pid);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
890
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
891
  void ubifs_dump_lpt_info(struct ubifs_info *c)
73944a6de   Adrian Hunter   UBIFS: add more d...
892
893
894
895
  {
  	int i;
  
  	spin_lock(&dbg_lock);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
  	pr_err("(pid %d) dumping LPT information
  ", current->pid);
  	pr_err("\tlpt_sz:        %lld
  ", c->lpt_sz);
  	pr_err("\tpnode_sz:      %d
  ", c->pnode_sz);
  	pr_err("\tnnode_sz:      %d
  ", c->nnode_sz);
  	pr_err("\tltab_sz:       %d
  ", c->ltab_sz);
  	pr_err("\tlsave_sz:      %d
  ", c->lsave_sz);
  	pr_err("\tbig_lpt:       %d
  ", c->big_lpt);
  	pr_err("\tlpt_hght:      %d
  ", c->lpt_hght);
  	pr_err("\tpnode_cnt:     %d
  ", c->pnode_cnt);
  	pr_err("\tnnode_cnt:     %d
  ", c->nnode_cnt);
  	pr_err("\tdirty_pn_cnt:  %d
  ", c->dirty_pn_cnt);
  	pr_err("\tdirty_nn_cnt:  %d
  ", c->dirty_nn_cnt);
  	pr_err("\tlsave_cnt:     %d
  ", c->lsave_cnt);
  	pr_err("\tspace_bits:    %d
  ", c->space_bits);
  	pr_err("\tlpt_lnum_bits: %d
  ", c->lpt_lnum_bits);
  	pr_err("\tlpt_offs_bits: %d
  ", c->lpt_offs_bits);
  	pr_err("\tlpt_spc_bits:  %d
  ", c->lpt_spc_bits);
  	pr_err("\tpcnt_bits:     %d
  ", c->pcnt_bits);
  	pr_err("\tlnum_bits:     %d
  ", c->lnum_bits);
  	pr_err("\tLPT root is at %d:%d
  ", c->lpt_lnum, c->lpt_offs);
  	pr_err("\tLPT head is at %d:%d
  ",
73944a6de   Adrian Hunter   UBIFS: add more d...
938
  	       c->nhead_lnum, c->nhead_offs);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
939
940
  	pr_err("\tLPT ltab is at %d:%d
  ", c->ltab_lnum, c->ltab_offs);
73944a6de   Adrian Hunter   UBIFS: add more d...
941
  	if (c->big_lpt)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
942
943
  		pr_err("\tLPT lsave is at %d:%d
  ",
73944a6de   Adrian Hunter   UBIFS: add more d...
944
945
  		       c->lsave_lnum, c->lsave_offs);
  	for (i = 0; i < c->lpt_lebs; i++)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
946
947
  		pr_err("\tLPT LEB %d free %d dirty %d tgc %d cmt %d
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
948
949
  		       i + c->lpt_first, c->ltab[i].free, c->ltab[i].dirty,
  		       c->ltab[i].tgc, c->ltab[i].cmt);
73944a6de   Adrian Hunter   UBIFS: add more d...
950
951
  	spin_unlock(&dbg_lock);
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
952
953
  void ubifs_dump_sleb(const struct ubifs_info *c,
  		     const struct ubifs_scan_leb *sleb, int offs)
d37854cf9   Artem Bityutskiy   UBIFS: introduce ...
954
955
  {
  	struct ubifs_scan_node *snod;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
956
957
  	pr_err("(pid %d) start dumping scanned data from LEB %d:%d
  ",
d37854cf9   Artem Bityutskiy   UBIFS: introduce ...
958
959
960
961
  	       current->pid, sleb->lnum, offs);
  
  	list_for_each_entry(snod, &sleb->nodes, list) {
  		cond_resched();
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
962
963
  		pr_err("Dumping node at LEB %d:%d len %d
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
964
  		       sleb->lnum, snod->offs, snod->len);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
965
  		ubifs_dump_node(c, snod->node);
d37854cf9   Artem Bityutskiy   UBIFS: introduce ...
966
967
  	}
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
968
  void ubifs_dump_leb(const struct ubifs_info *c, int lnum)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
969
970
971
  {
  	struct ubifs_scan_leb *sleb;
  	struct ubifs_scan_node *snod;
73d9aec3f   Artem Bityutskiy   UBIFS: allocate d...
972
  	void *buf;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
973

6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
974
975
  	pr_err("(pid %d) start dumping LEB %d
  ", current->pid, lnum);
73d9aec3f   Artem Bityutskiy   UBIFS: allocate d...
976

fc5e58c0c   Artem Bityutskiy   UBIFS: use GFP_NO...
977
  	buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
73d9aec3f   Artem Bityutskiy   UBIFS: allocate d...
978
  	if (!buf) {
235c362bd   Sheng Yong   UBIFS: extend deb...
979
  		ubifs_err(c, "cannot allocate memory for dumping LEB %d", lnum);
73d9aec3f   Artem Bityutskiy   UBIFS: allocate d...
980
981
982
983
  		return;
  	}
  
  	sleb = ubifs_scan(c, lnum, 0, buf, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
984
  	if (IS_ERR(sleb)) {
235c362bd   Sheng Yong   UBIFS: extend deb...
985
  		ubifs_err(c, "scan error %d", (int)PTR_ERR(sleb));
73d9aec3f   Artem Bityutskiy   UBIFS: allocate d...
986
  		goto out;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
987
  	}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
988
989
  	pr_err("LEB %d has %d nodes ending at %d
  ", lnum,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
990
991
992
993
  	       sleb->nodes_cnt, sleb->endpt);
  
  	list_for_each_entry(snod, &sleb->nodes, list) {
  		cond_resched();
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
994
995
  		pr_err("Dumping node at LEB %d:%d len %d
  ", lnum,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
996
  		       snod->offs, snod->len);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
997
  		ubifs_dump_node(c, snod->node);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
998
  	}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
999
1000
  	pr_err("(pid %d) finish dumping LEB %d
  ", current->pid, lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1001
  	ubifs_scan_destroy(sleb);
73d9aec3f   Artem Bityutskiy   UBIFS: allocate d...
1002
1003
1004
  
  out:
  	vfree(buf);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1005
1006
  	return;
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1007
1008
  void ubifs_dump_znode(const struct ubifs_info *c,
  		      const struct ubifs_znode *znode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1009
1010
1011
  {
  	int n;
  	const struct ubifs_zbranch *zbr;
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
1012
  	char key_buf[DBG_KEY_BUF_LEN];
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1013
1014
1015
1016
1017
1018
  
  	spin_lock(&dbg_lock);
  	if (znode->parent)
  		zbr = &znode->parent->zbranch[znode->iip];
  	else
  		zbr = &c->zroot;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1019
1020
  	pr_err("znode %p, LEB %d:%d len %d parent %p iip %d level %d child_cnt %d flags %lx
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1021
1022
  	       znode, zbr->lnum, zbr->offs, zbr->len, znode->parent, znode->iip,
  	       znode->level, znode->child_cnt, znode->flags);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1023
1024
1025
1026
1027
  
  	if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) {
  		spin_unlock(&dbg_lock);
  		return;
  	}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1028
1029
  	pr_err("zbranches:
  ");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1030
1031
1032
  	for (n = 0; n < znode->child_cnt; n++) {
  		zbr = &znode->zbranch[n];
  		if (znode->level > 0)
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1033
1034
  			pr_err("\t%d: znode %p LEB %d:%d len %d key %s
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1035
1036
1037
  			       n, zbr->znode, zbr->lnum, zbr->offs, zbr->len,
  			       dbg_snprintf_key(c, &zbr->key, key_buf,
  						DBG_KEY_BUF_LEN));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1038
  		else
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1039
1040
  			pr_err("\t%d: LNC %p LEB %d:%d len %d key %s
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1041
1042
1043
  			       n, zbr->znode, zbr->lnum, zbr->offs, zbr->len,
  			       dbg_snprintf_key(c, &zbr->key, key_buf,
  						DBG_KEY_BUF_LEN));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1044
1045
1046
  	}
  	spin_unlock(&dbg_lock);
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1047
  void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1048
1049
  {
  	int i;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1050
1051
  	pr_err("(pid %d) start dumping heap cat %d (%d elements)
  ",
1de941590   Artem Bityutskiy   UBIFS: print pid ...
1052
  	       current->pid, cat, heap->cnt);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1053
1054
  	for (i = 0; i < heap->cnt; i++) {
  		struct ubifs_lprops *lprops = heap->arr[i];
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1055
1056
  		pr_err("\t%d. LEB %d hpos %d free %d dirty %d flags %d
  ",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1057
1058
  		       i, lprops->lnum, lprops->hpos, lprops->free,
  		       lprops->dirty, lprops->flags);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1059
  	}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1060
1061
  	pr_err("(pid %d) finish dumping heap
  ", current->pid);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1062
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1063
1064
  void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
  		      struct ubifs_nnode *parent, int iip)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1065
1066
  {
  	int i;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1067
1068
1069
1070
  	pr_err("(pid %d) dumping pnode:
  ", current->pid);
  	pr_err("\taddress %zx parent %zx cnext %zx
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1071
  	       (size_t)pnode, (size_t)parent, (size_t)pnode->cnext);
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1072
1073
  	pr_err("\tflags %lu iip %d level %d num %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1074
1075
1076
  	       pnode->flags, iip, pnode->level, pnode->num);
  	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
  		struct ubifs_lprops *lp = &pnode->lprops[i];
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1077
1078
  		pr_err("\t%d: free %d dirty %d flags %d lnum %d
  ",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1079
1080
1081
  		       i, lp->free, lp->dirty, lp->flags, lp->lnum);
  	}
  }
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1082
  void ubifs_dump_tnc(struct ubifs_info *c)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1083
1084
1085
  {
  	struct ubifs_znode *znode;
  	int level;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1086
1087
1088
1089
  	pr_err("
  ");
  	pr_err("(pid %d) start dumping TNC tree
  ", current->pid);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1090
1091
  	znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL);
  	level = znode->level;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1092
1093
  	pr_err("== Level %d ==
  ", level);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1094
1095
1096
  	while (znode) {
  		if (level != znode->level) {
  			level = znode->level;
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1097
1098
  			pr_err("== Level %d ==
  ", level);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1099
  		}
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1100
  		ubifs_dump_znode(c, znode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1101
1102
  		znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
  	}
6b38d03f4   Artem Bityutskiy   UBIFS: use pr_ he...
1103
1104
  	pr_err("(pid %d) finish dumping TNC tree
  ", current->pid);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1105
1106
1107
1108
1109
  }
  
  static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode,
  		      void *priv)
  {
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1110
  	ubifs_dump_znode(c, znode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1111
1112
1113
1114
  	return 0;
  }
  
  /**
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1115
   * ubifs_dump_index - dump the on-flash index.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1116
1117
   * @c: UBIFS file-system description object
   *
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1118
   * This function dumps whole UBIFS indexing B-tree, unlike 'ubifs_dump_tnc()'
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1119
1120
   * which dumps only in-memory znodes and does not read znodes which from flash.
   */
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1121
  void ubifs_dump_index(struct ubifs_info *c)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1122
1123
1124
1125
1126
  {
  	dbg_walk_index(c, NULL, dump_znode, NULL);
  }
  
  /**
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1127
1128
1129
1130
1131
1132
1133
1134
1135
   * dbg_save_space_info - save information about flash space.
   * @c: UBIFS file-system description object
   *
   * This function saves information about UBIFS free space, dirty space, etc, in
   * order to check it later.
   */
  void dbg_save_space_info(struct ubifs_info *c)
  {
  	struct ubifs_debug_info *d = c->dbg;
7da6443ac   Artem Bityutskiy   UBIFS: fix debugg...
1136
  	int freeable_cnt;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1137
1138
  
  	spin_lock(&c->space_lock);
7da6443ac   Artem Bityutskiy   UBIFS: fix debugg...
1139
  	memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats));
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
1140
1141
  	memcpy(&d->saved_bi, &c->bi, sizeof(struct ubifs_budg_info));
  	d->saved_idx_gc_cnt = c->idx_gc_cnt;
7da6443ac   Artem Bityutskiy   UBIFS: fix debugg...
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
  
  	/*
  	 * We use a dirty hack here and zero out @c->freeable_cnt, because it
  	 * affects the free space calculations, and UBIFS might not know about
  	 * all freeable eraseblocks. Indeed, we know about freeable eraseblocks
  	 * only when we read their lprops, and we do this only lazily, upon the
  	 * need. So at any given point of time @c->freeable_cnt might be not
  	 * exactly accurate.
  	 *
  	 * Just one example about the issue we hit when we did not zero
  	 * @c->freeable_cnt.
  	 * 1. The file-system is mounted R/O, c->freeable_cnt is %0. We save the
  	 *    amount of free space in @d->saved_free
  	 * 2. We re-mount R/W, which makes UBIFS to read the "lsave"
  	 *    information from flash, where we cache LEBs from various
  	 *    categories ('ubifs_remount_fs()' -> 'ubifs_lpt_init()'
  	 *    -> 'lpt_init_wr()' -> 'read_lsave()' -> 'ubifs_lpt_lookup()'
  	 *    -> 'ubifs_get_pnode()' -> 'update_cats()'
  	 *    -> 'ubifs_add_to_cat()').
  	 * 3. Lsave contains a freeable eraseblock, and @c->freeable_cnt
  	 *    becomes %1.
  	 * 4. We calculate the amount of free space when the re-mount is
  	 *    finished in 'dbg_check_space_info()' and it does not match
  	 *    @d->saved_free.
  	 */
  	freeable_cnt = c->freeable_cnt;
  	c->freeable_cnt = 0;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1169
  	d->saved_free = ubifs_get_free_space_nolock(c);
7da6443ac   Artem Bityutskiy   UBIFS: fix debugg...
1170
  	c->freeable_cnt = freeable_cnt;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
  	spin_unlock(&c->space_lock);
  }
  
  /**
   * dbg_check_space_info - check flash space information.
   * @c: UBIFS file-system description object
   *
   * This function compares current flash space information with the information
   * which was saved when the 'dbg_save_space_info()' function was called.
   * Returns zero if the information has not changed, and %-EINVAL it it has
   * changed.
   */
  int dbg_check_space_info(struct ubifs_info *c)
  {
  	struct ubifs_debug_info *d = c->dbg;
  	struct ubifs_lp_stats lst;
7da6443ac   Artem Bityutskiy   UBIFS: fix debugg...
1187
1188
  	long long free;
  	int freeable_cnt;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1189
1190
  
  	spin_lock(&c->space_lock);
7da6443ac   Artem Bityutskiy   UBIFS: fix debugg...
1191
1192
1193
1194
  	freeable_cnt = c->freeable_cnt;
  	c->freeable_cnt = 0;
  	free = ubifs_get_free_space_nolock(c);
  	c->freeable_cnt = freeable_cnt;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1195
  	spin_unlock(&c->space_lock);
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1196
1197
  
  	if (free != d->saved_free) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1198
  		ubifs_err(c, "free space changed from %lld to %lld",
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1199
1200
1201
1202
1203
1204
1205
  			  d->saved_free, free);
  		goto out;
  	}
  
  	return 0;
  
  out:
235c362bd   Sheng Yong   UBIFS: extend deb...
1206
  	ubifs_msg(c, "saved lprops statistics dump");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1207
  	ubifs_dump_lstats(&d->saved_lst);
235c362bd   Sheng Yong   UBIFS: extend deb...
1208
  	ubifs_msg(c, "saved budgeting info dump");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1209
  	ubifs_dump_budg(c, &d->saved_bi);
235c362bd   Sheng Yong   UBIFS: extend deb...
1210
1211
  	ubifs_msg(c, "saved idx_gc_cnt %d", d->saved_idx_gc_cnt);
  	ubifs_msg(c, "current lprops statistics dump");
f1bd66afb   Artem Bityutskiy   UBIFS: improve sp...
1212
  	ubifs_get_lp_stats(c, &lst);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1213
  	ubifs_dump_lstats(&lst);
235c362bd   Sheng Yong   UBIFS: extend deb...
1214
  	ubifs_msg(c, "current budgeting info dump");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1215
  	ubifs_dump_budg(c, &c->bi);
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
1216
1217
1218
1219
1220
  	dump_stack();
  	return -EINVAL;
  }
  
  /**
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1221
   * dbg_check_synced_i_size - check synchronized inode size.
d808efb40   Artem Bityutskiy   UBIFS: amend debu...
1222
   * @c: UBIFS file-system description object
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1223
1224
1225
1226
1227
1228
1229
   * @inode: inode to check
   *
   * If inode is clean, synchronized inode size has to be equivalent to current
   * inode size. This function has to be called only for locked inodes (@i_mutex
   * has to be locked). Returns %0 if synchronized inode size if correct, and
   * %-EINVAL if not.
   */
d808efb40   Artem Bityutskiy   UBIFS: amend debu...
1230
  int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1231
1232
1233
  {
  	int err = 0;
  	struct ubifs_inode *ui = ubifs_inode(inode);
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
1234
  	if (!dbg_is_chk_gen(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1235
1236
1237
1238
1239
1240
1241
  		return 0;
  	if (!S_ISREG(inode->i_mode))
  		return 0;
  
  	mutex_lock(&ui->ui_mutex);
  	spin_lock(&ui->ui_lock);
  	if (ui->ui_size != ui->synced_i_size && !ui->dirty) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1242
  		ubifs_err(c, "ui_size is %lld, synced_i_size is %lld, but inode is clean",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1243
  			  ui->ui_size, ui->synced_i_size);
235c362bd   Sheng Yong   UBIFS: extend deb...
1244
  		ubifs_err(c, "i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1245
  			  inode->i_mode, i_size_read(inode));
7c46d0ae2   Artem Bityutskiy   UBIFS: get rid of...
1246
  		dump_stack();
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
  		err = -EINVAL;
  	}
  	spin_unlock(&ui->ui_lock);
  	mutex_unlock(&ui->ui_mutex);
  	return err;
  }
  
  /*
   * dbg_check_dir - check directory inode size and link count.
   * @c: UBIFS file-system description object
   * @dir: the directory to calculate size for
   * @size: the result is returned here
   *
   * This function makes sure that directory size and link count are correct.
   * Returns zero in case of success and a negative error code in case of
   * failure.
   *
   * Note, it is good idea to make sure the @dir->i_mutex is locked before
   * calling this function.
   */
1b51e9836   Artem Bityutskiy   UBIFS: rename dbg...
1267
  int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1268
1269
1270
1271
  {
  	unsigned int nlink = 2;
  	union ubifs_key key;
  	struct ubifs_dent_node *dent, *pdent = NULL;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1272
  	struct fscrypt_name nm = {0};
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1273
  	loff_t size = UBIFS_INO_NODE_SZ;
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
1274
  	if (!dbg_is_chk_gen(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
  		return 0;
  
  	if (!S_ISDIR(dir->i_mode))
  		return 0;
  
  	lowest_dent_key(c, &key, dir->i_ino);
  	while (1) {
  		int err;
  
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			err = PTR_ERR(dent);
  			if (err == -ENOENT)
  				break;
  			return err;
  		}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1291
1292
1293
  		fname_name(&nm) = dent->name;
  		fname_len(&nm) = le16_to_cpu(dent->nlen);
  		size += CALC_DENT_SIZE(fname_len(&nm));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1294
1295
1296
1297
1298
1299
1300
1301
1302
  		if (dent->type == UBIFS_ITYPE_DIR)
  			nlink += 1;
  		kfree(pdent);
  		pdent = dent;
  		key_read(c, &dent->key, &key);
  	}
  	kfree(pdent);
  
  	if (i_size_read(dir) != size) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1303
  		ubifs_err(c, "directory inode %lu has size %llu, but calculated size is %llu",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1304
  			  dir->i_ino, (unsigned long long)i_size_read(dir),
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1305
  			  (unsigned long long)size);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1306
  		ubifs_dump_inode(c, dir);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1307
1308
1309
1310
  		dump_stack();
  		return -EINVAL;
  	}
  	if (dir->i_nlink != nlink) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1311
  		ubifs_err(c, "directory inode %lu has nlink %u, but calculated nlink is %u",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1312
  			  dir->i_ino, dir->i_nlink, nlink);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1313
  		ubifs_dump_inode(c, dir);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
  		dump_stack();
  		return -EINVAL;
  	}
  
  	return 0;
  }
  
  /**
   * dbg_check_key_order - make sure that colliding keys are properly ordered.
   * @c: UBIFS file-system description object
   * @zbr1: first zbranch
   * @zbr2: following zbranch
   *
   * In UBIFS indexing B-tree colliding keys has to be sorted in binary order of
   * names of the direntries/xentries which are referred by the keys. This
   * function reads direntries/xentries referred by @zbr1 and @zbr2 and makes
   * sure the name of direntry/xentry referred by @zbr1 is less than
   * direntry/xentry referred by @zbr2. Returns zero if this is true, %1 if not,
   * and a negative error code in case of failure.
   */
  static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
  			       struct ubifs_zbranch *zbr2)
  {
  	int err, nlen1, nlen2, cmp;
  	struct ubifs_dent_node *dent1, *dent2;
  	union ubifs_key key;
515315a12   Artem Bityutskiy   UBIFS: fix key pr...
1340
  	char key_buf[DBG_KEY_BUF_LEN];
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
  
  	ubifs_assert(!keys_cmp(c, &zbr1->key, &zbr2->key));
  	dent1 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
  	if (!dent1)
  		return -ENOMEM;
  	dent2 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
  	if (!dent2) {
  		err = -ENOMEM;
  		goto out_free;
  	}
  
  	err = ubifs_tnc_read_node(c, zbr1, dent1);
  	if (err)
  		goto out_free;
  	err = ubifs_validate_entry(c, dent1);
  	if (err)
  		goto out_free;
  
  	err = ubifs_tnc_read_node(c, zbr2, dent2);
  	if (err)
  		goto out_free;
  	err = ubifs_validate_entry(c, dent2);
  	if (err)
  		goto out_free;
  
  	/* Make sure node keys are the same as in zbranch */
  	err = 1;
  	key_read(c, &dent1->key, &key);
  	if (keys_cmp(c, &zbr1->key, &key)) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1370
  		ubifs_err(c, "1st entry at %d:%d has key %s", zbr1->lnum,
a6aae4dd0   Artem Bityutskiy   UBIFS: get rid of...
1371
1372
  			  zbr1->offs, dbg_snprintf_key(c, &key, key_buf,
  						       DBG_KEY_BUF_LEN));
235c362bd   Sheng Yong   UBIFS: extend deb...
1373
  		ubifs_err(c, "but it should have key %s according to tnc",
a6aae4dd0   Artem Bityutskiy   UBIFS: get rid of...
1374
1375
  			  dbg_snprintf_key(c, &zbr1->key, key_buf,
  					   DBG_KEY_BUF_LEN));
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1376
  		ubifs_dump_node(c, dent1);
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
1377
  		goto out_free;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1378
1379
1380
1381
  	}
  
  	key_read(c, &dent2->key, &key);
  	if (keys_cmp(c, &zbr2->key, &key)) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1382
  		ubifs_err(c, "2nd entry at %d:%d has key %s", zbr1->lnum,
a6aae4dd0   Artem Bityutskiy   UBIFS: get rid of...
1383
1384
  			  zbr1->offs, dbg_snprintf_key(c, &key, key_buf,
  						       DBG_KEY_BUF_LEN));
235c362bd   Sheng Yong   UBIFS: extend deb...
1385
  		ubifs_err(c, "but it should have key %s according to tnc",
a6aae4dd0   Artem Bityutskiy   UBIFS: get rid of...
1386
1387
  			  dbg_snprintf_key(c, &zbr2->key, key_buf,
  					   DBG_KEY_BUF_LEN));
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1388
  		ubifs_dump_node(c, dent2);
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
1389
  		goto out_free;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  	}
  
  	nlen1 = le16_to_cpu(dent1->nlen);
  	nlen2 = le16_to_cpu(dent2->nlen);
  
  	cmp = memcmp(dent1->name, dent2->name, min_t(int, nlen1, nlen2));
  	if (cmp < 0 || (cmp == 0 && nlen1 < nlen2)) {
  		err = 0;
  		goto out_free;
  	}
  	if (cmp == 0 && nlen1 == nlen2)
235c362bd   Sheng Yong   UBIFS: extend deb...
1401
  		ubifs_err(c, "2 xent/dent nodes with the same name");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1402
  	else
235c362bd   Sheng Yong   UBIFS: extend deb...
1403
  		ubifs_err(c, "bad order of colliding key %s",
a6aae4dd0   Artem Bityutskiy   UBIFS: get rid of...
1404
  			  dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1405

235c362bd   Sheng Yong   UBIFS: extend deb...
1406
1407
  	ubifs_msg(c, "first node at %d:%d
  ", zbr1->lnum, zbr1->offs);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1408
  	ubifs_dump_node(c, dent1);
235c362bd   Sheng Yong   UBIFS: extend deb...
1409
1410
  	ubifs_msg(c, "second node at %d:%d
  ", zbr2->lnum, zbr2->offs);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1411
  	ubifs_dump_node(c, dent2);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
  
  out_free:
  	kfree(dent2);
  	kfree(dent1);
  	return err;
  }
  
  /**
   * dbg_check_znode - check if znode is all right.
   * @c: UBIFS file-system description object
   * @zbr: zbranch which points to this znode
   *
   * This function makes sure that znode referred to by @zbr is all right.
   * Returns zero if it is, and %-EINVAL if it is not.
   */
  static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr)
  {
  	struct ubifs_znode *znode = zbr->znode;
  	struct ubifs_znode *zp = znode->parent;
  	int n, err, cmp;
  
  	if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) {
  		err = 1;
  		goto out;
  	}
  	if (znode->level < 0) {
  		err = 2;
  		goto out;
  	}
  	if (znode->iip < 0 || znode->iip >= c->fanout) {
  		err = 3;
  		goto out;
  	}
  
  	if (zbr->len == 0)
  		/* Only dirty zbranch may have no on-flash nodes */
  		if (!ubifs_zn_dirty(znode)) {
  			err = 4;
  			goto out;
  		}
  
  	if (ubifs_zn_dirty(znode)) {
  		/*
  		 * If znode is dirty, its parent has to be dirty as well. The
  		 * order of the operation is important, so we have to have
  		 * memory barriers.
  		 */
  		smp_mb();
  		if (zp && !ubifs_zn_dirty(zp)) {
  			/*
  			 * The dirty flag is atomic and is cleared outside the
  			 * TNC mutex, so znode's dirty flag may now have
  			 * been cleared. The child is always cleared before the
  			 * parent, so we just need to check again.
  			 */
  			smp_mb();
  			if (ubifs_zn_dirty(znode)) {
  				err = 5;
  				goto out;
  			}
  		}
  	}
  
  	if (zp) {
  		const union ubifs_key *min, *max;
  
  		if (znode->level != zp->level - 1) {
  			err = 6;
  			goto out;
  		}
  
  		/* Make sure the 'parent' pointer in our znode is correct */
  		err = ubifs_search_zbranch(c, zp, &zbr->key, &n);
  		if (!err) {
  			/* This zbranch does not exist in the parent */
  			err = 7;
  			goto out;
  		}
  
  		if (znode->iip >= zp->child_cnt) {
  			err = 8;
  			goto out;
  		}
  
  		if (znode->iip != n) {
  			/* This may happen only in case of collisions */
  			if (keys_cmp(c, &zp->zbranch[n].key,
  				     &zp->zbranch[znode->iip].key)) {
  				err = 9;
  				goto out;
  			}
  			n = znode->iip;
  		}
  
  		/*
  		 * Make sure that the first key in our znode is greater than or
  		 * equal to the key in the pointing zbranch.
  		 */
  		min = &zbr->key;
  		cmp = keys_cmp(c, min, &znode->zbranch[0].key);
  		if (cmp == 1) {
  			err = 10;
  			goto out;
  		}
  
  		if (n + 1 < zp->child_cnt) {
  			max = &zp->zbranch[n + 1].key;
  
  			/*
  			 * Make sure the last key in our znode is less or
7d4e9ccb4   Artem Bityutskiy   UBIFS: fix commen...
1522
  			 * equivalent than the key in the zbranch which goes
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
  			 * after our pointing zbranch.
  			 */
  			cmp = keys_cmp(c, max,
  				&znode->zbranch[znode->child_cnt - 1].key);
  			if (cmp == -1) {
  				err = 11;
  				goto out;
  			}
  		}
  	} else {
  		/* This may only be root znode */
  		if (zbr != &c->zroot) {
  			err = 12;
  			goto out;
  		}
  	}
  
  	/*
  	 * Make sure that next key is greater or equivalent then the previous
  	 * one.
  	 */
  	for (n = 1; n < znode->child_cnt; n++) {
  		cmp = keys_cmp(c, &znode->zbranch[n - 1].key,
  			       &znode->zbranch[n].key);
  		if (cmp > 0) {
  			err = 13;
  			goto out;
  		}
  		if (cmp == 0) {
  			/* This can only be keys with colliding hash */
  			if (!is_hash_key(c, &znode->zbranch[n].key)) {
  				err = 14;
  				goto out;
  			}
  
  			if (znode->level != 0 || c->replaying)
  				continue;
  
  			/*
  			 * Colliding keys should follow binary order of
  			 * corresponding xentry/dentry names.
  			 */
  			err = dbg_check_key_order(c, &znode->zbranch[n - 1],
  						  &znode->zbranch[n]);
  			if (err < 0)
  				return err;
  			if (err) {
  				err = 15;
  				goto out;
  			}
  		}
  	}
  
  	for (n = 0; n < znode->child_cnt; n++) {
  		if (!znode->zbranch[n].znode &&
  		    (znode->zbranch[n].lnum == 0 ||
  		     znode->zbranch[n].len == 0)) {
  			err = 16;
  			goto out;
  		}
  
  		if (znode->zbranch[n].lnum != 0 &&
  		    znode->zbranch[n].len == 0) {
  			err = 17;
  			goto out;
  		}
  
  		if (znode->zbranch[n].lnum == 0 &&
  		    znode->zbranch[n].len != 0) {
  			err = 18;
  			goto out;
  		}
  
  		if (znode->zbranch[n].lnum == 0 &&
  		    znode->zbranch[n].offs != 0) {
  			err = 19;
  			goto out;
  		}
  
  		if (znode->level != 0 && znode->zbranch[n].znode)
  			if (znode->zbranch[n].znode->parent != znode) {
  				err = 20;
  				goto out;
  			}
  	}
  
  	return 0;
  
  out:
235c362bd   Sheng Yong   UBIFS: extend deb...
1612
1613
  	ubifs_err(c, "failed, error %d", err);
  	ubifs_msg(c, "dump of the znode");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1614
  	ubifs_dump_znode(c, znode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1615
  	if (zp) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1616
  		ubifs_msg(c, "dump of the parent znode");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1617
  		ubifs_dump_znode(c, zp);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
  	}
  	dump_stack();
  	return -EINVAL;
  }
  
  /**
   * dbg_check_tnc - check TNC tree.
   * @c: UBIFS file-system description object
   * @extra: do extra checks that are possible at start commit
   *
   * This function traverses whole TNC tree and checks every znode. Returns zero
   * if everything is all right and %-EINVAL if something is wrong with TNC.
   */
  int dbg_check_tnc(struct ubifs_info *c, int extra)
  {
  	struct ubifs_znode *znode;
  	long clean_cnt = 0, dirty_cnt = 0;
  	int err, last;
8d7819b4a   Artem Bityutskiy   UBIFS: lessen amo...
1636
  	if (!dbg_is_chk_index(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
  		return 0;
  
  	ubifs_assert(mutex_is_locked(&c->tnc_mutex));
  	if (!c->zroot.znode)
  		return 0;
  
  	znode = ubifs_tnc_postorder_first(c->zroot.znode);
  	while (1) {
  		struct ubifs_znode *prev;
  		struct ubifs_zbranch *zbr;
  
  		if (!znode->parent)
  			zbr = &c->zroot;
  		else
  			zbr = &znode->parent->zbranch[znode->iip];
  
  		err = dbg_check_znode(c, zbr);
  		if (err)
  			return err;
  
  		if (extra) {
  			if (ubifs_zn_dirty(znode))
  				dirty_cnt += 1;
  			else
  				clean_cnt += 1;
  		}
  
  		prev = znode;
  		znode = ubifs_tnc_postorder_next(znode);
  		if (!znode)
  			break;
  
  		/*
  		 * If the last key of this znode is equivalent to the first key
  		 * of the next znode (collision), then check order of the keys.
  		 */
  		last = prev->child_cnt - 1;
  		if (prev->level == 0 && znode->level == 0 && !c->replaying &&
  		    !keys_cmp(c, &prev->zbranch[last].key,
  			      &znode->zbranch[0].key)) {
  			err = dbg_check_key_order(c, &prev->zbranch[last],
  						  &znode->zbranch[0]);
  			if (err < 0)
  				return err;
  			if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1682
  				ubifs_msg(c, "first znode");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1683
  				ubifs_dump_znode(c, prev);
235c362bd   Sheng Yong   UBIFS: extend deb...
1684
  				ubifs_msg(c, "second znode");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1685
  				ubifs_dump_znode(c, znode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1686
1687
1688
1689
1690
1691
1692
  				return -EINVAL;
  			}
  		}
  	}
  
  	if (extra) {
  		if (clean_cnt != atomic_long_read(&c->clean_zn_cnt)) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1693
  			ubifs_err(c, "incorrect clean_zn_cnt %ld, calculated %ld",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1694
1695
1696
1697
1698
  				  atomic_long_read(&c->clean_zn_cnt),
  				  clean_cnt);
  			return -EINVAL;
  		}
  		if (dirty_cnt != atomic_long_read(&c->dirty_zn_cnt)) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1699
  			ubifs_err(c, "incorrect dirty_zn_cnt %ld, calculated %ld",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  				  atomic_long_read(&c->dirty_zn_cnt),
  				  dirty_cnt);
  			return -EINVAL;
  		}
  	}
  
  	return 0;
  }
  
  /**
   * dbg_walk_index - walk the on-flash index.
   * @c: UBIFS file-system description object
   * @leaf_cb: called for each leaf node
   * @znode_cb: called for each indexing node
227c75c91   Adrian Hunter   UBIFS: spelling f...
1714
   * @priv: private data which is passed to callbacks
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
   *
   * This function walks the UBIFS index and calls the @leaf_cb for each leaf
   * node and @znode_cb for each indexing node. Returns zero in case of success
   * and a negative error code in case of failure.
   *
   * It would be better if this function removed every znode it pulled to into
   * the TNC, so that the behavior more closely matched the non-debugging
   * behavior.
   */
  int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb,
  		   dbg_znode_callback znode_cb, void *priv)
  {
  	int err;
  	struct ubifs_zbranch *zbr;
  	struct ubifs_znode *znode, *child;
  
  	mutex_lock(&c->tnc_mutex);
  	/* If the root indexing node is not in TNC - pull it */
  	if (!c->zroot.znode) {
  		c->zroot.znode = ubifs_load_znode(c, &c->zroot, NULL, 0);
  		if (IS_ERR(c->zroot.znode)) {
  			err = PTR_ERR(c->zroot.znode);
  			c->zroot.znode = NULL;
  			goto out_unlock;
  		}
  	}
  
  	/*
  	 * We are going to traverse the indexing tree in the postorder manner.
  	 * Go down and find the leftmost indexing node where we are going to
  	 * start from.
  	 */
  	znode = c->zroot.znode;
  	while (znode->level > 0) {
  		zbr = &znode->zbranch[0];
  		child = zbr->znode;
  		if (!child) {
  			child = ubifs_load_znode(c, zbr, znode, 0);
  			if (IS_ERR(child)) {
  				err = PTR_ERR(child);
  				goto out_unlock;
  			}
  			zbr->znode = child;
  		}
  
  		znode = child;
  	}
  
  	/* Iterate over all indexing nodes */
  	while (1) {
  		int idx;
  
  		cond_resched();
  
  		if (znode_cb) {
  			err = znode_cb(c, znode, priv);
  			if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1772
  				ubifs_err(c, "znode checking function returned error %d",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1773
  					  err);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1774
  				ubifs_dump_znode(c, znode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1775
1776
1777
1778
1779
1780
1781
1782
  				goto out_dump;
  			}
  		}
  		if (leaf_cb && znode->level == 0) {
  			for (idx = 0; idx < znode->child_cnt; idx++) {
  				zbr = &znode->zbranch[idx];
  				err = leaf_cb(c, zbr, priv);
  				if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1783
  					ubifs_err(c, "leaf checking function returned error %d, for leaf at LEB %d:%d",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
  						  err, zbr->lnum, zbr->offs);
  					goto out_dump;
  				}
  			}
  		}
  
  		if (!znode->parent)
  			break;
  
  		idx = znode->iip + 1;
  		znode = znode->parent;
  		if (idx < znode->child_cnt) {
  			/* Switch to the next index in the parent */
  			zbr = &znode->zbranch[idx];
  			child = zbr->znode;
  			if (!child) {
  				child = ubifs_load_znode(c, zbr, znode, idx);
  				if (IS_ERR(child)) {
  					err = PTR_ERR(child);
  					goto out_unlock;
  				}
  				zbr->znode = child;
  			}
  			znode = child;
  		} else
  			/*
  			 * This is the last child, switch to the parent and
  			 * continue.
  			 */
  			continue;
  
  		/* Go to the lowest leftmost znode in the new sub-tree */
  		while (znode->level > 0) {
  			zbr = &znode->zbranch[0];
  			child = zbr->znode;
  			if (!child) {
  				child = ubifs_load_znode(c, zbr, znode, 0);
  				if (IS_ERR(child)) {
  					err = PTR_ERR(child);
  					goto out_unlock;
  				}
  				zbr->znode = child;
  			}
  			znode = child;
  		}
  	}
  
  	mutex_unlock(&c->tnc_mutex);
  	return 0;
  
  out_dump:
  	if (znode->parent)
  		zbr = &znode->parent->zbranch[znode->iip];
  	else
  		zbr = &c->zroot;
235c362bd   Sheng Yong   UBIFS: extend deb...
1839
  	ubifs_msg(c, "dump of znode at LEB %d:%d", zbr->lnum, zbr->offs);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
1840
  	ubifs_dump_znode(c, znode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
  out_unlock:
  	mutex_unlock(&c->tnc_mutex);
  	return err;
  }
  
  /**
   * add_size - add znode size to partially calculated index size.
   * @c: UBIFS file-system description object
   * @znode: znode to add size for
   * @priv: partially calculated index size
   *
   * This is a helper function for 'dbg_check_idx_size()' which is called for
   * every indexing node and adds its size to the 'long long' variable pointed to
   * by @priv.
   */
  static int add_size(struct ubifs_info *c, struct ubifs_znode *znode, void *priv)
  {
  	long long *idx_size = priv;
  	int add;
  
  	add = ubifs_idx_node_sz(c, znode->child_cnt);
  	add = ALIGN(add, 8);
  	*idx_size += add;
  	return 0;
  }
  
  /**
   * dbg_check_idx_size - check index size.
   * @c: UBIFS file-system description object
   * @idx_size: size to check
   *
   * This function walks the UBIFS index, calculates its size and checks that the
   * size is equivalent to @idx_size. Returns zero in case of success and a
   * negative error code in case of failure.
   */
  int dbg_check_idx_size(struct ubifs_info *c, long long idx_size)
  {
  	int err;
  	long long calc = 0;
8d7819b4a   Artem Bityutskiy   UBIFS: lessen amo...
1880
  	if (!dbg_is_chk_index(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1881
1882
1883
1884
  		return 0;
  
  	err = dbg_walk_index(c, NULL, add_size, &calc);
  	if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1885
  		ubifs_err(c, "error %d while walking the index", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1886
1887
1888
1889
  		return err;
  	}
  
  	if (calc != idx_size) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1890
  		ubifs_err(c, "index size check failed: calculated size is %lld, should be %lld",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
1891
  			  calc, idx_size);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
  		dump_stack();
  		return -EINVAL;
  	}
  
  	return 0;
  }
  
  /**
   * struct fsck_inode - information about an inode used when checking the file-system.
   * @rb: link in the RB-tree of inodes
   * @inum: inode number
   * @mode: inode type, permissions, etc
   * @nlink: inode link count
   * @xattr_cnt: count of extended attributes
   * @references: how many directory/xattr entries refer this inode (calculated
   *              while walking the index)
   * @calc_cnt: for directory inode count of child directories
   * @size: inode size (read from on-flash inode)
   * @xattr_sz: summary size of all extended attributes (read from on-flash
   *            inode)
   * @calc_sz: for directories calculated directory size
   * @calc_xcnt: count of extended attributes
   * @calc_xsz: calculated summary size of all extended attributes
   * @xattr_nms: sum of lengths of all extended attribute names belonging to this
   *             inode (read from on-flash inode)
   * @calc_xnms: calculated sum of lengths of all extended attribute names
   */
  struct fsck_inode {
  	struct rb_node rb;
  	ino_t inum;
  	umode_t mode;
  	unsigned int nlink;
  	unsigned int xattr_cnt;
  	int references;
  	int calc_cnt;
  	long long size;
  	unsigned int xattr_sz;
  	long long calc_sz;
  	long long calc_xcnt;
  	long long calc_xsz;
  	unsigned int xattr_nms;
  	long long calc_xnms;
  };
  
  /**
   * struct fsck_data - private FS checking information.
   * @inodes: RB-tree of all inodes (contains @struct fsck_inode objects)
   */
  struct fsck_data {
  	struct rb_root inodes;
  };
  
  /**
   * add_inode - add inode information to RB-tree of inodes.
   * @c: UBIFS file-system description object
   * @fsckd: FS checking information
   * @ino: raw UBIFS inode to add
   *
   * This is a helper function for 'check_leaf()' which adds information about
   * inode @ino to the RB-tree of inodes. Returns inode information pointer in
   * case of success and a negative error code in case of failure.
   */
  static struct fsck_inode *add_inode(struct ubifs_info *c,
  				    struct fsck_data *fsckd,
  				    struct ubifs_ino_node *ino)
  {
  	struct rb_node **p, *parent = NULL;
  	struct fsck_inode *fscki;
  	ino_t inum = key_inum_flash(c, &ino->key);
45cd5cddb   Artem Bityutskiy   UBIFS: fix debugg...
1961
1962
  	struct inode *inode;
  	struct ubifs_inode *ui;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
  
  	p = &fsckd->inodes.rb_node;
  	while (*p) {
  		parent = *p;
  		fscki = rb_entry(parent, struct fsck_inode, rb);
  		if (inum < fscki->inum)
  			p = &(*p)->rb_left;
  		else if (inum > fscki->inum)
  			p = &(*p)->rb_right;
  		else
  			return fscki;
  	}
  
  	if (inum > c->highest_inum) {
235c362bd   Sheng Yong   UBIFS: extend deb...
1977
  		ubifs_err(c, "too high inode number, max. is %lu",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
1978
  			  (unsigned long)c->highest_inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1979
1980
1981
1982
1983
1984
  		return ERR_PTR(-EINVAL);
  	}
  
  	fscki = kzalloc(sizeof(struct fsck_inode), GFP_NOFS);
  	if (!fscki)
  		return ERR_PTR(-ENOMEM);
45cd5cddb   Artem Bityutskiy   UBIFS: fix debugg...
1985
  	inode = ilookup(c->vfs_sb, inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1986
  	fscki->inum = inum;
45cd5cddb   Artem Bityutskiy   UBIFS: fix debugg...
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
  	/*
  	 * If the inode is present in the VFS inode cache, use it instead of
  	 * the on-flash inode which might be out-of-date. E.g., the size might
  	 * be out-of-date. If we do not do this, the following may happen, for
  	 * example:
  	 *   1. A power cut happens
  	 *   2. We mount the file-system R/O, the replay process fixes up the
  	 *      inode size in the VFS cache, but on on-flash.
  	 *   3. 'check_leaf()' fails because it hits a data node beyond inode
  	 *      size.
  	 */
  	if (!inode) {
  		fscki->nlink = le32_to_cpu(ino->nlink);
  		fscki->size = le64_to_cpu(ino->size);
  		fscki->xattr_cnt = le32_to_cpu(ino->xattr_cnt);
  		fscki->xattr_sz = le32_to_cpu(ino->xattr_size);
  		fscki->xattr_nms = le32_to_cpu(ino->xattr_names);
  		fscki->mode = le32_to_cpu(ino->mode);
  	} else {
  		ui = ubifs_inode(inode);
  		fscki->nlink = inode->i_nlink;
  		fscki->size = inode->i_size;
  		fscki->xattr_cnt = ui->xattr_cnt;
  		fscki->xattr_sz = ui->xattr_size;
  		fscki->xattr_nms = ui->xattr_names;
  		fscki->mode = inode->i_mode;
  		iput(inode);
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2015
2016
2017
2018
  	if (S_ISDIR(fscki->mode)) {
  		fscki->calc_sz = UBIFS_INO_NODE_SZ;
  		fscki->calc_cnt = 2;
  	}
45cd5cddb   Artem Bityutskiy   UBIFS: fix debugg...
2019

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2020
2021
  	rb_link_node(&fscki->rb, parent, p);
  	rb_insert_color(&fscki->rb, &fsckd->inodes);
45cd5cddb   Artem Bityutskiy   UBIFS: fix debugg...
2022

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
  	return fscki;
  }
  
  /**
   * search_inode - search inode in the RB-tree of inodes.
   * @fsckd: FS checking information
   * @inum: inode number to search
   *
   * This is a helper function for 'check_leaf()' which searches inode @inum in
   * the RB-tree of inodes and returns an inode information pointer or %NULL if
   * the inode was not found.
   */
  static struct fsck_inode *search_inode(struct fsck_data *fsckd, ino_t inum)
  {
  	struct rb_node *p;
  	struct fsck_inode *fscki;
  
  	p = fsckd->inodes.rb_node;
  	while (p) {
  		fscki = rb_entry(p, struct fsck_inode, rb);
  		if (inum < fscki->inum)
  			p = p->rb_left;
  		else if (inum > fscki->inum)
  			p = p->rb_right;
  		else
  			return fscki;
  	}
  	return NULL;
  }
  
  /**
   * read_add_inode - read inode node and add it to RB-tree of inodes.
   * @c: UBIFS file-system description object
   * @fsckd: FS checking information
   * @inum: inode number to read
   *
   * This is a helper function for 'check_leaf()' which finds inode node @inum in
   * the index, reads it, and adds it to the RB-tree of inodes. Returns inode
   * information pointer in case of success and a negative error code in case of
   * failure.
   */
  static struct fsck_inode *read_add_inode(struct ubifs_info *c,
  					 struct fsck_data *fsckd, ino_t inum)
  {
  	int n, err;
  	union ubifs_key key;
  	struct ubifs_znode *znode;
  	struct ubifs_zbranch *zbr;
  	struct ubifs_ino_node *ino;
  	struct fsck_inode *fscki;
  
  	fscki = search_inode(fsckd, inum);
  	if (fscki)
  		return fscki;
  
  	ino_key_init(c, &key, inum);
  	err = ubifs_lookup_level0(c, &key, &znode, &n);
  	if (!err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2081
  		ubifs_err(c, "inode %lu not found in index", (unsigned long)inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2082
2083
  		return ERR_PTR(-ENOENT);
  	} else if (err < 0) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2084
  		ubifs_err(c, "error %d while looking up inode %lu",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2085
  			  err, (unsigned long)inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2086
2087
2088
2089
2090
  		return ERR_PTR(err);
  	}
  
  	zbr = &znode->zbranch[n];
  	if (zbr->len < UBIFS_INO_NODE_SZ) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2091
  		ubifs_err(c, "bad node %lu node length %d",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2092
  			  (unsigned long)inum, zbr->len);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2093
2094
2095
2096
2097
2098
2099
2100
2101
  		return ERR_PTR(-EINVAL);
  	}
  
  	ino = kmalloc(zbr->len, GFP_NOFS);
  	if (!ino)
  		return ERR_PTR(-ENOMEM);
  
  	err = ubifs_tnc_read_node(c, zbr, ino);
  	if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2102
  		ubifs_err(c, "cannot read inode node at LEB %d:%d, error %d",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2103
2104
2105
2106
2107
2108
2109
2110
  			  zbr->lnum, zbr->offs, err);
  		kfree(ino);
  		return ERR_PTR(err);
  	}
  
  	fscki = add_inode(c, fsckd, ino);
  	kfree(ino);
  	if (IS_ERR(fscki)) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2111
  		ubifs_err(c, "error %ld while adding inode %lu node",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2112
  			  PTR_ERR(fscki), (unsigned long)inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
  		return fscki;
  	}
  
  	return fscki;
  }
  
  /**
   * check_leaf - check leaf node.
   * @c: UBIFS file-system description object
   * @zbr: zbranch of the leaf node to check
   * @priv: FS checking information
   *
   * This is a helper function for 'dbg_check_filesystem()' which is called for
   * every single leaf node while walking the indexing tree. It checks that the
   * leaf node referred from the indexing tree exists, has correct CRC, and does
   * some other basic validation. This function is also responsible for building
   * an RB-tree of inodes - it adds all inodes into the RB-tree. It also
   * calculates reference count, size, etc for each inode in order to later
   * compare them to the information stored inside the inodes and detect possible
   * inconsistencies. Returns zero in case of success and a negative error code
   * in case of failure.
   */
  static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
  		      void *priv)
  {
  	ino_t inum;
  	void *node;
  	struct ubifs_ch *ch;
  	int err, type = key_type(c, &zbr->key);
  	struct fsck_inode *fscki;
  
  	if (zbr->len < UBIFS_CH_SZ) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2145
  		ubifs_err(c, "bad leaf length %d (LEB %d:%d)",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
  			  zbr->len, zbr->lnum, zbr->offs);
  		return -EINVAL;
  	}
  
  	node = kmalloc(zbr->len, GFP_NOFS);
  	if (!node)
  		return -ENOMEM;
  
  	err = ubifs_tnc_read_node(c, zbr, node);
  	if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2156
  		ubifs_err(c, "cannot read leaf node at LEB %d:%d, error %d",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2157
2158
2159
2160
2161
2162
2163
2164
2165
  			  zbr->lnum, zbr->offs, err);
  		goto out_free;
  	}
  
  	/* If this is an inode node, add it to RB-tree of inodes */
  	if (type == UBIFS_INO_KEY) {
  		fscki = add_inode(c, priv, node);
  		if (IS_ERR(fscki)) {
  			err = PTR_ERR(fscki);
235c362bd   Sheng Yong   UBIFS: extend deb...
2166
  			ubifs_err(c, "error %d while adding inode node", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2167
2168
2169
2170
2171
2172
2173
  			goto out_dump;
  		}
  		goto out;
  	}
  
  	if (type != UBIFS_DENT_KEY && type != UBIFS_XENT_KEY &&
  	    type != UBIFS_DATA_KEY) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2174
  		ubifs_err(c, "unexpected node type %d at LEB %d:%d",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2175
2176
2177
2178
2179
2180
2181
  			  type, zbr->lnum, zbr->offs);
  		err = -EINVAL;
  		goto out_free;
  	}
  
  	ch = node;
  	if (le64_to_cpu(ch->sqnum) > c->max_sqnum) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2182
  		ubifs_err(c, "too high sequence number, max. is %llu",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2183
2184
2185
2186
2187
2188
2189
2190
  			  c->max_sqnum);
  		err = -EINVAL;
  		goto out_dump;
  	}
  
  	if (type == UBIFS_DATA_KEY) {
  		long long blk_offs;
  		struct ubifs_data_node *dn = node;
fb4325a3d   Artem Bityutskiy   UBIFS: add a coup...
2191
  		ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2192
2193
2194
2195
2196
2197
2198
2199
  		/*
  		 * Search the inode node this data node belongs to and insert
  		 * it to the RB-tree of inodes.
  		 */
  		inum = key_inum_flash(c, &dn->key);
  		fscki = read_add_inode(c, priv, inum);
  		if (IS_ERR(fscki)) {
  			err = PTR_ERR(fscki);
235c362bd   Sheng Yong   UBIFS: extend deb...
2200
  			ubifs_err(c, "error %d while processing data node and trying to find inode node %lu",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2201
  				  err, (unsigned long)inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2202
2203
2204
2205
2206
2207
2208
2209
  			goto out_dump;
  		}
  
  		/* Make sure the data node is within inode size */
  		blk_offs = key_block_flash(c, &dn->key);
  		blk_offs <<= UBIFS_BLOCK_SHIFT;
  		blk_offs += le32_to_cpu(dn->size);
  		if (blk_offs > fscki->size) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2210
  			ubifs_err(c, "data node at LEB %d:%d is not within inode size %lld",
79fda5179   Artem Bityutskiy   UBIFS: comply wit...
2211
  				  zbr->lnum, zbr->offs, fscki->size);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2212
2213
2214
2215
2216
2217
2218
  			err = -EINVAL;
  			goto out_dump;
  		}
  	} else {
  		int nlen;
  		struct ubifs_dent_node *dent = node;
  		struct fsck_inode *fscki1;
fb4325a3d   Artem Bityutskiy   UBIFS: add a coup...
2219
  		ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
  		err = ubifs_validate_entry(c, dent);
  		if (err)
  			goto out_dump;
  
  		/*
  		 * Search the inode node this entry refers to and the parent
  		 * inode node and insert them to the RB-tree of inodes.
  		 */
  		inum = le64_to_cpu(dent->inum);
  		fscki = read_add_inode(c, priv, inum);
  		if (IS_ERR(fscki)) {
  			err = PTR_ERR(fscki);
235c362bd   Sheng Yong   UBIFS: extend deb...
2232
  			ubifs_err(c, "error %d while processing entry node and trying to find inode node %lu",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2233
  				  err, (unsigned long)inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2234
2235
2236
2237
2238
2239
2240
2241
2242
  			goto out_dump;
  		}
  
  		/* Count how many direntries or xentries refers this inode */
  		fscki->references += 1;
  
  		inum = key_inum_flash(c, &dent->key);
  		fscki1 = read_add_inode(c, priv, inum);
  		if (IS_ERR(fscki1)) {
b38882f5c   Roel Kluin   UBIFS: fix return...
2243
  			err = PTR_ERR(fscki1);
235c362bd   Sheng Yong   UBIFS: extend deb...
2244
  			ubifs_err(c, "error %d while processing entry node and trying to find parent inode node %lu",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2245
  				  err, (unsigned long)inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
  			goto out_dump;
  		}
  
  		nlen = le16_to_cpu(dent->nlen);
  		if (type == UBIFS_XENT_KEY) {
  			fscki1->calc_xcnt += 1;
  			fscki1->calc_xsz += CALC_DENT_SIZE(nlen);
  			fscki1->calc_xsz += CALC_XATTR_BYTES(fscki->size);
  			fscki1->calc_xnms += nlen;
  		} else {
  			fscki1->calc_sz += CALC_DENT_SIZE(nlen);
  			if (dent->type == UBIFS_ITYPE_DIR)
  				fscki1->calc_cnt += 1;
  		}
  	}
  
  out:
  	kfree(node);
  	return 0;
  
  out_dump:
235c362bd   Sheng Yong   UBIFS: extend deb...
2267
  	ubifs_msg(c, "dump of node at LEB %d:%d", zbr->lnum, zbr->offs);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2268
  	ubifs_dump_node(c, node);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
  out_free:
  	kfree(node);
  	return err;
  }
  
  /**
   * free_inodes - free RB-tree of inodes.
   * @fsckd: FS checking information
   */
  static void free_inodes(struct fsck_data *fsckd)
  {
bb25e49ff   Cody P Schafer   fs/ubifs: use rbt...
2280
  	struct fsck_inode *fscki, *n;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2281

bb25e49ff   Cody P Schafer   fs/ubifs: use rbt...
2282
2283
  	rbtree_postorder_for_each_entry_safe(fscki, n, &fsckd->inodes, rb)
  		kfree(fscki);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
  }
  
  /**
   * check_inodes - checks all inodes.
   * @c: UBIFS file-system description object
   * @fsckd: FS checking information
   *
   * This is a helper function for 'dbg_check_filesystem()' which walks the
   * RB-tree of inodes after the index scan has been finished, and checks that
   * inode nlink, size, etc are correct. Returns zero if inodes are fine,
   * %-EINVAL if not, and a negative error code in case of failure.
   */
  static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd)
  {
  	int n, err;
  	union ubifs_key key;
  	struct ubifs_znode *znode;
  	struct ubifs_zbranch *zbr;
  	struct ubifs_ino_node *ino;
  	struct fsck_inode *fscki;
  	struct rb_node *this = rb_first(&fsckd->inodes);
  
  	while (this) {
  		fscki = rb_entry(this, struct fsck_inode, rb);
  		this = rb_next(this);
  
  		if (S_ISDIR(fscki->mode)) {
  			/*
  			 * Directories have to have exactly one reference (they
  			 * cannot have hardlinks), although root inode is an
  			 * exception.
  			 */
  			if (fscki->inum != UBIFS_ROOT_INO &&
  			    fscki->references != 1) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2318
  				ubifs_err(c, "directory inode %lu has %d direntries which refer it, but should be 1",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2319
  					  (unsigned long)fscki->inum,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2320
2321
2322
2323
2324
  					  fscki->references);
  				goto out_dump;
  			}
  			if (fscki->inum == UBIFS_ROOT_INO &&
  			    fscki->references != 0) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2325
  				ubifs_err(c, "root inode %lu has non-zero (%d) direntries which refer it",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2326
2327
  					  (unsigned long)fscki->inum,
  					  fscki->references);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2328
2329
2330
  				goto out_dump;
  			}
  			if (fscki->calc_sz != fscki->size) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2331
  				ubifs_err(c, "directory inode %lu size is %lld, but calculated size is %lld",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2332
2333
  					  (unsigned long)fscki->inum,
  					  fscki->size, fscki->calc_sz);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2334
2335
2336
  				goto out_dump;
  			}
  			if (fscki->calc_cnt != fscki->nlink) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2337
  				ubifs_err(c, "directory inode %lu nlink is %d, but calculated nlink is %d",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2338
2339
  					  (unsigned long)fscki->inum,
  					  fscki->nlink, fscki->calc_cnt);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2340
2341
2342
2343
  				goto out_dump;
  			}
  		} else {
  			if (fscki->references != fscki->nlink) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2344
  				ubifs_err(c, "inode %lu nlink is %d, but calculated nlink is %d",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2345
  					  (unsigned long)fscki->inum,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2346
2347
2348
2349
2350
  					  fscki->nlink, fscki->references);
  				goto out_dump;
  			}
  		}
  		if (fscki->xattr_sz != fscki->calc_xsz) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2351
  			ubifs_err(c, "inode %lu has xattr size %u, but calculated size is %lld",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2352
  				  (unsigned long)fscki->inum, fscki->xattr_sz,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2353
2354
2355
2356
  				  fscki->calc_xsz);
  			goto out_dump;
  		}
  		if (fscki->xattr_cnt != fscki->calc_xcnt) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2357
  			ubifs_err(c, "inode %lu has %u xattrs, but calculated count is %lld",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2358
  				  (unsigned long)fscki->inum,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2359
2360
2361
2362
  				  fscki->xattr_cnt, fscki->calc_xcnt);
  			goto out_dump;
  		}
  		if (fscki->xattr_nms != fscki->calc_xnms) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2363
  			ubifs_err(c, "inode %lu has xattr names' size %u, but calculated names' size is %lld",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2364
  				  (unsigned long)fscki->inum, fscki->xattr_nms,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
  				  fscki->calc_xnms);
  			goto out_dump;
  		}
  	}
  
  	return 0;
  
  out_dump:
  	/* Read the bad inode and dump it */
  	ino_key_init(c, &key, fscki->inum);
  	err = ubifs_lookup_level0(c, &key, &znode, &n);
  	if (!err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2377
  		ubifs_err(c, "inode %lu not found in index",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2378
  			  (unsigned long)fscki->inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2379
2380
  		return -ENOENT;
  	} else if (err < 0) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2381
  		ubifs_err(c, "error %d while looking up inode %lu",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2382
  			  err, (unsigned long)fscki->inum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
  		return err;
  	}
  
  	zbr = &znode->zbranch[n];
  	ino = kmalloc(zbr->len, GFP_NOFS);
  	if (!ino)
  		return -ENOMEM;
  
  	err = ubifs_tnc_read_node(c, zbr, ino);
  	if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2393
  		ubifs_err(c, "cannot read inode node at LEB %d:%d, error %d",
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2394
2395
2396
2397
  			  zbr->lnum, zbr->offs, err);
  		kfree(ino);
  		return err;
  	}
235c362bd   Sheng Yong   UBIFS: extend deb...
2398
  	ubifs_msg(c, "dump of the inode %lu sitting in LEB %d:%d",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
2399
  		  (unsigned long)fscki->inum, zbr->lnum, zbr->offs);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2400
  	ubifs_dump_node(c, ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
  	kfree(ino);
  	return -EINVAL;
  }
  
  /**
   * dbg_check_filesystem - check the file-system.
   * @c: UBIFS file-system description object
   *
   * This function checks the file system, namely:
   * o makes sure that all leaf nodes exist and their CRCs are correct;
   * o makes sure inode nlink, size, xattr size/count are correct (for all
   *   inodes).
   *
   * The function reads whole indexing tree and all nodes, so it is pretty
   * heavy-weight. Returns zero if the file-system is consistent, %-EINVAL if
   * not, and a negative error code in case of failure.
   */
  int dbg_check_filesystem(struct ubifs_info *c)
  {
  	int err;
  	struct fsck_data fsckd;
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
2422
  	if (!dbg_is_chk_fs(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
  		return 0;
  
  	fsckd.inodes = RB_ROOT;
  	err = dbg_walk_index(c, check_leaf, NULL, &fsckd);
  	if (err)
  		goto out_free;
  
  	err = check_inodes(c, &fsckd);
  	if (err)
  		goto out_free;
  
  	free_inodes(&fsckd);
  	return 0;
  
  out_free:
235c362bd   Sheng Yong   UBIFS: extend deb...
2438
  	ubifs_err(c, "file-system check failed with error %d", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2439
2440
2441
2442
  	dump_stack();
  	free_inodes(&fsckd);
  	return err;
  }
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
  /**
   * dbg_check_data_nodes_order - check that list of data nodes is sorted.
   * @c: UBIFS file-system description object
   * @head: the list of nodes ('struct ubifs_scan_node' objects)
   *
   * This function returns zero if the list of data nodes is sorted correctly,
   * and %-EINVAL if not.
   */
  int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head)
  {
  	struct list_head *cur;
  	struct ubifs_scan_node *sa, *sb;
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
2455
  	if (!dbg_is_chk_gen(c))
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
  		return 0;
  
  	for (cur = head->next; cur->next != head; cur = cur->next) {
  		ino_t inuma, inumb;
  		uint32_t blka, blkb;
  
  		cond_resched();
  		sa = container_of(cur, struct ubifs_scan_node, list);
  		sb = container_of(cur->next, struct ubifs_scan_node, list);
  
  		if (sa->type != UBIFS_DATA_NODE) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2467
  			ubifs_err(c, "bad node type %d", sa->type);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2468
  			ubifs_dump_node(c, sa->node);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2469
2470
2471
  			return -EINVAL;
  		}
  		if (sb->type != UBIFS_DATA_NODE) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2472
  			ubifs_err(c, "bad node type %d", sb->type);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2473
  			ubifs_dump_node(c, sb->node);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2474
2475
2476
2477
2478
2479
2480
2481
2482
  			return -EINVAL;
  		}
  
  		inuma = key_inum(c, &sa->key);
  		inumb = key_inum(c, &sb->key);
  
  		if (inuma < inumb)
  			continue;
  		if (inuma > inumb) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2483
  			ubifs_err(c, "larger inum %lu goes before inum %lu",
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2484
2485
2486
2487
2488
2489
2490
2491
  				  (unsigned long)inuma, (unsigned long)inumb);
  			goto error_dump;
  		}
  
  		blka = key_block(c, &sa->key);
  		blkb = key_block(c, &sb->key);
  
  		if (blka > blkb) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2492
  			ubifs_err(c, "larger block %u goes before %u", blka, blkb);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2493
2494
2495
  			goto error_dump;
  		}
  		if (blka == blkb) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2496
  			ubifs_err(c, "two data nodes for the same block");
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2497
2498
2499
2500
2501
2502
2503
  			goto error_dump;
  		}
  	}
  
  	return 0;
  
  error_dump:
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2504
2505
  	ubifs_dump_node(c, sa->node);
  	ubifs_dump_node(c, sb->node);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
  	return -EINVAL;
  }
  
  /**
   * dbg_check_nondata_nodes_order - check that list of data nodes is sorted.
   * @c: UBIFS file-system description object
   * @head: the list of nodes ('struct ubifs_scan_node' objects)
   *
   * This function returns zero if the list of non-data nodes is sorted correctly,
   * and %-EINVAL if not.
   */
  int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
  {
  	struct list_head *cur;
  	struct ubifs_scan_node *sa, *sb;
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
2521
  	if (!dbg_is_chk_gen(c))
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
  		return 0;
  
  	for (cur = head->next; cur->next != head; cur = cur->next) {
  		ino_t inuma, inumb;
  		uint32_t hasha, hashb;
  
  		cond_resched();
  		sa = container_of(cur, struct ubifs_scan_node, list);
  		sb = container_of(cur->next, struct ubifs_scan_node, list);
  
  		if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE &&
  		    sa->type != UBIFS_XENT_NODE) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2534
  			ubifs_err(c, "bad node type %d", sa->type);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2535
  			ubifs_dump_node(c, sa->node);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2536
2537
  			return -EINVAL;
  		}
6a258f7d0   Colin Ian King   ubifs: Fix cut an...
2538
2539
  		if (sb->type != UBIFS_INO_NODE && sb->type != UBIFS_DENT_NODE &&
  		    sb->type != UBIFS_XENT_NODE) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2540
  			ubifs_err(c, "bad node type %d", sb->type);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2541
  			ubifs_dump_node(c, sb->node);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2542
2543
2544
2545
  			return -EINVAL;
  		}
  
  		if (sa->type != UBIFS_INO_NODE && sb->type == UBIFS_INO_NODE) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2546
  			ubifs_err(c, "non-inode node goes before inode node");
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2547
2548
2549
2550
2551
2552
2553
2554
2555
  			goto error_dump;
  		}
  
  		if (sa->type == UBIFS_INO_NODE && sb->type != UBIFS_INO_NODE)
  			continue;
  
  		if (sa->type == UBIFS_INO_NODE && sb->type == UBIFS_INO_NODE) {
  			/* Inode nodes are sorted in descending size order */
  			if (sa->len < sb->len) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2556
  				ubifs_err(c, "smaller inode node goes first");
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
  				goto error_dump;
  			}
  			continue;
  		}
  
  		/*
  		 * This is either a dentry or xentry, which should be sorted in
  		 * ascending (parent ino, hash) order.
  		 */
  		inuma = key_inum(c, &sa->key);
  		inumb = key_inum(c, &sb->key);
  
  		if (inuma < inumb)
  			continue;
  		if (inuma > inumb) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2572
  			ubifs_err(c, "larger inum %lu goes before inum %lu",
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2573
2574
2575
2576
2577
2578
2579
2580
  				  (unsigned long)inuma, (unsigned long)inumb);
  			goto error_dump;
  		}
  
  		hasha = key_block(c, &sa->key);
  		hashb = key_block(c, &sb->key);
  
  		if (hasha > hashb) {
235c362bd   Sheng Yong   UBIFS: extend deb...
2581
  			ubifs_err(c, "larger hash %u goes before %u",
c43615702   Artem Bityutskiy   UBIFS: fix minor ...
2582
  				  hasha, hashb);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2583
2584
2585
2586
2587
2588
2589
  			goto error_dump;
  		}
  	}
  
  	return 0;
  
  error_dump:
235c362bd   Sheng Yong   UBIFS: extend deb...
2590
  	ubifs_msg(c, "dumping first node");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2591
  	ubifs_dump_node(c, sa->node);
235c362bd   Sheng Yong   UBIFS: extend deb...
2592
  	ubifs_msg(c, "dumping second node");
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2593
  	ubifs_dump_node(c, sb->node);
3bb66b47a   Artem Bityutskiy   UBIFS: introduce ...
2594
2595
2596
  	return -EINVAL;
  	return 0;
  }
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2597
  static inline int chance(unsigned int n, unsigned int out_of)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2598
  {
3d251a5b9   Akinobu Mita   UBIFS: rename ran...
2599
  	return !!((prandom_u32() % out_of) + 1 <= n);
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2600

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2601
  }
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2602
  static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2603
  {
f57cb188c   Artem Bityutskiy   UBIFS: remove cus...
2604
  	struct ubifs_debug_info *d = c->dbg;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2605

f57cb188c   Artem Bityutskiy   UBIFS: remove cus...
2606
  	ubifs_assert(dbg_is_tst_rcvry(c));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2607

d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2608
2609
  	if (!d->pc_cnt) {
  		/* First call - decide delay to the power cut */
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2610
  		if (chance(1, 2)) {
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2611
  			unsigned long delay;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2612
2613
  
  			if (chance(1, 2)) {
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2614
  				d->pc_delay = 1;
443b39cdd   Richard Weinberger   UBIFS: Fix trivia...
2615
  				/* Fail within 1 minute */
3d251a5b9   Akinobu Mita   UBIFS: rename ran...
2616
  				delay = prandom_u32() % 60000;
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2617
2618
  				d->pc_timeout = jiffies;
  				d->pc_timeout += msecs_to_jiffies(delay);
235c362bd   Sheng Yong   UBIFS: extend deb...
2619
  				ubifs_warn(c, "failing after %lums", delay);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2620
  			} else {
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2621
  				d->pc_delay = 2;
3d251a5b9   Akinobu Mita   UBIFS: rename ran...
2622
  				delay = prandom_u32() % 10000;
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2623
  				/* Fail within 10000 operations */
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2624
  				d->pc_cnt_max = delay;
235c362bd   Sheng Yong   UBIFS: extend deb...
2625
  				ubifs_warn(c, "failing after %lu calls", delay);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2626
2627
  			}
  		}
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2628

d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2629
  		d->pc_cnt += 1;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2630
  	}
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2631

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2632
  	/* Determine if failure delay has expired */
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2633
  	if (d->pc_delay == 1 && time_before(jiffies, d->pc_timeout))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2634
  			return 0;
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2635
  	if (d->pc_delay == 2 && d->pc_cnt++ < d->pc_cnt_max)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2636
  			return 0;
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2637

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2638
  	if (lnum == UBIFS_SB_LNUM) {
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2639
2640
2641
  		if (write && chance(1, 2))
  			return 0;
  		if (chance(19, 20))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2642
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2643
  		ubifs_warn(c, "failing in super block LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2644
2645
2646
  	} else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) {
  		if (chance(19, 20))
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2647
  		ubifs_warn(c, "failing in master LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2648
  	} else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) {
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2649
2650
2651
  		if (write && chance(99, 100))
  			return 0;
  		if (chance(399, 400))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2652
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2653
  		ubifs_warn(c, "failing in log LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2654
  	} else if (lnum >= c->lpt_first && lnum <= c->lpt_last) {
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2655
2656
2657
  		if (write && chance(7, 8))
  			return 0;
  		if (chance(19, 20))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2658
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2659
  		ubifs_warn(c, "failing in LPT LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2660
  	} else if (lnum >= c->orph_first && lnum <= c->orph_last) {
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2661
2662
2663
  		if (write && chance(1, 2))
  			return 0;
  		if (chance(9, 10))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2664
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2665
  		ubifs_warn(c, "failing in orphan LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2666
2667
2668
  	} else if (lnum == c->ihead_lnum) {
  		if (chance(99, 100))
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2669
  		ubifs_warn(c, "failing in index head LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2670
2671
2672
  	} else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) {
  		if (chance(9, 10))
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2673
  		ubifs_warn(c, "failing in GC head LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2674
2675
2676
2677
  	} else if (write && !RB_EMPTY_ROOT(&c->buds) &&
  		   !ubifs_search_bud(c, lnum)) {
  		if (chance(19, 20))
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2678
  		ubifs_warn(c, "failing in non-bud LEB %d", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2679
2680
2681
2682
  	} else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND ||
  		   c->cmt_state == COMMIT_RUNNING_REQUIRED) {
  		if (chance(999, 1000))
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2683
  		ubifs_warn(c, "failing in bud LEB %d commit running", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2684
2685
2686
  	} else {
  		if (chance(9999, 10000))
  			return 0;
235c362bd   Sheng Yong   UBIFS: extend deb...
2687
  		ubifs_warn(c, "failing in bud LEB %d commit not running", lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2688
  	}
24a4f8009   Artem Bityutskiy   UBIFS: be more in...
2689

d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2690
  	d->pc_happened = 1;
235c362bd   Sheng Yong   UBIFS: extend deb...
2691
  	ubifs_warn(c, "========== Power cut emulated ==========");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2692
2693
2694
  	dump_stack();
  	return 1;
  }
8089ed792   Artem Bityutskiy   UBIFS: fix power ...
2695
2696
  static int corrupt_data(const struct ubifs_info *c, const void *buf,
  			unsigned int len)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2697
  {
cdd9fa8de   Akinobu Mita   ubifs: use prando...
2698
  	unsigned int from, to, ffs = chance(1, 2);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2699
  	unsigned char *p = (void *)buf;
58a4e2370   Mats Kärrman   UBIFS: correct da...
2700
2701
2702
  	from = prandom_u32() % len;
  	/* Corruption span max to end of write unit */
  	to = min(len, ALIGN(from + 1, c->max_write_size));
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2703

235c362bd   Sheng Yong   UBIFS: extend deb...
2704
  	ubifs_warn(c, "filled bytes %u-%u with %s", from, to - 1,
8089ed792   Artem Bityutskiy   UBIFS: fix power ...
2705
  		   ffs ? "0xFFs" : "random data");
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2706
2707
  
  	if (ffs)
cdd9fa8de   Akinobu Mita   ubifs: use prando...
2708
  		memset(p + from, 0xFF, to - from);
a7fa94a9f   Artem Bityutskiy   UBIFS: improve po...
2709
  	else
cdd9fa8de   Akinobu Mita   ubifs: use prando...
2710
  		prandom_bytes(p + from, to - from);
8089ed792   Artem Bityutskiy   UBIFS: fix power ...
2711
2712
  
  	return to;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2713
  }
f57cb188c   Artem Bityutskiy   UBIFS: remove cus...
2714
  int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
b36a261e8   Richard Weinberger   UBI: Kill data ty...
2715
  		  int offs, int len)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2716
  {
16dfd804b   Adrian Hunter   UBIFS: fix error ...
2717
  	int err, failing;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2718

8f6983abe   shengyong   UBIFS: call dbg_i...
2719
  	if (dbg_is_power_cut(c))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2720
  		return -EROFS;
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2721
2722
  
  	failing = power_cut_emulated(c, lnum, 1);
c23e9b75c   Mats Kärrman   UBIFS: remove inv...
2723
  	if (failing) {
8089ed792   Artem Bityutskiy   UBIFS: fix power ...
2724
  		len = corrupt_data(c, buf, len);
235c362bd   Sheng Yong   UBIFS: extend deb...
2725
  		ubifs_warn(c, "actually write %d bytes to LEB %d:%d (the buffer was corrupted)",
c23e9b75c   Mats Kärrman   UBIFS: remove inv...
2726
2727
  			   len, lnum, offs);
  	}
b36a261e8   Richard Weinberger   UBI: Kill data ty...
2728
  	err = ubi_leb_write(c->ubi, lnum, buf, offs, len);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2729
2730
  	if (err)
  		return err;
16dfd804b   Adrian Hunter   UBIFS: fix error ...
2731
  	if (failing)
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2732
  		return -EROFS;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2733
2734
  	return 0;
  }
f57cb188c   Artem Bityutskiy   UBIFS: remove cus...
2735
  int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
b36a261e8   Richard Weinberger   UBI: Kill data ty...
2736
  		   int len)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2737
2738
  {
  	int err;
8f6983abe   shengyong   UBIFS: call dbg_i...
2739
  	if (dbg_is_power_cut(c))
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2740
2741
  		return -EROFS;
  	if (power_cut_emulated(c, lnum, 1))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2742
  		return -EROFS;
b36a261e8   Richard Weinberger   UBI: Kill data ty...
2743
  	err = ubi_leb_change(c->ubi, lnum, buf, len);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2744
2745
  	if (err)
  		return err;
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2746
  	if (power_cut_emulated(c, lnum, 1))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2747
  		return -EROFS;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2748
2749
  	return 0;
  }
f57cb188c   Artem Bityutskiy   UBIFS: remove cus...
2750
  int dbg_leb_unmap(struct ubifs_info *c, int lnum)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2751
2752
  {
  	int err;
8f6983abe   shengyong   UBIFS: call dbg_i...
2753
  	if (dbg_is_power_cut(c))
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2754
2755
  		return -EROFS;
  	if (power_cut_emulated(c, lnum, 0))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2756
  		return -EROFS;
f57cb188c   Artem Bityutskiy   UBIFS: remove cus...
2757
  	err = ubi_leb_unmap(c->ubi, lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2758
2759
  	if (err)
  		return err;
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2760
  	if (power_cut_emulated(c, lnum, 0))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2761
  		return -EROFS;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2762
2763
  	return 0;
  }
b36a261e8   Richard Weinberger   UBI: Kill data ty...
2764
  int dbg_leb_map(struct ubifs_info *c, int lnum)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2765
2766
  {
  	int err;
8f6983abe   shengyong   UBIFS: call dbg_i...
2767
  	if (dbg_is_power_cut(c))
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2768
2769
  		return -EROFS;
  	if (power_cut_emulated(c, lnum, 0))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2770
  		return -EROFS;
b36a261e8   Richard Weinberger   UBI: Kill data ty...
2771
  	err = ubi_leb_map(c->ubi, lnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2772
2773
  	if (err)
  		return err;
d27462a51   Artem Bityutskiy   UBIFS: rename rec...
2774
  	if (power_cut_emulated(c, lnum, 0))
1a29af8bd   Artem Bityutskiy   UBIFS: use EROFS ...
2775
  		return -EROFS;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2776
2777
  	return 0;
  }
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2778
2779
2780
2781
  /*
   * Root directory for UBIFS stuff in debugfs. Contains sub-directories which
   * contain the stuff specific to particular file-system mounts.
   */
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
2782
  static struct dentry *dfs_rootdir;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2783

7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
2784
  static int dfs_file_open(struct inode *inode, struct file *file)
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2785
2786
  {
  	file->private_data = inode->i_private;
1bbfc848a   Artem Bityutskiy   UBIFS: make debug...
2787
  	return nonseekable_open(inode, file);
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2788
  }
28488fc28   Artem Bityutskiy   UBIFS: introduce ...
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
  /**
   * provide_user_output - provide output to the user reading a debugfs file.
   * @val: boolean value for the answer
   * @u: the buffer to store the answer at
   * @count: size of the buffer
   * @ppos: position in the @u output buffer
   *
   * This is a simple helper function which stores @val boolean value in the user
   * buffer when the user reads one of UBIFS debugfs files. Returns amount of
   * bytes written to @u in case of success and a negative error code in case of
   * failure.
   */
  static int provide_user_output(int val, char __user *u, size_t count,
  			       loff_t *ppos)
  {
  	char buf[3];
  
  	if (val)
  		buf[0] = '1';
  	else
  		buf[0] = '0';
  	buf[1] = '
  ';
  	buf[2] = 0x00;
  
  	return simple_read_from_buffer(u, count, ppos, buf, 2);
  }
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2816
2817
2818
2819
2820
2821
  static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count,
  			     loff_t *ppos)
  {
  	struct dentry *dent = file->f_path.dentry;
  	struct ubifs_info *c = file->private_data;
  	struct ubifs_debug_info *d = c->dbg;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
  	int val;
  
  	if (dent == d->dfs_chk_gen)
  		val = d->chk_gen;
  	else if (dent == d->dfs_chk_index)
  		val = d->chk_index;
  	else if (dent == d->dfs_chk_orph)
  		val = d->chk_orph;
  	else if (dent == d->dfs_chk_lprops)
  		val = d->chk_lprops;
  	else if (dent == d->dfs_chk_fs)
  		val = d->chk_fs;
  	else if (dent == d->dfs_tst_rcvry)
  		val = d->tst_rcvry;
06bef9451   Artem Bityutskiy   UBIFS: add debugf...
2836
2837
  	else if (dent == d->dfs_ro_error)
  		val = c->ro_error;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2838
2839
  	else
  		return -EINVAL;
28488fc28   Artem Bityutskiy   UBIFS: introduce ...
2840
2841
  	return provide_user_output(val, u, count, ppos);
  }
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2842

28488fc28   Artem Bityutskiy   UBIFS: introduce ...
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
  /**
   * interpret_user_input - interpret user debugfs file input.
   * @u: user-provided buffer with the input
   * @count: buffer size
   *
   * This is a helper function which interpret user input to a boolean UBIFS
   * debugfs file. Returns %0 or %1 in case of success and a negative error code
   * in case of failure.
   */
  static int interpret_user_input(const char __user *u, size_t count)
  {
  	size_t buf_size;
  	char buf[8];
  
  	buf_size = min_t(size_t, count, (sizeof(buf) - 1));
  	if (copy_from_user(buf, u, buf_size))
  		return -EFAULT;
  
  	if (buf[0] == '1')
  		return 1;
  	else if (buf[0] == '0')
  		return 0;
  
  	return -EINVAL;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2867
2868
2869
2870
  }
  
  static ssize_t dfs_file_write(struct file *file, const char __user *u,
  			      size_t count, loff_t *ppos)
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2871
2872
2873
  {
  	struct ubifs_info *c = file->private_data;
  	struct ubifs_debug_info *d = c->dbg;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2874
  	struct dentry *dent = file->f_path.dentry;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2875
  	int val;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2876

81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2877
  	/*
24a4f8009   Artem Bityutskiy   UBIFS: be more in...
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
  	 * TODO: this is racy - the file-system might have already been
  	 * unmounted and we'd oops in this case. The plan is to fix it with
  	 * help of 'iterate_supers_type()' which we should have in v3.0: when
  	 * a debugfs opened, we rember FS's UUID in file->private_data. Then
  	 * whenever we access the FS via a debugfs file, we iterate all UBIFS
  	 * superblocks and fine the one with the same UUID, and take the
  	 * locking right.
  	 *
  	 * The other way to go suggested by Al Viro is to create a separate
  	 * 'ubifs-debug' file-system instead.
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2888
2889
  	 */
  	if (file->f_path.dentry == d->dfs_dump_lprops) {
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2890
  		ubifs_dump_lprops(c);
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2891
2892
2893
  		return count;
  	}
  	if (file->f_path.dentry == d->dfs_dump_budg) {
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2894
  		ubifs_dump_budg(c, &c->bi);
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2895
2896
2897
  		return count;
  	}
  	if (file->f_path.dentry == d->dfs_dump_tnc) {
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2898
  		mutex_lock(&c->tnc_mutex);
edf6be245   Artem Bityutskiy   UBIFS: rename dum...
2899
  		ubifs_dump_tnc(c);
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2900
  		mutex_unlock(&c->tnc_mutex);
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2901
2902
  		return count;
  	}
28488fc28   Artem Bityutskiy   UBIFS: introduce ...
2903
2904
2905
  	val = interpret_user_input(u, count);
  	if (val < 0)
  		return val;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
  
  	if (dent == d->dfs_chk_gen)
  		d->chk_gen = val;
  	else if (dent == d->dfs_chk_index)
  		d->chk_index = val;
  	else if (dent == d->dfs_chk_orph)
  		d->chk_orph = val;
  	else if (dent == d->dfs_chk_lprops)
  		d->chk_lprops = val;
  	else if (dent == d->dfs_chk_fs)
  		d->chk_fs = val;
  	else if (dent == d->dfs_tst_rcvry)
  		d->tst_rcvry = val;
06bef9451   Artem Bityutskiy   UBIFS: add debugf...
2919
2920
  	else if (dent == d->dfs_ro_error)
  		c->ro_error = !!val;
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2921
  	else
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2922
  		return -EINVAL;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2923
2924
  	return count;
  }
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
2925
  static const struct file_operations dfs_fops = {
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
2926
  	.open = dfs_file_open,
81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2927
2928
  	.read = dfs_file_read,
  	.write = dfs_file_write,
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2929
  	.owner = THIS_MODULE,
1bbfc848a   Artem Bityutskiy   UBIFS: make debug...
2930
  	.llseek = no_llseek,
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
  };
  
  /**
   * dbg_debugfs_init_fs - initialize debugfs for UBIFS instance.
   * @c: UBIFS file-system description object
   *
   * This function creates all debugfs files for this instance of UBIFS. Returns
   * zero in case of success and a negative error code in case of failure.
   *
   * Note, the only reason we have not merged this function with the
   * 'ubifs_debugging_init()' function is because it is better to initialize
   * debugfs interfaces at the very end of the mount process, and remove them at
   * the very beginning of the mount process.
   */
  int dbg_debugfs_init_fs(struct ubifs_info *c)
  {
ae380ce04   Artem Bityutskiy   UBIFS: lessen the...
2947
  	int err, n;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2948
2949
2950
  	const char *fname;
  	struct dentry *dent;
  	struct ubifs_debug_info *d = c->dbg;
2d4cf5ae1   Brian Norris   UBIFS: correct us...
2951
  	if (!IS_ENABLED(CONFIG_DEBUG_FS))
818039c7d   Artem Bityutskiy   UBIFS: fix debugf...
2952
  		return 0;
ae380ce04   Artem Bityutskiy   UBIFS: lessen the...
2953
2954
2955
2956
2957
2958
2959
2960
  	n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME,
  		     c->vi.ubi_num, c->vi.vol_id);
  	if (n == UBIFS_DFS_DIR_LEN) {
  		/* The array size is too small */
  		fname = UBIFS_DFS_DIR_NAME;
  		dent = ERR_PTR(-EINVAL);
  		goto out;
  	}
cc6a86b95   Artem Bityutskiy   UBIFS: unify erro...
2961
2962
  	fname = d->dfs_dir_name;
  	dent = debugfs_create_dir(fname, dfs_rootdir);
951695351   Artem Bityutskiy   UBIFS: fix error ...
2963
  	if (IS_ERR_OR_NULL(dent))
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2964
  		goto out;
cc6a86b95   Artem Bityutskiy   UBIFS: unify erro...
2965
  	d->dfs_dir = dent;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2966
2967
  
  	fname = "dump_lprops";
8c559d30b   Vasiliy Kulikov   UBIFS: restrict w...
2968
  	dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
951695351   Artem Bityutskiy   UBIFS: fix error ...
2969
  	if (IS_ERR_OR_NULL(dent))
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2970
  		goto out_remove;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
2971
  	d->dfs_dump_lprops = dent;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2972
2973
  
  	fname = "dump_budg";
8c559d30b   Vasiliy Kulikov   UBIFS: restrict w...
2974
  	dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
951695351   Artem Bityutskiy   UBIFS: fix error ...
2975
  	if (IS_ERR_OR_NULL(dent))
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2976
  		goto out_remove;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
2977
  	d->dfs_dump_budg = dent;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2978
2979
  
  	fname = "dump_tnc";
8c559d30b   Vasiliy Kulikov   UBIFS: restrict w...
2980
  	dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
951695351   Artem Bityutskiy   UBIFS: fix error ...
2981
  	if (IS_ERR_OR_NULL(dent))
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2982
  		goto out_remove;
84abf972c   Artem Bityutskiy   UBIFS: add re-mou...
2983
  	d->dfs_dump_tnc = dent;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
2984

81e79d38d   Artem Bityutskiy   UBIFS: switch sel...
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
  	fname = "chk_general";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_chk_gen = dent;
  
  	fname = "chk_index";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_chk_index = dent;
  
  	fname = "chk_orphans";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_chk_orph = dent;
  
  	fname = "chk_lprops";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_chk_lprops = dent;
  
  	fname = "chk_fs";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_chk_fs = dent;
  
  	fname = "tst_recovery";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_tst_rcvry = dent;
06bef9451   Artem Bityutskiy   UBIFS: add debugf...
3026
3027
3028
3029
3030
3031
  	fname = "ro_error";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
  				   &dfs_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	d->dfs_ro_error = dent;
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
3032
3033
3034
  	return 0;
  
  out_remove:
cc6a86b95   Artem Bityutskiy   UBIFS: unify erro...
3035
3036
  	debugfs_remove_recursive(d->dfs_dir);
  out:
951695351   Artem Bityutskiy   UBIFS: fix error ...
3037
  	err = dent ? PTR_ERR(dent) : -ENODEV;
235c362bd   Sheng Yong   UBIFS: extend deb...
3038
3039
  	ubifs_err(c, "cannot create \"%s\" debugfs file or directory, error %d
  ",
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
3040
  		  fname, err);
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
3041
3042
3043
3044
3045
3046
3047
3048
3049
  	return err;
  }
  
  /**
   * dbg_debugfs_exit_fs - remove all debugfs files.
   * @c: UBIFS file-system description object
   */
  void dbg_debugfs_exit_fs(struct ubifs_info *c)
  {
2d4cf5ae1   Brian Norris   UBIFS: correct us...
3050
  	if (IS_ENABLED(CONFIG_DEBUG_FS))
818039c7d   Artem Bityutskiy   UBIFS: fix debugf...
3051
  		debugfs_remove_recursive(c->dbg->dfs_dir);
552ff3179   Artem Bityutskiy   UBIFS: add debugf...
3052
  }
e7717060d   Artem Bityutskiy   UBIFS: add global...
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
  struct ubifs_global_debug_info ubifs_dbg;
  
  static struct dentry *dfs_chk_gen;
  static struct dentry *dfs_chk_index;
  static struct dentry *dfs_chk_orph;
  static struct dentry *dfs_chk_lprops;
  static struct dentry *dfs_chk_fs;
  static struct dentry *dfs_tst_rcvry;
  
  static ssize_t dfs_global_file_read(struct file *file, char __user *u,
  				    size_t count, loff_t *ppos)
  {
  	struct dentry *dent = file->f_path.dentry;
  	int val;
  
  	if (dent == dfs_chk_gen)
  		val = ubifs_dbg.chk_gen;
  	else if (dent == dfs_chk_index)
  		val = ubifs_dbg.chk_index;
  	else if (dent == dfs_chk_orph)
  		val = ubifs_dbg.chk_orph;
  	else if (dent == dfs_chk_lprops)
  		val = ubifs_dbg.chk_lprops;
  	else if (dent == dfs_chk_fs)
  		val = ubifs_dbg.chk_fs;
  	else if (dent == dfs_tst_rcvry)
  		val = ubifs_dbg.tst_rcvry;
  	else
  		return -EINVAL;
  
  	return provide_user_output(val, u, count, ppos);
  }
  
  static ssize_t dfs_global_file_write(struct file *file, const char __user *u,
  				     size_t count, loff_t *ppos)
  {
  	struct dentry *dent = file->f_path.dentry;
  	int val;
  
  	val = interpret_user_input(u, count);
  	if (val < 0)
  		return val;
  
  	if (dent == dfs_chk_gen)
  		ubifs_dbg.chk_gen = val;
  	else if (dent == dfs_chk_index)
  		ubifs_dbg.chk_index = val;
  	else if (dent == dfs_chk_orph)
  		ubifs_dbg.chk_orph = val;
  	else if (dent == dfs_chk_lprops)
  		ubifs_dbg.chk_lprops = val;
  	else if (dent == dfs_chk_fs)
  		ubifs_dbg.chk_fs = val;
  	else if (dent == dfs_tst_rcvry)
  		ubifs_dbg.tst_rcvry = val;
  	else
  		return -EINVAL;
  
  	return count;
  }
  
  static const struct file_operations dfs_global_fops = {
  	.read = dfs_global_file_read,
  	.write = dfs_global_file_write,
  	.owner = THIS_MODULE,
  	.llseek = no_llseek,
  };
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
  /**
   * dbg_debugfs_init - initialize debugfs file-system.
   *
   * UBIFS uses debugfs file-system to expose various debugging knobs to
   * user-space. This function creates "ubifs" directory in the debugfs
   * file-system. Returns zero in case of success and a negative error code in
   * case of failure.
   */
  int dbg_debugfs_init(void)
  {
e7717060d   Artem Bityutskiy   UBIFS: add global...
3130
3131
3132
  	int err;
  	const char *fname;
  	struct dentry *dent;
2d4cf5ae1   Brian Norris   UBIFS: correct us...
3133
  	if (!IS_ENABLED(CONFIG_DEBUG_FS))
818039c7d   Artem Bityutskiy   UBIFS: fix debugf...
3134
  		return 0;
e7717060d   Artem Bityutskiy   UBIFS: add global...
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
  	fname = "ubifs";
  	dent = debugfs_create_dir(fname, NULL);
  	if (IS_ERR_OR_NULL(dent))
  		goto out;
  	dfs_rootdir = dent;
  
  	fname = "chk_general";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
  				   &dfs_global_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	dfs_chk_gen = dent;
  
  	fname = "chk_index";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
  				   &dfs_global_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	dfs_chk_index = dent;
  
  	fname = "chk_orphans";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
  				   &dfs_global_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	dfs_chk_orph = dent;
  
  	fname = "chk_lprops";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
  				   &dfs_global_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	dfs_chk_lprops = dent;
  
  	fname = "chk_fs";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
  				   &dfs_global_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	dfs_chk_fs = dent;
  
  	fname = "tst_recovery";
  	dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
  				   &dfs_global_fops);
  	if (IS_ERR_OR_NULL(dent))
  		goto out_remove;
  	dfs_tst_rcvry = dent;
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
3182
3183
  
  	return 0;
e7717060d   Artem Bityutskiy   UBIFS: add global...
3184
3185
3186
3187
3188
  
  out_remove:
  	debugfs_remove_recursive(dfs_rootdir);
  out:
  	err = dent ? PTR_ERR(dent) : -ENODEV;
235c362bd   Sheng Yong   UBIFS: extend deb...
3189
3190
3191
  	pr_err("UBIFS error (pid %d): cannot create \"%s\" debugfs file or directory, error %d
  ",
  	       current->pid, fname, err);
e7717060d   Artem Bityutskiy   UBIFS: add global...
3192
  	return err;
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
3193
3194
3195
3196
3197
3198
3199
  }
  
  /**
   * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system.
   */
  void dbg_debugfs_exit(void)
  {
2d4cf5ae1   Brian Norris   UBIFS: correct us...
3200
  	if (IS_ENABLED(CONFIG_DEBUG_FS))
818039c7d   Artem Bityutskiy   UBIFS: fix debugf...
3201
  		debugfs_remove_recursive(dfs_rootdir);
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
  }
  
  /**
   * ubifs_debugging_init - initialize UBIFS debugging.
   * @c: UBIFS file-system description object
   *
   * This function initializes debugging-related data for the file system.
   * Returns zero in case of success and a negative error code in case of
   * failure.
   */
  int ubifs_debugging_init(struct ubifs_info *c)
  {
  	c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL);
  	if (!c->dbg)
  		return -ENOMEM;
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
3217
3218
3219
3220
3221
3222
3223
3224
3225
  	return 0;
  }
  
  /**
   * ubifs_debugging_exit - free debugging data.
   * @c: UBIFS file-system description object
   */
  void ubifs_debugging_exit(struct ubifs_info *c)
  {
7dae997de   Artem Bityutskiy   UBIFS: re-arrange...
3226
3227
  	kfree(c->dbg);
  }