19eefe2a2SStefan Roese /* 29eefe2a2SStefan Roese * This file is part of UBIFS. 39eefe2a2SStefan Roese * 49eefe2a2SStefan Roese * Copyright (C) 2006-2008 Nokia Corporation 59eefe2a2SStefan Roese * 6ff94bc40SHeiko Schocher * SPDX-License-Identifier: GPL-2.0+ 79eefe2a2SStefan Roese * 89eefe2a2SStefan Roese * Authors: Artem Bityutskiy (Битюцкий Артём) 99eefe2a2SStefan Roese * Adrian Hunter 109eefe2a2SStefan Roese */ 119eefe2a2SStefan Roese 129eefe2a2SStefan Roese /* 139eefe2a2SStefan Roese * This file implements most of the debugging stuff which is compiled in only 149eefe2a2SStefan Roese * when it is enabled. But some debugging check functions are implemented in 159eefe2a2SStefan Roese * corresponding subsystem, just because they are closely related and utilize 169eefe2a2SStefan Roese * various local functions of those subsystems. 179eefe2a2SStefan Roese */ 189eefe2a2SStefan Roese 19ff94bc40SHeiko Schocher #ifndef __UBOOT__ 20ff94bc40SHeiko Schocher #include <linux/module.h> 21ff94bc40SHeiko Schocher #include <linux/debugfs.h> 22ff94bc40SHeiko Schocher #include <linux/math64.h> 23ff94bc40SHeiko Schocher #include <linux/uaccess.h> 24ff94bc40SHeiko Schocher #include <linux/random.h> 25ff94bc40SHeiko Schocher #else 26ff94bc40SHeiko Schocher #include <linux/compat.h> 27ff94bc40SHeiko Schocher #include <linux/err.h> 28ff94bc40SHeiko Schocher #endif 299eefe2a2SStefan Roese #include "ubifs.h" 309eefe2a2SStefan Roese 31ff94bc40SHeiko Schocher #ifndef __UBOOT__ 32ff94bc40SHeiko Schocher static DEFINE_SPINLOCK(dbg_lock); 33ff94bc40SHeiko Schocher #endif 349eefe2a2SStefan Roese 35ff94bc40SHeiko Schocher static const char *get_key_fmt(int fmt) 36ff94bc40SHeiko Schocher { 37ff94bc40SHeiko Schocher switch (fmt) { 38ff94bc40SHeiko Schocher case UBIFS_SIMPLE_KEY_FMT: 39ff94bc40SHeiko Schocher return "simple"; 40ff94bc40SHeiko Schocher default: 41ff94bc40SHeiko Schocher return "unknown/invalid format"; 42ff94bc40SHeiko Schocher } 43ff94bc40SHeiko Schocher } 449eefe2a2SStefan Roese 45ff94bc40SHeiko Schocher static const char *get_key_hash(int hash) 46ff94bc40SHeiko Schocher { 47ff94bc40SHeiko Schocher switch (hash) { 48ff94bc40SHeiko Schocher case UBIFS_KEY_HASH_R5: 49ff94bc40SHeiko Schocher return "R5"; 50ff94bc40SHeiko Schocher case UBIFS_KEY_HASH_TEST: 51ff94bc40SHeiko Schocher return "test"; 52ff94bc40SHeiko Schocher default: 53ff94bc40SHeiko Schocher return "unknown/invalid name hash"; 54ff94bc40SHeiko Schocher } 55ff94bc40SHeiko Schocher } 569eefe2a2SStefan Roese 579eefe2a2SStefan Roese static const char *get_key_type(int type) 589eefe2a2SStefan Roese { 599eefe2a2SStefan Roese switch (type) { 609eefe2a2SStefan Roese case UBIFS_INO_KEY: 619eefe2a2SStefan Roese return "inode"; 629eefe2a2SStefan Roese case UBIFS_DENT_KEY: 639eefe2a2SStefan Roese return "direntry"; 649eefe2a2SStefan Roese case UBIFS_XENT_KEY: 659eefe2a2SStefan Roese return "xentry"; 669eefe2a2SStefan Roese case UBIFS_DATA_KEY: 679eefe2a2SStefan Roese return "data"; 689eefe2a2SStefan Roese case UBIFS_TRUN_KEY: 699eefe2a2SStefan Roese return "truncate"; 709eefe2a2SStefan Roese default: 719eefe2a2SStefan Roese return "unknown/invalid key"; 729eefe2a2SStefan Roese } 739eefe2a2SStefan Roese } 749eefe2a2SStefan Roese 75ff94bc40SHeiko Schocher #ifndef __UBOOT__ 76ff94bc40SHeiko Schocher static const char *get_dent_type(int type) 77ff94bc40SHeiko Schocher { 78ff94bc40SHeiko Schocher switch (type) { 79ff94bc40SHeiko Schocher case UBIFS_ITYPE_REG: 80ff94bc40SHeiko Schocher return "file"; 81ff94bc40SHeiko Schocher case UBIFS_ITYPE_DIR: 82ff94bc40SHeiko Schocher return "dir"; 83ff94bc40SHeiko Schocher case UBIFS_ITYPE_LNK: 84ff94bc40SHeiko Schocher return "symlink"; 85ff94bc40SHeiko Schocher case UBIFS_ITYPE_BLK: 86ff94bc40SHeiko Schocher return "blkdev"; 87ff94bc40SHeiko Schocher case UBIFS_ITYPE_CHR: 88ff94bc40SHeiko Schocher return "char dev"; 89ff94bc40SHeiko Schocher case UBIFS_ITYPE_FIFO: 90ff94bc40SHeiko Schocher return "fifo"; 91ff94bc40SHeiko Schocher case UBIFS_ITYPE_SOCK: 92ff94bc40SHeiko Schocher return "socket"; 93ff94bc40SHeiko Schocher default: 94ff94bc40SHeiko Schocher return "unknown/invalid type"; 95ff94bc40SHeiko Schocher } 96ff94bc40SHeiko Schocher } 97ff94bc40SHeiko Schocher #endif 98ff94bc40SHeiko Schocher 99ff94bc40SHeiko Schocher const char *dbg_snprintf_key(const struct ubifs_info *c, 100ff94bc40SHeiko Schocher const union ubifs_key *key, char *buffer, int len) 1019eefe2a2SStefan Roese { 1029eefe2a2SStefan Roese char *p = buffer; 1039eefe2a2SStefan Roese int type = key_type(c, key); 1049eefe2a2SStefan Roese 1059eefe2a2SStefan Roese if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) { 1069eefe2a2SStefan Roese switch (type) { 1079eefe2a2SStefan Roese case UBIFS_INO_KEY: 108ff94bc40SHeiko Schocher len -= snprintf(p, len, "(%lu, %s)", 109ff94bc40SHeiko Schocher (unsigned long)key_inum(c, key), 1109eefe2a2SStefan Roese get_key_type(type)); 1119eefe2a2SStefan Roese break; 1129eefe2a2SStefan Roese case UBIFS_DENT_KEY: 1139eefe2a2SStefan Roese case UBIFS_XENT_KEY: 114ff94bc40SHeiko Schocher len -= snprintf(p, len, "(%lu, %s, %#08x)", 1159eefe2a2SStefan Roese (unsigned long)key_inum(c, key), 1169eefe2a2SStefan Roese get_key_type(type), key_hash(c, key)); 1179eefe2a2SStefan Roese break; 1189eefe2a2SStefan Roese case UBIFS_DATA_KEY: 119ff94bc40SHeiko Schocher len -= snprintf(p, len, "(%lu, %s, %u)", 1209eefe2a2SStefan Roese (unsigned long)key_inum(c, key), 1219eefe2a2SStefan Roese get_key_type(type), key_block(c, key)); 1229eefe2a2SStefan Roese break; 1239eefe2a2SStefan Roese case UBIFS_TRUN_KEY: 124ff94bc40SHeiko Schocher len -= snprintf(p, len, "(%lu, %s)", 1259eefe2a2SStefan Roese (unsigned long)key_inum(c, key), 1269eefe2a2SStefan Roese get_key_type(type)); 1279eefe2a2SStefan Roese break; 1289eefe2a2SStefan Roese default: 129ff94bc40SHeiko Schocher len -= snprintf(p, len, "(bad key type: %#08x, %#08x)", 1309eefe2a2SStefan Roese key->u32[0], key->u32[1]); 1319eefe2a2SStefan Roese } 1329eefe2a2SStefan Roese } else 133ff94bc40SHeiko Schocher len -= snprintf(p, len, "bad key format %d", c->key_fmt); 134ff94bc40SHeiko Schocher ubifs_assert(len > 0); 135ff94bc40SHeiko Schocher return p; 1369eefe2a2SStefan Roese } 1379eefe2a2SStefan Roese 138ff94bc40SHeiko Schocher const char *dbg_ntype(int type) 1399eefe2a2SStefan Roese { 140ff94bc40SHeiko Schocher switch (type) { 141ff94bc40SHeiko Schocher case UBIFS_PAD_NODE: 142ff94bc40SHeiko Schocher return "padding node"; 143ff94bc40SHeiko Schocher case UBIFS_SB_NODE: 144ff94bc40SHeiko Schocher return "superblock node"; 145ff94bc40SHeiko Schocher case UBIFS_MST_NODE: 146ff94bc40SHeiko Schocher return "master node"; 147ff94bc40SHeiko Schocher case UBIFS_REF_NODE: 148ff94bc40SHeiko Schocher return "reference node"; 149ff94bc40SHeiko Schocher case UBIFS_INO_NODE: 150ff94bc40SHeiko Schocher return "inode node"; 151ff94bc40SHeiko Schocher case UBIFS_DENT_NODE: 152ff94bc40SHeiko Schocher return "direntry node"; 153ff94bc40SHeiko Schocher case UBIFS_XENT_NODE: 154ff94bc40SHeiko Schocher return "xentry node"; 155ff94bc40SHeiko Schocher case UBIFS_DATA_NODE: 156ff94bc40SHeiko Schocher return "data node"; 157ff94bc40SHeiko Schocher case UBIFS_TRUN_NODE: 158ff94bc40SHeiko Schocher return "truncate node"; 159ff94bc40SHeiko Schocher case UBIFS_IDX_NODE: 160ff94bc40SHeiko Schocher return "indexing node"; 161ff94bc40SHeiko Schocher case UBIFS_CS_NODE: 162ff94bc40SHeiko Schocher return "commit start node"; 163ff94bc40SHeiko Schocher case UBIFS_ORPH_NODE: 164ff94bc40SHeiko Schocher return "orphan node"; 165ff94bc40SHeiko Schocher default: 166ff94bc40SHeiko Schocher return "unknown node"; 167ff94bc40SHeiko Schocher } 1689eefe2a2SStefan Roese } 1699eefe2a2SStefan Roese 170ff94bc40SHeiko Schocher static const char *dbg_gtype(int type) 1719eefe2a2SStefan Roese { 172ff94bc40SHeiko Schocher switch (type) { 173ff94bc40SHeiko Schocher case UBIFS_NO_NODE_GROUP: 174ff94bc40SHeiko Schocher return "no node group"; 175ff94bc40SHeiko Schocher case UBIFS_IN_NODE_GROUP: 176ff94bc40SHeiko Schocher return "in node group"; 177ff94bc40SHeiko Schocher case UBIFS_LAST_OF_NODE_GROUP: 178ff94bc40SHeiko Schocher return "last of node group"; 179ff94bc40SHeiko Schocher default: 180ff94bc40SHeiko Schocher return "unknown"; 181ff94bc40SHeiko Schocher } 182ff94bc40SHeiko Schocher } 183ff94bc40SHeiko Schocher 184ff94bc40SHeiko Schocher const char *dbg_cstate(int cmt_state) 185ff94bc40SHeiko Schocher { 186ff94bc40SHeiko Schocher switch (cmt_state) { 187ff94bc40SHeiko Schocher case COMMIT_RESTING: 188ff94bc40SHeiko Schocher return "commit resting"; 189ff94bc40SHeiko Schocher case COMMIT_BACKGROUND: 190ff94bc40SHeiko Schocher return "background commit requested"; 191ff94bc40SHeiko Schocher case COMMIT_REQUIRED: 192ff94bc40SHeiko Schocher return "commit required"; 193ff94bc40SHeiko Schocher case COMMIT_RUNNING_BACKGROUND: 194ff94bc40SHeiko Schocher return "BACKGROUND commit running"; 195ff94bc40SHeiko Schocher case COMMIT_RUNNING_REQUIRED: 196ff94bc40SHeiko Schocher return "commit running and required"; 197ff94bc40SHeiko Schocher case COMMIT_BROKEN: 198ff94bc40SHeiko Schocher return "broken commit"; 199ff94bc40SHeiko Schocher default: 200ff94bc40SHeiko Schocher return "unknown commit state"; 201ff94bc40SHeiko Schocher } 202ff94bc40SHeiko Schocher } 203ff94bc40SHeiko Schocher 204ff94bc40SHeiko Schocher const char *dbg_jhead(int jhead) 205ff94bc40SHeiko Schocher { 206ff94bc40SHeiko Schocher switch (jhead) { 207ff94bc40SHeiko Schocher case GCHD: 208ff94bc40SHeiko Schocher return "0 (GC)"; 209ff94bc40SHeiko Schocher case BASEHD: 210ff94bc40SHeiko Schocher return "1 (base)"; 211ff94bc40SHeiko Schocher case DATAHD: 212ff94bc40SHeiko Schocher return "2 (data)"; 213ff94bc40SHeiko Schocher default: 214ff94bc40SHeiko Schocher return "unknown journal head"; 215ff94bc40SHeiko Schocher } 216ff94bc40SHeiko Schocher } 217ff94bc40SHeiko Schocher 218ff94bc40SHeiko Schocher static void dump_ch(const struct ubifs_ch *ch) 219ff94bc40SHeiko Schocher { 220ff94bc40SHeiko Schocher pr_err("\tmagic %#x\n", le32_to_cpu(ch->magic)); 221ff94bc40SHeiko Schocher pr_err("\tcrc %#x\n", le32_to_cpu(ch->crc)); 222ff94bc40SHeiko Schocher pr_err("\tnode_type %d (%s)\n", ch->node_type, 223ff94bc40SHeiko Schocher dbg_ntype(ch->node_type)); 224ff94bc40SHeiko Schocher pr_err("\tgroup_type %d (%s)\n", ch->group_type, 225ff94bc40SHeiko Schocher dbg_gtype(ch->group_type)); 226ff94bc40SHeiko Schocher pr_err("\tsqnum %llu\n", 227ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(ch->sqnum)); 228ff94bc40SHeiko Schocher pr_err("\tlen %u\n", le32_to_cpu(ch->len)); 229ff94bc40SHeiko Schocher } 230ff94bc40SHeiko Schocher 231ff94bc40SHeiko Schocher void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode) 232ff94bc40SHeiko Schocher { 233ff94bc40SHeiko Schocher #ifndef __UBOOT__ 234ff94bc40SHeiko Schocher const struct ubifs_inode *ui = ubifs_inode(inode); 235ff94bc40SHeiko Schocher struct qstr nm = { .name = NULL }; 236ff94bc40SHeiko Schocher union ubifs_key key; 237ff94bc40SHeiko Schocher struct ubifs_dent_node *dent, *pdent = NULL; 238ff94bc40SHeiko Schocher int count = 2; 239ff94bc40SHeiko Schocher 240ff94bc40SHeiko Schocher pr_err("Dump in-memory inode:"); 241ff94bc40SHeiko Schocher pr_err("\tinode %lu\n", inode->i_ino); 242ff94bc40SHeiko Schocher pr_err("\tsize %llu\n", 243ff94bc40SHeiko Schocher (unsigned long long)i_size_read(inode)); 244ff94bc40SHeiko Schocher pr_err("\tnlink %u\n", inode->i_nlink); 245ff94bc40SHeiko Schocher pr_err("\tuid %u\n", (unsigned int)i_uid_read(inode)); 246ff94bc40SHeiko Schocher pr_err("\tgid %u\n", (unsigned int)i_gid_read(inode)); 247ff94bc40SHeiko Schocher pr_err("\tatime %u.%u\n", 248ff94bc40SHeiko Schocher (unsigned int)inode->i_atime.tv_sec, 249ff94bc40SHeiko Schocher (unsigned int)inode->i_atime.tv_nsec); 250ff94bc40SHeiko Schocher pr_err("\tmtime %u.%u\n", 251ff94bc40SHeiko Schocher (unsigned int)inode->i_mtime.tv_sec, 252ff94bc40SHeiko Schocher (unsigned int)inode->i_mtime.tv_nsec); 253ff94bc40SHeiko Schocher pr_err("\tctime %u.%u\n", 254ff94bc40SHeiko Schocher (unsigned int)inode->i_ctime.tv_sec, 255ff94bc40SHeiko Schocher (unsigned int)inode->i_ctime.tv_nsec); 256ff94bc40SHeiko Schocher pr_err("\tcreat_sqnum %llu\n", ui->creat_sqnum); 257ff94bc40SHeiko Schocher pr_err("\txattr_size %u\n", ui->xattr_size); 258ff94bc40SHeiko Schocher pr_err("\txattr_cnt %u\n", ui->xattr_cnt); 259ff94bc40SHeiko Schocher pr_err("\txattr_names %u\n", ui->xattr_names); 260ff94bc40SHeiko Schocher pr_err("\tdirty %u\n", ui->dirty); 261ff94bc40SHeiko Schocher pr_err("\txattr %u\n", ui->xattr); 262ff94bc40SHeiko Schocher pr_err("\tbulk_read %u\n", ui->xattr); 263ff94bc40SHeiko Schocher pr_err("\tsynced_i_size %llu\n", 264ff94bc40SHeiko Schocher (unsigned long long)ui->synced_i_size); 265ff94bc40SHeiko Schocher pr_err("\tui_size %llu\n", 266ff94bc40SHeiko Schocher (unsigned long long)ui->ui_size); 267ff94bc40SHeiko Schocher pr_err("\tflags %d\n", ui->flags); 268ff94bc40SHeiko Schocher pr_err("\tcompr_type %d\n", ui->compr_type); 269ff94bc40SHeiko Schocher pr_err("\tlast_page_read %lu\n", ui->last_page_read); 270ff94bc40SHeiko Schocher pr_err("\tread_in_a_row %lu\n", ui->read_in_a_row); 271ff94bc40SHeiko Schocher pr_err("\tdata_len %d\n", ui->data_len); 272ff94bc40SHeiko Schocher 273ff94bc40SHeiko Schocher if (!S_ISDIR(inode->i_mode)) 274ff94bc40SHeiko Schocher return; 275ff94bc40SHeiko Schocher 276ff94bc40SHeiko Schocher pr_err("List of directory entries:\n"); 277ff94bc40SHeiko Schocher ubifs_assert(!mutex_is_locked(&c->tnc_mutex)); 278ff94bc40SHeiko Schocher 279ff94bc40SHeiko Schocher lowest_dent_key(c, &key, inode->i_ino); 280ff94bc40SHeiko Schocher while (1) { 281ff94bc40SHeiko Schocher dent = ubifs_tnc_next_ent(c, &key, &nm); 282ff94bc40SHeiko Schocher if (IS_ERR(dent)) { 283ff94bc40SHeiko Schocher if (PTR_ERR(dent) != -ENOENT) 284ff94bc40SHeiko Schocher pr_err("error %ld\n", PTR_ERR(dent)); 285ff94bc40SHeiko Schocher break; 286ff94bc40SHeiko Schocher } 287ff94bc40SHeiko Schocher 288ff94bc40SHeiko Schocher pr_err("\t%d: %s (%s)\n", 289ff94bc40SHeiko Schocher count++, dent->name, get_dent_type(dent->type)); 290ff94bc40SHeiko Schocher 291ff94bc40SHeiko Schocher nm.name = dent->name; 292ff94bc40SHeiko Schocher nm.len = le16_to_cpu(dent->nlen); 293ff94bc40SHeiko Schocher kfree(pdent); 294ff94bc40SHeiko Schocher pdent = dent; 295ff94bc40SHeiko Schocher key_read(c, &dent->key, &key); 296ff94bc40SHeiko Schocher } 297ff94bc40SHeiko Schocher kfree(pdent); 298ff94bc40SHeiko Schocher #endif 299ff94bc40SHeiko Schocher } 300ff94bc40SHeiko Schocher 301ff94bc40SHeiko Schocher void ubifs_dump_node(const struct ubifs_info *c, const void *node) 302ff94bc40SHeiko Schocher { 303ff94bc40SHeiko Schocher int i, n; 304ff94bc40SHeiko Schocher union ubifs_key key; 305ff94bc40SHeiko Schocher const struct ubifs_ch *ch = node; 306ff94bc40SHeiko Schocher char key_buf[DBG_KEY_BUF_LEN]; 307ff94bc40SHeiko Schocher 308ff94bc40SHeiko Schocher /* If the magic is incorrect, just hexdump the first bytes */ 309ff94bc40SHeiko Schocher if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) { 310ff94bc40SHeiko Schocher pr_err("Not a node, first %zu bytes:", UBIFS_CH_SZ); 311ff94bc40SHeiko Schocher print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 32, 1, 312ff94bc40SHeiko Schocher (void *)node, UBIFS_CH_SZ, 1); 313ff94bc40SHeiko Schocher return; 314ff94bc40SHeiko Schocher } 315ff94bc40SHeiko Schocher 316ff94bc40SHeiko Schocher spin_lock(&dbg_lock); 317ff94bc40SHeiko Schocher dump_ch(node); 318ff94bc40SHeiko Schocher 319ff94bc40SHeiko Schocher switch (ch->node_type) { 320ff94bc40SHeiko Schocher case UBIFS_PAD_NODE: 321ff94bc40SHeiko Schocher { 322ff94bc40SHeiko Schocher const struct ubifs_pad_node *pad = node; 323ff94bc40SHeiko Schocher 324ff94bc40SHeiko Schocher pr_err("\tpad_len %u\n", le32_to_cpu(pad->pad_len)); 325ff94bc40SHeiko Schocher break; 326ff94bc40SHeiko Schocher } 327ff94bc40SHeiko Schocher case UBIFS_SB_NODE: 328ff94bc40SHeiko Schocher { 329ff94bc40SHeiko Schocher const struct ubifs_sb_node *sup = node; 330ff94bc40SHeiko Schocher unsigned int sup_flags = le32_to_cpu(sup->flags); 331ff94bc40SHeiko Schocher 332ff94bc40SHeiko Schocher pr_err("\tkey_hash %d (%s)\n", 333ff94bc40SHeiko Schocher (int)sup->key_hash, get_key_hash(sup->key_hash)); 334ff94bc40SHeiko Schocher pr_err("\tkey_fmt %d (%s)\n", 335ff94bc40SHeiko Schocher (int)sup->key_fmt, get_key_fmt(sup->key_fmt)); 336ff94bc40SHeiko Schocher pr_err("\tflags %#x\n", sup_flags); 337ff94bc40SHeiko Schocher pr_err("\tbig_lpt %u\n", 338ff94bc40SHeiko Schocher !!(sup_flags & UBIFS_FLG_BIGLPT)); 339ff94bc40SHeiko Schocher pr_err("\tspace_fixup %u\n", 340ff94bc40SHeiko Schocher !!(sup_flags & UBIFS_FLG_SPACE_FIXUP)); 341ff94bc40SHeiko Schocher pr_err("\tmin_io_size %u\n", le32_to_cpu(sup->min_io_size)); 342ff94bc40SHeiko Schocher pr_err("\tleb_size %u\n", le32_to_cpu(sup->leb_size)); 343ff94bc40SHeiko Schocher pr_err("\tleb_cnt %u\n", le32_to_cpu(sup->leb_cnt)); 344ff94bc40SHeiko Schocher pr_err("\tmax_leb_cnt %u\n", le32_to_cpu(sup->max_leb_cnt)); 345ff94bc40SHeiko Schocher pr_err("\tmax_bud_bytes %llu\n", 346ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(sup->max_bud_bytes)); 347ff94bc40SHeiko Schocher pr_err("\tlog_lebs %u\n", le32_to_cpu(sup->log_lebs)); 348ff94bc40SHeiko Schocher pr_err("\tlpt_lebs %u\n", le32_to_cpu(sup->lpt_lebs)); 349ff94bc40SHeiko Schocher pr_err("\torph_lebs %u\n", le32_to_cpu(sup->orph_lebs)); 350ff94bc40SHeiko Schocher pr_err("\tjhead_cnt %u\n", le32_to_cpu(sup->jhead_cnt)); 351ff94bc40SHeiko Schocher pr_err("\tfanout %u\n", le32_to_cpu(sup->fanout)); 352ff94bc40SHeiko Schocher pr_err("\tlsave_cnt %u\n", le32_to_cpu(sup->lsave_cnt)); 353ff94bc40SHeiko Schocher pr_err("\tdefault_compr %u\n", 354ff94bc40SHeiko Schocher (int)le16_to_cpu(sup->default_compr)); 355ff94bc40SHeiko Schocher pr_err("\trp_size %llu\n", 356ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(sup->rp_size)); 357ff94bc40SHeiko Schocher pr_err("\trp_uid %u\n", le32_to_cpu(sup->rp_uid)); 358ff94bc40SHeiko Schocher pr_err("\trp_gid %u\n", le32_to_cpu(sup->rp_gid)); 359ff94bc40SHeiko Schocher pr_err("\tfmt_version %u\n", le32_to_cpu(sup->fmt_version)); 360ff94bc40SHeiko Schocher pr_err("\ttime_gran %u\n", le32_to_cpu(sup->time_gran)); 361ff94bc40SHeiko Schocher pr_err("\tUUID %pUB\n", sup->uuid); 362ff94bc40SHeiko Schocher break; 363ff94bc40SHeiko Schocher } 364ff94bc40SHeiko Schocher case UBIFS_MST_NODE: 365ff94bc40SHeiko Schocher { 366ff94bc40SHeiko Schocher const struct ubifs_mst_node *mst = node; 367ff94bc40SHeiko Schocher 368ff94bc40SHeiko Schocher pr_err("\thighest_inum %llu\n", 369ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->highest_inum)); 370ff94bc40SHeiko Schocher pr_err("\tcommit number %llu\n", 371ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->cmt_no)); 372ff94bc40SHeiko Schocher pr_err("\tflags %#x\n", le32_to_cpu(mst->flags)); 373ff94bc40SHeiko Schocher pr_err("\tlog_lnum %u\n", le32_to_cpu(mst->log_lnum)); 374ff94bc40SHeiko Schocher pr_err("\troot_lnum %u\n", le32_to_cpu(mst->root_lnum)); 375ff94bc40SHeiko Schocher pr_err("\troot_offs %u\n", le32_to_cpu(mst->root_offs)); 376ff94bc40SHeiko Schocher pr_err("\troot_len %u\n", le32_to_cpu(mst->root_len)); 377ff94bc40SHeiko Schocher pr_err("\tgc_lnum %u\n", le32_to_cpu(mst->gc_lnum)); 378ff94bc40SHeiko Schocher pr_err("\tihead_lnum %u\n", le32_to_cpu(mst->ihead_lnum)); 379ff94bc40SHeiko Schocher pr_err("\tihead_offs %u\n", le32_to_cpu(mst->ihead_offs)); 380ff94bc40SHeiko Schocher pr_err("\tindex_size %llu\n", 381ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->index_size)); 382ff94bc40SHeiko Schocher pr_err("\tlpt_lnum %u\n", le32_to_cpu(mst->lpt_lnum)); 383ff94bc40SHeiko Schocher pr_err("\tlpt_offs %u\n", le32_to_cpu(mst->lpt_offs)); 384ff94bc40SHeiko Schocher pr_err("\tnhead_lnum %u\n", le32_to_cpu(mst->nhead_lnum)); 385ff94bc40SHeiko Schocher pr_err("\tnhead_offs %u\n", le32_to_cpu(mst->nhead_offs)); 386ff94bc40SHeiko Schocher pr_err("\tltab_lnum %u\n", le32_to_cpu(mst->ltab_lnum)); 387ff94bc40SHeiko Schocher pr_err("\tltab_offs %u\n", le32_to_cpu(mst->ltab_offs)); 388ff94bc40SHeiko Schocher pr_err("\tlsave_lnum %u\n", le32_to_cpu(mst->lsave_lnum)); 389ff94bc40SHeiko Schocher pr_err("\tlsave_offs %u\n", le32_to_cpu(mst->lsave_offs)); 390ff94bc40SHeiko Schocher pr_err("\tlscan_lnum %u\n", le32_to_cpu(mst->lscan_lnum)); 391ff94bc40SHeiko Schocher pr_err("\tleb_cnt %u\n", le32_to_cpu(mst->leb_cnt)); 392ff94bc40SHeiko Schocher pr_err("\tempty_lebs %u\n", le32_to_cpu(mst->empty_lebs)); 393ff94bc40SHeiko Schocher pr_err("\tidx_lebs %u\n", le32_to_cpu(mst->idx_lebs)); 394ff94bc40SHeiko Schocher pr_err("\ttotal_free %llu\n", 395ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->total_free)); 396ff94bc40SHeiko Schocher pr_err("\ttotal_dirty %llu\n", 397ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->total_dirty)); 398ff94bc40SHeiko Schocher pr_err("\ttotal_used %llu\n", 399ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->total_used)); 400ff94bc40SHeiko Schocher pr_err("\ttotal_dead %llu\n", 401ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->total_dead)); 402ff94bc40SHeiko Schocher pr_err("\ttotal_dark %llu\n", 403ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(mst->total_dark)); 404ff94bc40SHeiko Schocher break; 405ff94bc40SHeiko Schocher } 406ff94bc40SHeiko Schocher case UBIFS_REF_NODE: 407ff94bc40SHeiko Schocher { 408ff94bc40SHeiko Schocher const struct ubifs_ref_node *ref = node; 409ff94bc40SHeiko Schocher 410ff94bc40SHeiko Schocher pr_err("\tlnum %u\n", le32_to_cpu(ref->lnum)); 411ff94bc40SHeiko Schocher pr_err("\toffs %u\n", le32_to_cpu(ref->offs)); 412ff94bc40SHeiko Schocher pr_err("\tjhead %u\n", le32_to_cpu(ref->jhead)); 413ff94bc40SHeiko Schocher break; 414ff94bc40SHeiko Schocher } 415ff94bc40SHeiko Schocher case UBIFS_INO_NODE: 416ff94bc40SHeiko Schocher { 417ff94bc40SHeiko Schocher const struct ubifs_ino_node *ino = node; 418ff94bc40SHeiko Schocher 419ff94bc40SHeiko Schocher key_read(c, &ino->key, &key); 420ff94bc40SHeiko Schocher pr_err("\tkey %s\n", 421ff94bc40SHeiko Schocher dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); 422ff94bc40SHeiko Schocher pr_err("\tcreat_sqnum %llu\n", 423ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(ino->creat_sqnum)); 424ff94bc40SHeiko Schocher pr_err("\tsize %llu\n", 425ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(ino->size)); 426ff94bc40SHeiko Schocher pr_err("\tnlink %u\n", le32_to_cpu(ino->nlink)); 427ff94bc40SHeiko Schocher pr_err("\tatime %lld.%u\n", 428ff94bc40SHeiko Schocher (long long)le64_to_cpu(ino->atime_sec), 429ff94bc40SHeiko Schocher le32_to_cpu(ino->atime_nsec)); 430ff94bc40SHeiko Schocher pr_err("\tmtime %lld.%u\n", 431ff94bc40SHeiko Schocher (long long)le64_to_cpu(ino->mtime_sec), 432ff94bc40SHeiko Schocher le32_to_cpu(ino->mtime_nsec)); 433ff94bc40SHeiko Schocher pr_err("\tctime %lld.%u\n", 434ff94bc40SHeiko Schocher (long long)le64_to_cpu(ino->ctime_sec), 435ff94bc40SHeiko Schocher le32_to_cpu(ino->ctime_nsec)); 436ff94bc40SHeiko Schocher pr_err("\tuid %u\n", le32_to_cpu(ino->uid)); 437ff94bc40SHeiko Schocher pr_err("\tgid %u\n", le32_to_cpu(ino->gid)); 438ff94bc40SHeiko Schocher pr_err("\tmode %u\n", le32_to_cpu(ino->mode)); 439ff94bc40SHeiko Schocher pr_err("\tflags %#x\n", le32_to_cpu(ino->flags)); 440ff94bc40SHeiko Schocher pr_err("\txattr_cnt %u\n", le32_to_cpu(ino->xattr_cnt)); 441ff94bc40SHeiko Schocher pr_err("\txattr_size %u\n", le32_to_cpu(ino->xattr_size)); 442ff94bc40SHeiko Schocher pr_err("\txattr_names %u\n", le32_to_cpu(ino->xattr_names)); 443ff94bc40SHeiko Schocher pr_err("\tcompr_type %#x\n", 444ff94bc40SHeiko Schocher (int)le16_to_cpu(ino->compr_type)); 445ff94bc40SHeiko Schocher pr_err("\tdata len %u\n", le32_to_cpu(ino->data_len)); 446ff94bc40SHeiko Schocher break; 447ff94bc40SHeiko Schocher } 448ff94bc40SHeiko Schocher case UBIFS_DENT_NODE: 449ff94bc40SHeiko Schocher case UBIFS_XENT_NODE: 450ff94bc40SHeiko Schocher { 451ff94bc40SHeiko Schocher const struct ubifs_dent_node *dent = node; 452ff94bc40SHeiko Schocher int nlen = le16_to_cpu(dent->nlen); 453ff94bc40SHeiko Schocher 454ff94bc40SHeiko Schocher key_read(c, &dent->key, &key); 455ff94bc40SHeiko Schocher pr_err("\tkey %s\n", 456ff94bc40SHeiko Schocher dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); 457ff94bc40SHeiko Schocher pr_err("\tinum %llu\n", 458ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(dent->inum)); 459ff94bc40SHeiko Schocher pr_err("\ttype %d\n", (int)dent->type); 460ff94bc40SHeiko Schocher pr_err("\tnlen %d\n", nlen); 461ff94bc40SHeiko Schocher pr_err("\tname "); 462ff94bc40SHeiko Schocher 463ff94bc40SHeiko Schocher if (nlen > UBIFS_MAX_NLEN) 464ff94bc40SHeiko Schocher pr_err("(bad name length, not printing, bad or corrupted node)"); 465ff94bc40SHeiko Schocher else { 466ff94bc40SHeiko Schocher for (i = 0; i < nlen && dent->name[i]; i++) 467ff94bc40SHeiko Schocher pr_cont("%c", dent->name[i]); 468ff94bc40SHeiko Schocher } 469ff94bc40SHeiko Schocher pr_cont("\n"); 470ff94bc40SHeiko Schocher 471ff94bc40SHeiko Schocher break; 472ff94bc40SHeiko Schocher } 473ff94bc40SHeiko Schocher case UBIFS_DATA_NODE: 474ff94bc40SHeiko Schocher { 475ff94bc40SHeiko Schocher const struct ubifs_data_node *dn = node; 476ff94bc40SHeiko Schocher int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ; 477ff94bc40SHeiko Schocher 478ff94bc40SHeiko Schocher key_read(c, &dn->key, &key); 479ff94bc40SHeiko Schocher pr_err("\tkey %s\n", 480ff94bc40SHeiko Schocher dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); 481ff94bc40SHeiko Schocher pr_err("\tsize %u\n", le32_to_cpu(dn->size)); 482ff94bc40SHeiko Schocher pr_err("\tcompr_typ %d\n", 483ff94bc40SHeiko Schocher (int)le16_to_cpu(dn->compr_type)); 484ff94bc40SHeiko Schocher pr_err("\tdata size %d\n", dlen); 485ff94bc40SHeiko Schocher pr_err("\tdata:\n"); 486ff94bc40SHeiko Schocher print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1, 487ff94bc40SHeiko Schocher (void *)&dn->data, dlen, 0); 488ff94bc40SHeiko Schocher break; 489ff94bc40SHeiko Schocher } 490ff94bc40SHeiko Schocher case UBIFS_TRUN_NODE: 491ff94bc40SHeiko Schocher { 492ff94bc40SHeiko Schocher const struct ubifs_trun_node *trun = node; 493ff94bc40SHeiko Schocher 494ff94bc40SHeiko Schocher pr_err("\tinum %u\n", le32_to_cpu(trun->inum)); 495ff94bc40SHeiko Schocher pr_err("\told_size %llu\n", 496ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(trun->old_size)); 497ff94bc40SHeiko Schocher pr_err("\tnew_size %llu\n", 498ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(trun->new_size)); 499ff94bc40SHeiko Schocher break; 500ff94bc40SHeiko Schocher } 501ff94bc40SHeiko Schocher case UBIFS_IDX_NODE: 502ff94bc40SHeiko Schocher { 503ff94bc40SHeiko Schocher const struct ubifs_idx_node *idx = node; 504ff94bc40SHeiko Schocher 505ff94bc40SHeiko Schocher n = le16_to_cpu(idx->child_cnt); 506ff94bc40SHeiko Schocher pr_err("\tchild_cnt %d\n", n); 507ff94bc40SHeiko Schocher pr_err("\tlevel %d\n", (int)le16_to_cpu(idx->level)); 508ff94bc40SHeiko Schocher pr_err("\tBranches:\n"); 509ff94bc40SHeiko Schocher 510ff94bc40SHeiko Schocher for (i = 0; i < n && i < c->fanout - 1; i++) { 511ff94bc40SHeiko Schocher const struct ubifs_branch *br; 512ff94bc40SHeiko Schocher 513ff94bc40SHeiko Schocher br = ubifs_idx_branch(c, idx, i); 514ff94bc40SHeiko Schocher key_read(c, &br->key, &key); 515ff94bc40SHeiko Schocher pr_err("\t%d: LEB %d:%d len %d key %s\n", 516ff94bc40SHeiko Schocher i, le32_to_cpu(br->lnum), le32_to_cpu(br->offs), 517ff94bc40SHeiko Schocher le32_to_cpu(br->len), 518ff94bc40SHeiko Schocher dbg_snprintf_key(c, &key, key_buf, 519ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 520ff94bc40SHeiko Schocher } 521ff94bc40SHeiko Schocher break; 522ff94bc40SHeiko Schocher } 523ff94bc40SHeiko Schocher case UBIFS_CS_NODE: 524ff94bc40SHeiko Schocher break; 525ff94bc40SHeiko Schocher case UBIFS_ORPH_NODE: 526ff94bc40SHeiko Schocher { 527ff94bc40SHeiko Schocher const struct ubifs_orph_node *orph = node; 528ff94bc40SHeiko Schocher 529ff94bc40SHeiko Schocher pr_err("\tcommit number %llu\n", 530ff94bc40SHeiko Schocher (unsigned long long) 531ff94bc40SHeiko Schocher le64_to_cpu(orph->cmt_no) & LLONG_MAX); 532ff94bc40SHeiko Schocher pr_err("\tlast node flag %llu\n", 533ff94bc40SHeiko Schocher (unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63); 534ff94bc40SHeiko Schocher n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3; 535ff94bc40SHeiko Schocher pr_err("\t%d orphan inode numbers:\n", n); 536ff94bc40SHeiko Schocher for (i = 0; i < n; i++) 537ff94bc40SHeiko Schocher pr_err("\t ino %llu\n", 538ff94bc40SHeiko Schocher (unsigned long long)le64_to_cpu(orph->inos[i])); 539ff94bc40SHeiko Schocher break; 540ff94bc40SHeiko Schocher } 541ff94bc40SHeiko Schocher default: 542ff94bc40SHeiko Schocher pr_err("node type %d was not recognized\n", 543ff94bc40SHeiko Schocher (int)ch->node_type); 544ff94bc40SHeiko Schocher } 545ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 546ff94bc40SHeiko Schocher } 547ff94bc40SHeiko Schocher 548ff94bc40SHeiko Schocher void ubifs_dump_budget_req(const struct ubifs_budget_req *req) 549ff94bc40SHeiko Schocher { 550ff94bc40SHeiko Schocher spin_lock(&dbg_lock); 551ff94bc40SHeiko Schocher pr_err("Budgeting request: new_ino %d, dirtied_ino %d\n", 552ff94bc40SHeiko Schocher req->new_ino, req->dirtied_ino); 553ff94bc40SHeiko Schocher pr_err("\tnew_ino_d %d, dirtied_ino_d %d\n", 554ff94bc40SHeiko Schocher req->new_ino_d, req->dirtied_ino_d); 555ff94bc40SHeiko Schocher pr_err("\tnew_page %d, dirtied_page %d\n", 556ff94bc40SHeiko Schocher req->new_page, req->dirtied_page); 557ff94bc40SHeiko Schocher pr_err("\tnew_dent %d, mod_dent %d\n", 558ff94bc40SHeiko Schocher req->new_dent, req->mod_dent); 559ff94bc40SHeiko Schocher pr_err("\tidx_growth %d\n", req->idx_growth); 560ff94bc40SHeiko Schocher pr_err("\tdata_growth %d dd_growth %d\n", 561ff94bc40SHeiko Schocher req->data_growth, req->dd_growth); 562ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 563ff94bc40SHeiko Schocher } 564ff94bc40SHeiko Schocher 565ff94bc40SHeiko Schocher void ubifs_dump_lstats(const struct ubifs_lp_stats *lst) 566ff94bc40SHeiko Schocher { 567ff94bc40SHeiko Schocher spin_lock(&dbg_lock); 568ff94bc40SHeiko Schocher pr_err("(pid %d) Lprops statistics: empty_lebs %d, idx_lebs %d\n", 569ff94bc40SHeiko Schocher current->pid, lst->empty_lebs, lst->idx_lebs); 570ff94bc40SHeiko Schocher pr_err("\ttaken_empty_lebs %d, total_free %lld, total_dirty %lld\n", 571ff94bc40SHeiko Schocher lst->taken_empty_lebs, lst->total_free, lst->total_dirty); 572ff94bc40SHeiko Schocher pr_err("\ttotal_used %lld, total_dark %lld, total_dead %lld\n", 573ff94bc40SHeiko Schocher lst->total_used, lst->total_dark, lst->total_dead); 574ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 575ff94bc40SHeiko Schocher } 576ff94bc40SHeiko Schocher 577ff94bc40SHeiko Schocher #ifndef __UBOOT__ 578ff94bc40SHeiko Schocher void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi) 579ff94bc40SHeiko Schocher { 580ff94bc40SHeiko Schocher int i; 581ff94bc40SHeiko Schocher struct rb_node *rb; 582ff94bc40SHeiko Schocher struct ubifs_bud *bud; 583ff94bc40SHeiko Schocher struct ubifs_gced_idx_leb *idx_gc; 584ff94bc40SHeiko Schocher long long available, outstanding, free; 585ff94bc40SHeiko Schocher 586ff94bc40SHeiko Schocher spin_lock(&c->space_lock); 587ff94bc40SHeiko Schocher spin_lock(&dbg_lock); 588ff94bc40SHeiko Schocher pr_err("(pid %d) Budgeting info: data budget sum %lld, total budget sum %lld\n", 589ff94bc40SHeiko Schocher current->pid, bi->data_growth + bi->dd_growth, 590ff94bc40SHeiko Schocher bi->data_growth + bi->dd_growth + bi->idx_growth); 591ff94bc40SHeiko Schocher pr_err("\tbudg_data_growth %lld, budg_dd_growth %lld, budg_idx_growth %lld\n", 592ff94bc40SHeiko Schocher bi->data_growth, bi->dd_growth, bi->idx_growth); 593ff94bc40SHeiko Schocher pr_err("\tmin_idx_lebs %d, old_idx_sz %llu, uncommitted_idx %lld\n", 594ff94bc40SHeiko Schocher bi->min_idx_lebs, bi->old_idx_sz, bi->uncommitted_idx); 595ff94bc40SHeiko Schocher pr_err("\tpage_budget %d, inode_budget %d, dent_budget %d\n", 596ff94bc40SHeiko Schocher bi->page_budget, bi->inode_budget, bi->dent_budget); 597ff94bc40SHeiko Schocher pr_err("\tnospace %u, nospace_rp %u\n", bi->nospace, bi->nospace_rp); 598ff94bc40SHeiko Schocher pr_err("\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n", 599ff94bc40SHeiko Schocher c->dark_wm, c->dead_wm, c->max_idx_node_sz); 600ff94bc40SHeiko Schocher 601ff94bc40SHeiko Schocher if (bi != &c->bi) 602ff94bc40SHeiko Schocher /* 603ff94bc40SHeiko Schocher * If we are dumping saved budgeting data, do not print 604ff94bc40SHeiko Schocher * additional information which is about the current state, not 605ff94bc40SHeiko Schocher * the old one which corresponded to the saved budgeting data. 606ff94bc40SHeiko Schocher */ 607ff94bc40SHeiko Schocher goto out_unlock; 608ff94bc40SHeiko Schocher 609ff94bc40SHeiko Schocher pr_err("\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n", 610ff94bc40SHeiko Schocher c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt); 611ff94bc40SHeiko Schocher pr_err("\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, clean_zn_cnt %ld\n", 612ff94bc40SHeiko Schocher atomic_long_read(&c->dirty_pg_cnt), 613ff94bc40SHeiko Schocher atomic_long_read(&c->dirty_zn_cnt), 614ff94bc40SHeiko Schocher atomic_long_read(&c->clean_zn_cnt)); 615ff94bc40SHeiko Schocher pr_err("\tgc_lnum %d, ihead_lnum %d\n", c->gc_lnum, c->ihead_lnum); 616ff94bc40SHeiko Schocher 617ff94bc40SHeiko Schocher /* If we are in R/O mode, journal heads do not exist */ 618ff94bc40SHeiko Schocher if (c->jheads) 619ff94bc40SHeiko Schocher for (i = 0; i < c->jhead_cnt; i++) 620ff94bc40SHeiko Schocher pr_err("\tjhead %s\t LEB %d\n", 621ff94bc40SHeiko Schocher dbg_jhead(c->jheads[i].wbuf.jhead), 622ff94bc40SHeiko Schocher c->jheads[i].wbuf.lnum); 623ff94bc40SHeiko Schocher for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) { 624ff94bc40SHeiko Schocher bud = rb_entry(rb, struct ubifs_bud, rb); 625ff94bc40SHeiko Schocher pr_err("\tbud LEB %d\n", bud->lnum); 626ff94bc40SHeiko Schocher } 627ff94bc40SHeiko Schocher list_for_each_entry(bud, &c->old_buds, list) 628ff94bc40SHeiko Schocher pr_err("\told bud LEB %d\n", bud->lnum); 629ff94bc40SHeiko Schocher list_for_each_entry(idx_gc, &c->idx_gc, list) 630ff94bc40SHeiko Schocher pr_err("\tGC'ed idx LEB %d unmap %d\n", 631ff94bc40SHeiko Schocher idx_gc->lnum, idx_gc->unmap); 632ff94bc40SHeiko Schocher pr_err("\tcommit state %d\n", c->cmt_state); 633ff94bc40SHeiko Schocher 634ff94bc40SHeiko Schocher /* Print budgeting predictions */ 635ff94bc40SHeiko Schocher available = ubifs_calc_available(c, c->bi.min_idx_lebs); 636ff94bc40SHeiko Schocher outstanding = c->bi.data_growth + c->bi.dd_growth; 637ff94bc40SHeiko Schocher free = ubifs_get_free_space_nolock(c); 638ff94bc40SHeiko Schocher pr_err("Budgeting predictions:\n"); 639ff94bc40SHeiko Schocher pr_err("\tavailable: %lld, outstanding %lld, free %lld\n", 640ff94bc40SHeiko Schocher available, outstanding, free); 641ff94bc40SHeiko Schocher out_unlock: 642ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 643ff94bc40SHeiko Schocher spin_unlock(&c->space_lock); 644ff94bc40SHeiko Schocher } 645ff94bc40SHeiko Schocher #else 646ff94bc40SHeiko Schocher void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi) 647ff94bc40SHeiko Schocher { 648ff94bc40SHeiko Schocher } 649ff94bc40SHeiko Schocher #endif 650ff94bc40SHeiko Schocher 651ff94bc40SHeiko Schocher void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp) 652ff94bc40SHeiko Schocher { 653ff94bc40SHeiko Schocher int i, spc, dark = 0, dead = 0; 654ff94bc40SHeiko Schocher struct rb_node *rb; 655ff94bc40SHeiko Schocher struct ubifs_bud *bud; 656ff94bc40SHeiko Schocher 657ff94bc40SHeiko Schocher spc = lp->free + lp->dirty; 658ff94bc40SHeiko Schocher if (spc < c->dead_wm) 659ff94bc40SHeiko Schocher dead = spc; 660ff94bc40SHeiko Schocher else 661ff94bc40SHeiko Schocher dark = ubifs_calc_dark(c, spc); 662ff94bc40SHeiko Schocher 663ff94bc40SHeiko Schocher if (lp->flags & LPROPS_INDEX) 664ff94bc40SHeiko Schocher pr_err("LEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d flags %#x (", 665ff94bc40SHeiko Schocher lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc, 666ff94bc40SHeiko Schocher lp->flags); 667ff94bc40SHeiko Schocher else 668ff94bc40SHeiko Schocher pr_err("LEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d flags %#-4x (", 669ff94bc40SHeiko Schocher lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc, 670ff94bc40SHeiko Schocher dark, dead, (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags); 671ff94bc40SHeiko Schocher 672ff94bc40SHeiko Schocher if (lp->flags & LPROPS_TAKEN) { 673ff94bc40SHeiko Schocher if (lp->flags & LPROPS_INDEX) 674ff94bc40SHeiko Schocher pr_cont("index, taken"); 675ff94bc40SHeiko Schocher else 676ff94bc40SHeiko Schocher pr_cont("taken"); 677ff94bc40SHeiko Schocher } else { 678ff94bc40SHeiko Schocher const char *s; 679ff94bc40SHeiko Schocher 680ff94bc40SHeiko Schocher if (lp->flags & LPROPS_INDEX) { 681ff94bc40SHeiko Schocher switch (lp->flags & LPROPS_CAT_MASK) { 682ff94bc40SHeiko Schocher case LPROPS_DIRTY_IDX: 683ff94bc40SHeiko Schocher s = "dirty index"; 684ff94bc40SHeiko Schocher break; 685ff94bc40SHeiko Schocher case LPROPS_FRDI_IDX: 686ff94bc40SHeiko Schocher s = "freeable index"; 687ff94bc40SHeiko Schocher break; 688ff94bc40SHeiko Schocher default: 689ff94bc40SHeiko Schocher s = "index"; 690ff94bc40SHeiko Schocher } 691ff94bc40SHeiko Schocher } else { 692ff94bc40SHeiko Schocher switch (lp->flags & LPROPS_CAT_MASK) { 693ff94bc40SHeiko Schocher case LPROPS_UNCAT: 694ff94bc40SHeiko Schocher s = "not categorized"; 695ff94bc40SHeiko Schocher break; 696ff94bc40SHeiko Schocher case LPROPS_DIRTY: 697ff94bc40SHeiko Schocher s = "dirty"; 698ff94bc40SHeiko Schocher break; 699ff94bc40SHeiko Schocher case LPROPS_FREE: 700ff94bc40SHeiko Schocher s = "free"; 701ff94bc40SHeiko Schocher break; 702ff94bc40SHeiko Schocher case LPROPS_EMPTY: 703ff94bc40SHeiko Schocher s = "empty"; 704ff94bc40SHeiko Schocher break; 705ff94bc40SHeiko Schocher case LPROPS_FREEABLE: 706ff94bc40SHeiko Schocher s = "freeable"; 707ff94bc40SHeiko Schocher break; 708ff94bc40SHeiko Schocher default: 709ff94bc40SHeiko Schocher s = NULL; 710ff94bc40SHeiko Schocher break; 711ff94bc40SHeiko Schocher } 712ff94bc40SHeiko Schocher } 713ff94bc40SHeiko Schocher pr_cont("%s", s); 714ff94bc40SHeiko Schocher } 715ff94bc40SHeiko Schocher 716ff94bc40SHeiko Schocher for (rb = rb_first((struct rb_root *)&c->buds); rb; rb = rb_next(rb)) { 717ff94bc40SHeiko Schocher bud = rb_entry(rb, struct ubifs_bud, rb); 718ff94bc40SHeiko Schocher if (bud->lnum == lp->lnum) { 719ff94bc40SHeiko Schocher int head = 0; 720ff94bc40SHeiko Schocher for (i = 0; i < c->jhead_cnt; i++) { 721ff94bc40SHeiko Schocher /* 722ff94bc40SHeiko Schocher * Note, if we are in R/O mode or in the middle 723ff94bc40SHeiko Schocher * of mounting/re-mounting, the write-buffers do 724ff94bc40SHeiko Schocher * not exist. 725ff94bc40SHeiko Schocher */ 726ff94bc40SHeiko Schocher if (c->jheads && 727ff94bc40SHeiko Schocher lp->lnum == c->jheads[i].wbuf.lnum) { 728ff94bc40SHeiko Schocher pr_cont(", jhead %s", dbg_jhead(i)); 729ff94bc40SHeiko Schocher head = 1; 730ff94bc40SHeiko Schocher } 731ff94bc40SHeiko Schocher } 732ff94bc40SHeiko Schocher if (!head) 733ff94bc40SHeiko Schocher pr_cont(", bud of jhead %s", 734ff94bc40SHeiko Schocher dbg_jhead(bud->jhead)); 735ff94bc40SHeiko Schocher } 736ff94bc40SHeiko Schocher } 737ff94bc40SHeiko Schocher if (lp->lnum == c->gc_lnum) 738ff94bc40SHeiko Schocher pr_cont(", GC LEB"); 739ff94bc40SHeiko Schocher pr_cont(")\n"); 740ff94bc40SHeiko Schocher } 741ff94bc40SHeiko Schocher 742ff94bc40SHeiko Schocher void ubifs_dump_lprops(struct ubifs_info *c) 743ff94bc40SHeiko Schocher { 744ff94bc40SHeiko Schocher int lnum, err; 745ff94bc40SHeiko Schocher struct ubifs_lprops lp; 746ff94bc40SHeiko Schocher struct ubifs_lp_stats lst; 747ff94bc40SHeiko Schocher 748ff94bc40SHeiko Schocher pr_err("(pid %d) start dumping LEB properties\n", current->pid); 749ff94bc40SHeiko Schocher ubifs_get_lp_stats(c, &lst); 750ff94bc40SHeiko Schocher ubifs_dump_lstats(&lst); 751ff94bc40SHeiko Schocher 752ff94bc40SHeiko Schocher for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) { 753ff94bc40SHeiko Schocher err = ubifs_read_one_lp(c, lnum, &lp); 754*0195a7bbSHeiko Schocher if (err) { 755*0195a7bbSHeiko Schocher ubifs_err(c, "cannot read lprops for LEB %d", lnum); 756*0195a7bbSHeiko Schocher continue; 757*0195a7bbSHeiko Schocher } 758ff94bc40SHeiko Schocher 759ff94bc40SHeiko Schocher ubifs_dump_lprop(c, &lp); 760ff94bc40SHeiko Schocher } 761ff94bc40SHeiko Schocher pr_err("(pid %d) finish dumping LEB properties\n", current->pid); 762ff94bc40SHeiko Schocher } 763ff94bc40SHeiko Schocher 764ff94bc40SHeiko Schocher void ubifs_dump_lpt_info(struct ubifs_info *c) 765ff94bc40SHeiko Schocher { 766ff94bc40SHeiko Schocher int i; 767ff94bc40SHeiko Schocher 768ff94bc40SHeiko Schocher spin_lock(&dbg_lock); 769ff94bc40SHeiko Schocher pr_err("(pid %d) dumping LPT information\n", current->pid); 770ff94bc40SHeiko Schocher pr_err("\tlpt_sz: %lld\n", c->lpt_sz); 771ff94bc40SHeiko Schocher pr_err("\tpnode_sz: %d\n", c->pnode_sz); 772ff94bc40SHeiko Schocher pr_err("\tnnode_sz: %d\n", c->nnode_sz); 773ff94bc40SHeiko Schocher pr_err("\tltab_sz: %d\n", c->ltab_sz); 774ff94bc40SHeiko Schocher pr_err("\tlsave_sz: %d\n", c->lsave_sz); 775ff94bc40SHeiko Schocher pr_err("\tbig_lpt: %d\n", c->big_lpt); 776ff94bc40SHeiko Schocher pr_err("\tlpt_hght: %d\n", c->lpt_hght); 777ff94bc40SHeiko Schocher pr_err("\tpnode_cnt: %d\n", c->pnode_cnt); 778ff94bc40SHeiko Schocher pr_err("\tnnode_cnt: %d\n", c->nnode_cnt); 779ff94bc40SHeiko Schocher pr_err("\tdirty_pn_cnt: %d\n", c->dirty_pn_cnt); 780ff94bc40SHeiko Schocher pr_err("\tdirty_nn_cnt: %d\n", c->dirty_nn_cnt); 781ff94bc40SHeiko Schocher pr_err("\tlsave_cnt: %d\n", c->lsave_cnt); 782ff94bc40SHeiko Schocher pr_err("\tspace_bits: %d\n", c->space_bits); 783ff94bc40SHeiko Schocher pr_err("\tlpt_lnum_bits: %d\n", c->lpt_lnum_bits); 784ff94bc40SHeiko Schocher pr_err("\tlpt_offs_bits: %d\n", c->lpt_offs_bits); 785ff94bc40SHeiko Schocher pr_err("\tlpt_spc_bits: %d\n", c->lpt_spc_bits); 786ff94bc40SHeiko Schocher pr_err("\tpcnt_bits: %d\n", c->pcnt_bits); 787ff94bc40SHeiko Schocher pr_err("\tlnum_bits: %d\n", c->lnum_bits); 788ff94bc40SHeiko Schocher pr_err("\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs); 789ff94bc40SHeiko Schocher pr_err("\tLPT head is at %d:%d\n", 790ff94bc40SHeiko Schocher c->nhead_lnum, c->nhead_offs); 791ff94bc40SHeiko Schocher pr_err("\tLPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs); 792ff94bc40SHeiko Schocher if (c->big_lpt) 793ff94bc40SHeiko Schocher pr_err("\tLPT lsave is at %d:%d\n", 794ff94bc40SHeiko Schocher c->lsave_lnum, c->lsave_offs); 795ff94bc40SHeiko Schocher for (i = 0; i < c->lpt_lebs; i++) 796ff94bc40SHeiko Schocher pr_err("\tLPT LEB %d free %d dirty %d tgc %d cmt %d\n", 797ff94bc40SHeiko Schocher i + c->lpt_first, c->ltab[i].free, c->ltab[i].dirty, 798ff94bc40SHeiko Schocher c->ltab[i].tgc, c->ltab[i].cmt); 799ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 800ff94bc40SHeiko Schocher } 801ff94bc40SHeiko Schocher 802ff94bc40SHeiko Schocher void ubifs_dump_sleb(const struct ubifs_info *c, 803ff94bc40SHeiko Schocher const struct ubifs_scan_leb *sleb, int offs) 804ff94bc40SHeiko Schocher { 805ff94bc40SHeiko Schocher struct ubifs_scan_node *snod; 806ff94bc40SHeiko Schocher 807ff94bc40SHeiko Schocher pr_err("(pid %d) start dumping scanned data from LEB %d:%d\n", 808ff94bc40SHeiko Schocher current->pid, sleb->lnum, offs); 809ff94bc40SHeiko Schocher 810ff94bc40SHeiko Schocher list_for_each_entry(snod, &sleb->nodes, list) { 811ff94bc40SHeiko Schocher cond_resched(); 812ff94bc40SHeiko Schocher pr_err("Dumping node at LEB %d:%d len %d\n", 813ff94bc40SHeiko Schocher sleb->lnum, snod->offs, snod->len); 814ff94bc40SHeiko Schocher ubifs_dump_node(c, snod->node); 815ff94bc40SHeiko Schocher } 816ff94bc40SHeiko Schocher } 817ff94bc40SHeiko Schocher 818ff94bc40SHeiko Schocher void ubifs_dump_leb(const struct ubifs_info *c, int lnum) 819ff94bc40SHeiko Schocher { 820ff94bc40SHeiko Schocher struct ubifs_scan_leb *sleb; 821ff94bc40SHeiko Schocher struct ubifs_scan_node *snod; 822ff94bc40SHeiko Schocher void *buf; 823ff94bc40SHeiko Schocher 824ff94bc40SHeiko Schocher pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum); 825ff94bc40SHeiko Schocher 826ff94bc40SHeiko Schocher buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); 827ff94bc40SHeiko Schocher if (!buf) { 828*0195a7bbSHeiko Schocher ubifs_err(c, "cannot allocate memory for dumping LEB %d", lnum); 829ff94bc40SHeiko Schocher return; 830ff94bc40SHeiko Schocher } 831ff94bc40SHeiko Schocher 832ff94bc40SHeiko Schocher sleb = ubifs_scan(c, lnum, 0, buf, 0); 833ff94bc40SHeiko Schocher if (IS_ERR(sleb)) { 834*0195a7bbSHeiko Schocher ubifs_err(c, "scan error %d", (int)PTR_ERR(sleb)); 835ff94bc40SHeiko Schocher goto out; 836ff94bc40SHeiko Schocher } 837ff94bc40SHeiko Schocher 838ff94bc40SHeiko Schocher pr_err("LEB %d has %d nodes ending at %d\n", lnum, 839ff94bc40SHeiko Schocher sleb->nodes_cnt, sleb->endpt); 840ff94bc40SHeiko Schocher 841ff94bc40SHeiko Schocher list_for_each_entry(snod, &sleb->nodes, list) { 842ff94bc40SHeiko Schocher cond_resched(); 843ff94bc40SHeiko Schocher pr_err("Dumping node at LEB %d:%d len %d\n", lnum, 844ff94bc40SHeiko Schocher snod->offs, snod->len); 845ff94bc40SHeiko Schocher ubifs_dump_node(c, snod->node); 846ff94bc40SHeiko Schocher } 847ff94bc40SHeiko Schocher 848ff94bc40SHeiko Schocher pr_err("(pid %d) finish dumping LEB %d\n", current->pid, lnum); 849ff94bc40SHeiko Schocher ubifs_scan_destroy(sleb); 850ff94bc40SHeiko Schocher 851ff94bc40SHeiko Schocher out: 852ff94bc40SHeiko Schocher vfree(buf); 853ff94bc40SHeiko Schocher return; 854ff94bc40SHeiko Schocher } 855ff94bc40SHeiko Schocher 856ff94bc40SHeiko Schocher void ubifs_dump_znode(const struct ubifs_info *c, 857ff94bc40SHeiko Schocher const struct ubifs_znode *znode) 858ff94bc40SHeiko Schocher { 859ff94bc40SHeiko Schocher int n; 860ff94bc40SHeiko Schocher const struct ubifs_zbranch *zbr; 861ff94bc40SHeiko Schocher char key_buf[DBG_KEY_BUF_LEN]; 862ff94bc40SHeiko Schocher 863ff94bc40SHeiko Schocher spin_lock(&dbg_lock); 864ff94bc40SHeiko Schocher if (znode->parent) 865ff94bc40SHeiko Schocher zbr = &znode->parent->zbranch[znode->iip]; 866ff94bc40SHeiko Schocher else 867ff94bc40SHeiko Schocher zbr = &c->zroot; 868ff94bc40SHeiko Schocher 869ff94bc40SHeiko Schocher pr_err("znode %p, LEB %d:%d len %d parent %p iip %d level %d child_cnt %d flags %lx\n", 870ff94bc40SHeiko Schocher znode, zbr->lnum, zbr->offs, zbr->len, znode->parent, znode->iip, 871ff94bc40SHeiko Schocher znode->level, znode->child_cnt, znode->flags); 872ff94bc40SHeiko Schocher 873ff94bc40SHeiko Schocher if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) { 874ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 875ff94bc40SHeiko Schocher return; 876ff94bc40SHeiko Schocher } 877ff94bc40SHeiko Schocher 878ff94bc40SHeiko Schocher pr_err("zbranches:\n"); 879ff94bc40SHeiko Schocher for (n = 0; n < znode->child_cnt; n++) { 880ff94bc40SHeiko Schocher zbr = &znode->zbranch[n]; 881ff94bc40SHeiko Schocher if (znode->level > 0) 882ff94bc40SHeiko Schocher pr_err("\t%d: znode %p LEB %d:%d len %d key %s\n", 883ff94bc40SHeiko Schocher n, zbr->znode, zbr->lnum, zbr->offs, zbr->len, 884ff94bc40SHeiko Schocher dbg_snprintf_key(c, &zbr->key, key_buf, 885ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 886ff94bc40SHeiko Schocher else 887ff94bc40SHeiko Schocher pr_err("\t%d: LNC %p LEB %d:%d len %d key %s\n", 888ff94bc40SHeiko Schocher n, zbr->znode, zbr->lnum, zbr->offs, zbr->len, 889ff94bc40SHeiko Schocher dbg_snprintf_key(c, &zbr->key, key_buf, 890ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 891ff94bc40SHeiko Schocher } 892ff94bc40SHeiko Schocher spin_unlock(&dbg_lock); 893ff94bc40SHeiko Schocher } 894ff94bc40SHeiko Schocher 895ff94bc40SHeiko Schocher void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat) 896ff94bc40SHeiko Schocher { 897ff94bc40SHeiko Schocher int i; 898ff94bc40SHeiko Schocher 899ff94bc40SHeiko Schocher pr_err("(pid %d) start dumping heap cat %d (%d elements)\n", 900ff94bc40SHeiko Schocher current->pid, cat, heap->cnt); 901ff94bc40SHeiko Schocher for (i = 0; i < heap->cnt; i++) { 902ff94bc40SHeiko Schocher struct ubifs_lprops *lprops = heap->arr[i]; 903ff94bc40SHeiko Schocher 904ff94bc40SHeiko Schocher pr_err("\t%d. LEB %d hpos %d free %d dirty %d flags %d\n", 905ff94bc40SHeiko Schocher i, lprops->lnum, lprops->hpos, lprops->free, 906ff94bc40SHeiko Schocher lprops->dirty, lprops->flags); 907ff94bc40SHeiko Schocher } 908ff94bc40SHeiko Schocher pr_err("(pid %d) finish dumping heap\n", current->pid); 909ff94bc40SHeiko Schocher } 910ff94bc40SHeiko Schocher 911ff94bc40SHeiko Schocher void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, 912ff94bc40SHeiko Schocher struct ubifs_nnode *parent, int iip) 913ff94bc40SHeiko Schocher { 914ff94bc40SHeiko Schocher int i; 915ff94bc40SHeiko Schocher 916ff94bc40SHeiko Schocher pr_err("(pid %d) dumping pnode:\n", current->pid); 917ff94bc40SHeiko Schocher pr_err("\taddress %zx parent %zx cnext %zx\n", 918ff94bc40SHeiko Schocher (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); 919ff94bc40SHeiko Schocher pr_err("\tflags %lu iip %d level %d num %d\n", 920ff94bc40SHeiko Schocher pnode->flags, iip, pnode->level, pnode->num); 921ff94bc40SHeiko Schocher for (i = 0; i < UBIFS_LPT_FANOUT; i++) { 922ff94bc40SHeiko Schocher struct ubifs_lprops *lp = &pnode->lprops[i]; 923ff94bc40SHeiko Schocher 924ff94bc40SHeiko Schocher pr_err("\t%d: free %d dirty %d flags %d lnum %d\n", 925ff94bc40SHeiko Schocher i, lp->free, lp->dirty, lp->flags, lp->lnum); 926ff94bc40SHeiko Schocher } 927ff94bc40SHeiko Schocher } 928ff94bc40SHeiko Schocher 929ff94bc40SHeiko Schocher void ubifs_dump_tnc(struct ubifs_info *c) 930ff94bc40SHeiko Schocher { 931ff94bc40SHeiko Schocher struct ubifs_znode *znode; 932ff94bc40SHeiko Schocher int level; 933ff94bc40SHeiko Schocher 934ff94bc40SHeiko Schocher pr_err("\n"); 935ff94bc40SHeiko Schocher pr_err("(pid %d) start dumping TNC tree\n", current->pid); 936ff94bc40SHeiko Schocher znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); 937ff94bc40SHeiko Schocher level = znode->level; 938ff94bc40SHeiko Schocher pr_err("== Level %d ==\n", level); 939ff94bc40SHeiko Schocher while (znode) { 940ff94bc40SHeiko Schocher if (level != znode->level) { 941ff94bc40SHeiko Schocher level = znode->level; 942ff94bc40SHeiko Schocher pr_err("== Level %d ==\n", level); 943ff94bc40SHeiko Schocher } 944ff94bc40SHeiko Schocher ubifs_dump_znode(c, znode); 945ff94bc40SHeiko Schocher znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); 946ff94bc40SHeiko Schocher } 947ff94bc40SHeiko Schocher pr_err("(pid %d) finish dumping TNC tree\n", current->pid); 948ff94bc40SHeiko Schocher } 949ff94bc40SHeiko Schocher 950ff94bc40SHeiko Schocher static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode, 951ff94bc40SHeiko Schocher void *priv) 952ff94bc40SHeiko Schocher { 953ff94bc40SHeiko Schocher ubifs_dump_znode(c, znode); 954ff94bc40SHeiko Schocher return 0; 955ff94bc40SHeiko Schocher } 956ff94bc40SHeiko Schocher 957ff94bc40SHeiko Schocher /** 958ff94bc40SHeiko Schocher * ubifs_dump_index - dump the on-flash index. 959ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 960ff94bc40SHeiko Schocher * 961ff94bc40SHeiko Schocher * This function dumps whole UBIFS indexing B-tree, unlike 'ubifs_dump_tnc()' 962ff94bc40SHeiko Schocher * which dumps only in-memory znodes and does not read znodes which from flash. 963ff94bc40SHeiko Schocher */ 964ff94bc40SHeiko Schocher void ubifs_dump_index(struct ubifs_info *c) 965ff94bc40SHeiko Schocher { 966ff94bc40SHeiko Schocher dbg_walk_index(c, NULL, dump_znode, NULL); 967ff94bc40SHeiko Schocher } 968ff94bc40SHeiko Schocher 969ff94bc40SHeiko Schocher #ifndef __UBOOT__ 970ff94bc40SHeiko Schocher /** 971ff94bc40SHeiko Schocher * dbg_save_space_info - save information about flash space. 972ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 973ff94bc40SHeiko Schocher * 974ff94bc40SHeiko Schocher * This function saves information about UBIFS free space, dirty space, etc, in 975ff94bc40SHeiko Schocher * order to check it later. 976ff94bc40SHeiko Schocher */ 977ff94bc40SHeiko Schocher void dbg_save_space_info(struct ubifs_info *c) 978ff94bc40SHeiko Schocher { 979ff94bc40SHeiko Schocher struct ubifs_debug_info *d = c->dbg; 980ff94bc40SHeiko Schocher int freeable_cnt; 981ff94bc40SHeiko Schocher 982ff94bc40SHeiko Schocher spin_lock(&c->space_lock); 983ff94bc40SHeiko Schocher memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats)); 984ff94bc40SHeiko Schocher memcpy(&d->saved_bi, &c->bi, sizeof(struct ubifs_budg_info)); 985ff94bc40SHeiko Schocher d->saved_idx_gc_cnt = c->idx_gc_cnt; 986ff94bc40SHeiko Schocher 987ff94bc40SHeiko Schocher /* 988ff94bc40SHeiko Schocher * We use a dirty hack here and zero out @c->freeable_cnt, because it 989ff94bc40SHeiko Schocher * affects the free space calculations, and UBIFS might not know about 990ff94bc40SHeiko Schocher * all freeable eraseblocks. Indeed, we know about freeable eraseblocks 991ff94bc40SHeiko Schocher * only when we read their lprops, and we do this only lazily, upon the 992ff94bc40SHeiko Schocher * need. So at any given point of time @c->freeable_cnt might be not 993ff94bc40SHeiko Schocher * exactly accurate. 994ff94bc40SHeiko Schocher * 995ff94bc40SHeiko Schocher * Just one example about the issue we hit when we did not zero 996ff94bc40SHeiko Schocher * @c->freeable_cnt. 997ff94bc40SHeiko Schocher * 1. The file-system is mounted R/O, c->freeable_cnt is %0. We save the 998ff94bc40SHeiko Schocher * amount of free space in @d->saved_free 999ff94bc40SHeiko Schocher * 2. We re-mount R/W, which makes UBIFS to read the "lsave" 1000ff94bc40SHeiko Schocher * information from flash, where we cache LEBs from various 1001ff94bc40SHeiko Schocher * categories ('ubifs_remount_fs()' -> 'ubifs_lpt_init()' 1002ff94bc40SHeiko Schocher * -> 'lpt_init_wr()' -> 'read_lsave()' -> 'ubifs_lpt_lookup()' 1003ff94bc40SHeiko Schocher * -> 'ubifs_get_pnode()' -> 'update_cats()' 1004ff94bc40SHeiko Schocher * -> 'ubifs_add_to_cat()'). 1005ff94bc40SHeiko Schocher * 3. Lsave contains a freeable eraseblock, and @c->freeable_cnt 1006ff94bc40SHeiko Schocher * becomes %1. 1007ff94bc40SHeiko Schocher * 4. We calculate the amount of free space when the re-mount is 1008ff94bc40SHeiko Schocher * finished in 'dbg_check_space_info()' and it does not match 1009ff94bc40SHeiko Schocher * @d->saved_free. 1010ff94bc40SHeiko Schocher */ 1011ff94bc40SHeiko Schocher freeable_cnt = c->freeable_cnt; 1012ff94bc40SHeiko Schocher c->freeable_cnt = 0; 1013ff94bc40SHeiko Schocher d->saved_free = ubifs_get_free_space_nolock(c); 1014ff94bc40SHeiko Schocher c->freeable_cnt = freeable_cnt; 1015ff94bc40SHeiko Schocher spin_unlock(&c->space_lock); 1016ff94bc40SHeiko Schocher } 1017ff94bc40SHeiko Schocher 1018ff94bc40SHeiko Schocher /** 1019ff94bc40SHeiko Schocher * dbg_check_space_info - check flash space information. 1020ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1021ff94bc40SHeiko Schocher * 1022ff94bc40SHeiko Schocher * This function compares current flash space information with the information 1023ff94bc40SHeiko Schocher * which was saved when the 'dbg_save_space_info()' function was called. 1024ff94bc40SHeiko Schocher * Returns zero if the information has not changed, and %-EINVAL it it has 1025ff94bc40SHeiko Schocher * changed. 1026ff94bc40SHeiko Schocher */ 1027ff94bc40SHeiko Schocher int dbg_check_space_info(struct ubifs_info *c) 1028ff94bc40SHeiko Schocher { 1029ff94bc40SHeiko Schocher struct ubifs_debug_info *d = c->dbg; 1030ff94bc40SHeiko Schocher struct ubifs_lp_stats lst; 1031ff94bc40SHeiko Schocher long long free; 1032ff94bc40SHeiko Schocher int freeable_cnt; 1033ff94bc40SHeiko Schocher 1034ff94bc40SHeiko Schocher spin_lock(&c->space_lock); 1035ff94bc40SHeiko Schocher freeable_cnt = c->freeable_cnt; 1036ff94bc40SHeiko Schocher c->freeable_cnt = 0; 1037ff94bc40SHeiko Schocher free = ubifs_get_free_space_nolock(c); 1038ff94bc40SHeiko Schocher c->freeable_cnt = freeable_cnt; 1039ff94bc40SHeiko Schocher spin_unlock(&c->space_lock); 1040ff94bc40SHeiko Schocher 1041ff94bc40SHeiko Schocher if (free != d->saved_free) { 1042*0195a7bbSHeiko Schocher ubifs_err(c, "free space changed from %lld to %lld", 1043ff94bc40SHeiko Schocher d->saved_free, free); 1044ff94bc40SHeiko Schocher goto out; 1045ff94bc40SHeiko Schocher } 1046ff94bc40SHeiko Schocher 1047ff94bc40SHeiko Schocher return 0; 1048ff94bc40SHeiko Schocher 1049ff94bc40SHeiko Schocher out: 1050*0195a7bbSHeiko Schocher ubifs_msg(c, "saved lprops statistics dump"); 1051ff94bc40SHeiko Schocher ubifs_dump_lstats(&d->saved_lst); 1052*0195a7bbSHeiko Schocher ubifs_msg(c, "saved budgeting info dump"); 1053ff94bc40SHeiko Schocher ubifs_dump_budg(c, &d->saved_bi); 1054*0195a7bbSHeiko Schocher ubifs_msg(c, "saved idx_gc_cnt %d", d->saved_idx_gc_cnt); 1055*0195a7bbSHeiko Schocher ubifs_msg(c, "current lprops statistics dump"); 1056ff94bc40SHeiko Schocher ubifs_get_lp_stats(c, &lst); 1057ff94bc40SHeiko Schocher ubifs_dump_lstats(&lst); 1058*0195a7bbSHeiko Schocher ubifs_msg(c, "current budgeting info dump"); 1059ff94bc40SHeiko Schocher ubifs_dump_budg(c, &c->bi); 1060ff94bc40SHeiko Schocher dump_stack(); 1061ff94bc40SHeiko Schocher return -EINVAL; 1062ff94bc40SHeiko Schocher } 1063ff94bc40SHeiko Schocher 1064ff94bc40SHeiko Schocher /** 1065ff94bc40SHeiko Schocher * dbg_check_synced_i_size - check synchronized inode size. 1066ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1067ff94bc40SHeiko Schocher * @inode: inode to check 1068ff94bc40SHeiko Schocher * 1069ff94bc40SHeiko Schocher * If inode is clean, synchronized inode size has to be equivalent to current 1070ff94bc40SHeiko Schocher * inode size. This function has to be called only for locked inodes (@i_mutex 1071ff94bc40SHeiko Schocher * has to be locked). Returns %0 if synchronized inode size if correct, and 1072ff94bc40SHeiko Schocher * %-EINVAL if not. 1073ff94bc40SHeiko Schocher */ 1074ff94bc40SHeiko Schocher int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode) 1075ff94bc40SHeiko Schocher { 1076ff94bc40SHeiko Schocher int err = 0; 1077ff94bc40SHeiko Schocher struct ubifs_inode *ui = ubifs_inode(inode); 1078ff94bc40SHeiko Schocher 1079ff94bc40SHeiko Schocher if (!dbg_is_chk_gen(c)) 1080ff94bc40SHeiko Schocher return 0; 1081ff94bc40SHeiko Schocher if (!S_ISREG(inode->i_mode)) 1082ff94bc40SHeiko Schocher return 0; 1083ff94bc40SHeiko Schocher 1084ff94bc40SHeiko Schocher mutex_lock(&ui->ui_mutex); 1085ff94bc40SHeiko Schocher spin_lock(&ui->ui_lock); 1086ff94bc40SHeiko Schocher if (ui->ui_size != ui->synced_i_size && !ui->dirty) { 1087*0195a7bbSHeiko Schocher ubifs_err(c, "ui_size is %lld, synced_i_size is %lld, but inode is clean", 1088ff94bc40SHeiko Schocher ui->ui_size, ui->synced_i_size); 1089*0195a7bbSHeiko Schocher ubifs_err(c, "i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino, 1090ff94bc40SHeiko Schocher inode->i_mode, i_size_read(inode)); 1091ff94bc40SHeiko Schocher dump_stack(); 1092ff94bc40SHeiko Schocher err = -EINVAL; 1093ff94bc40SHeiko Schocher } 1094ff94bc40SHeiko Schocher spin_unlock(&ui->ui_lock); 1095ff94bc40SHeiko Schocher mutex_unlock(&ui->ui_mutex); 1096ff94bc40SHeiko Schocher return err; 1097ff94bc40SHeiko Schocher } 1098ff94bc40SHeiko Schocher 1099ff94bc40SHeiko Schocher /* 1100ff94bc40SHeiko Schocher * dbg_check_dir - check directory inode size and link count. 1101ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1102ff94bc40SHeiko Schocher * @dir: the directory to calculate size for 1103ff94bc40SHeiko Schocher * @size: the result is returned here 1104ff94bc40SHeiko Schocher * 1105ff94bc40SHeiko Schocher * This function makes sure that directory size and link count are correct. 1106ff94bc40SHeiko Schocher * Returns zero in case of success and a negative error code in case of 1107ff94bc40SHeiko Schocher * failure. 1108ff94bc40SHeiko Schocher * 1109ff94bc40SHeiko Schocher * Note, it is good idea to make sure the @dir->i_mutex is locked before 1110ff94bc40SHeiko Schocher * calling this function. 1111ff94bc40SHeiko Schocher */ 1112ff94bc40SHeiko Schocher int dbg_check_dir(struct ubifs_info *c, const struct inode *dir) 1113ff94bc40SHeiko Schocher { 1114ff94bc40SHeiko Schocher unsigned int nlink = 2; 1115ff94bc40SHeiko Schocher union ubifs_key key; 1116ff94bc40SHeiko Schocher struct ubifs_dent_node *dent, *pdent = NULL; 1117ff94bc40SHeiko Schocher struct qstr nm = { .name = NULL }; 1118ff94bc40SHeiko Schocher loff_t size = UBIFS_INO_NODE_SZ; 1119ff94bc40SHeiko Schocher 1120ff94bc40SHeiko Schocher if (!dbg_is_chk_gen(c)) 1121ff94bc40SHeiko Schocher return 0; 1122ff94bc40SHeiko Schocher 1123ff94bc40SHeiko Schocher if (!S_ISDIR(dir->i_mode)) 1124ff94bc40SHeiko Schocher return 0; 1125ff94bc40SHeiko Schocher 1126ff94bc40SHeiko Schocher lowest_dent_key(c, &key, dir->i_ino); 1127ff94bc40SHeiko Schocher while (1) { 1128ff94bc40SHeiko Schocher int err; 1129ff94bc40SHeiko Schocher 1130ff94bc40SHeiko Schocher dent = ubifs_tnc_next_ent(c, &key, &nm); 1131ff94bc40SHeiko Schocher if (IS_ERR(dent)) { 1132ff94bc40SHeiko Schocher err = PTR_ERR(dent); 1133ff94bc40SHeiko Schocher if (err == -ENOENT) 1134ff94bc40SHeiko Schocher break; 1135ff94bc40SHeiko Schocher return err; 1136ff94bc40SHeiko Schocher } 1137ff94bc40SHeiko Schocher 1138ff94bc40SHeiko Schocher nm.name = dent->name; 1139ff94bc40SHeiko Schocher nm.len = le16_to_cpu(dent->nlen); 1140ff94bc40SHeiko Schocher size += CALC_DENT_SIZE(nm.len); 1141ff94bc40SHeiko Schocher if (dent->type == UBIFS_ITYPE_DIR) 1142ff94bc40SHeiko Schocher nlink += 1; 1143ff94bc40SHeiko Schocher kfree(pdent); 1144ff94bc40SHeiko Schocher pdent = dent; 1145ff94bc40SHeiko Schocher key_read(c, &dent->key, &key); 1146ff94bc40SHeiko Schocher } 1147ff94bc40SHeiko Schocher kfree(pdent); 1148ff94bc40SHeiko Schocher 1149ff94bc40SHeiko Schocher if (i_size_read(dir) != size) { 1150*0195a7bbSHeiko Schocher ubifs_err(c, "directory inode %lu has size %llu, but calculated size is %llu", 1151ff94bc40SHeiko Schocher dir->i_ino, (unsigned long long)i_size_read(dir), 1152ff94bc40SHeiko Schocher (unsigned long long)size); 1153ff94bc40SHeiko Schocher ubifs_dump_inode(c, dir); 1154ff94bc40SHeiko Schocher dump_stack(); 1155ff94bc40SHeiko Schocher return -EINVAL; 1156ff94bc40SHeiko Schocher } 1157ff94bc40SHeiko Schocher if (dir->i_nlink != nlink) { 1158*0195a7bbSHeiko Schocher ubifs_err(c, "directory inode %lu has nlink %u, but calculated nlink is %u", 1159ff94bc40SHeiko Schocher dir->i_ino, dir->i_nlink, nlink); 1160ff94bc40SHeiko Schocher ubifs_dump_inode(c, dir); 1161ff94bc40SHeiko Schocher dump_stack(); 1162ff94bc40SHeiko Schocher return -EINVAL; 1163ff94bc40SHeiko Schocher } 1164ff94bc40SHeiko Schocher 1165ff94bc40SHeiko Schocher return 0; 1166ff94bc40SHeiko Schocher } 1167ff94bc40SHeiko Schocher 1168ff94bc40SHeiko Schocher /** 1169ff94bc40SHeiko Schocher * dbg_check_key_order - make sure that colliding keys are properly ordered. 1170ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1171ff94bc40SHeiko Schocher * @zbr1: first zbranch 1172ff94bc40SHeiko Schocher * @zbr2: following zbranch 1173ff94bc40SHeiko Schocher * 1174ff94bc40SHeiko Schocher * In UBIFS indexing B-tree colliding keys has to be sorted in binary order of 1175ff94bc40SHeiko Schocher * names of the direntries/xentries which are referred by the keys. This 1176ff94bc40SHeiko Schocher * function reads direntries/xentries referred by @zbr1 and @zbr2 and makes 1177ff94bc40SHeiko Schocher * sure the name of direntry/xentry referred by @zbr1 is less than 1178ff94bc40SHeiko Schocher * direntry/xentry referred by @zbr2. Returns zero if this is true, %1 if not, 1179ff94bc40SHeiko Schocher * and a negative error code in case of failure. 1180ff94bc40SHeiko Schocher */ 1181ff94bc40SHeiko Schocher static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, 1182ff94bc40SHeiko Schocher struct ubifs_zbranch *zbr2) 1183ff94bc40SHeiko Schocher { 1184ff94bc40SHeiko Schocher int err, nlen1, nlen2, cmp; 1185ff94bc40SHeiko Schocher struct ubifs_dent_node *dent1, *dent2; 1186ff94bc40SHeiko Schocher union ubifs_key key; 1187ff94bc40SHeiko Schocher char key_buf[DBG_KEY_BUF_LEN]; 1188ff94bc40SHeiko Schocher 1189ff94bc40SHeiko Schocher ubifs_assert(!keys_cmp(c, &zbr1->key, &zbr2->key)); 1190ff94bc40SHeiko Schocher dent1 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); 1191ff94bc40SHeiko Schocher if (!dent1) 1192ff94bc40SHeiko Schocher return -ENOMEM; 1193ff94bc40SHeiko Schocher dent2 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); 1194ff94bc40SHeiko Schocher if (!dent2) { 1195ff94bc40SHeiko Schocher err = -ENOMEM; 1196ff94bc40SHeiko Schocher goto out_free; 1197ff94bc40SHeiko Schocher } 1198ff94bc40SHeiko Schocher 1199ff94bc40SHeiko Schocher err = ubifs_tnc_read_node(c, zbr1, dent1); 1200ff94bc40SHeiko Schocher if (err) 1201ff94bc40SHeiko Schocher goto out_free; 1202ff94bc40SHeiko Schocher err = ubifs_validate_entry(c, dent1); 1203ff94bc40SHeiko Schocher if (err) 1204ff94bc40SHeiko Schocher goto out_free; 1205ff94bc40SHeiko Schocher 1206ff94bc40SHeiko Schocher err = ubifs_tnc_read_node(c, zbr2, dent2); 1207ff94bc40SHeiko Schocher if (err) 1208ff94bc40SHeiko Schocher goto out_free; 1209ff94bc40SHeiko Schocher err = ubifs_validate_entry(c, dent2); 1210ff94bc40SHeiko Schocher if (err) 1211ff94bc40SHeiko Schocher goto out_free; 1212ff94bc40SHeiko Schocher 1213ff94bc40SHeiko Schocher /* Make sure node keys are the same as in zbranch */ 1214ff94bc40SHeiko Schocher err = 1; 1215ff94bc40SHeiko Schocher key_read(c, &dent1->key, &key); 1216ff94bc40SHeiko Schocher if (keys_cmp(c, &zbr1->key, &key)) { 1217*0195a7bbSHeiko Schocher ubifs_err(c, "1st entry at %d:%d has key %s", zbr1->lnum, 1218ff94bc40SHeiko Schocher zbr1->offs, dbg_snprintf_key(c, &key, key_buf, 1219ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 1220*0195a7bbSHeiko Schocher ubifs_err(c, "but it should have key %s according to tnc", 1221ff94bc40SHeiko Schocher dbg_snprintf_key(c, &zbr1->key, key_buf, 1222ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 1223ff94bc40SHeiko Schocher ubifs_dump_node(c, dent1); 1224ff94bc40SHeiko Schocher goto out_free; 1225ff94bc40SHeiko Schocher } 1226ff94bc40SHeiko Schocher 1227ff94bc40SHeiko Schocher key_read(c, &dent2->key, &key); 1228ff94bc40SHeiko Schocher if (keys_cmp(c, &zbr2->key, &key)) { 1229*0195a7bbSHeiko Schocher ubifs_err(c, "2nd entry at %d:%d has key %s", zbr1->lnum, 1230ff94bc40SHeiko Schocher zbr1->offs, dbg_snprintf_key(c, &key, key_buf, 1231ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 1232*0195a7bbSHeiko Schocher ubifs_err(c, "but it should have key %s according to tnc", 1233ff94bc40SHeiko Schocher dbg_snprintf_key(c, &zbr2->key, key_buf, 1234ff94bc40SHeiko Schocher DBG_KEY_BUF_LEN)); 1235ff94bc40SHeiko Schocher ubifs_dump_node(c, dent2); 1236ff94bc40SHeiko Schocher goto out_free; 1237ff94bc40SHeiko Schocher } 1238ff94bc40SHeiko Schocher 1239ff94bc40SHeiko Schocher nlen1 = le16_to_cpu(dent1->nlen); 1240ff94bc40SHeiko Schocher nlen2 = le16_to_cpu(dent2->nlen); 1241ff94bc40SHeiko Schocher 1242ff94bc40SHeiko Schocher cmp = memcmp(dent1->name, dent2->name, min_t(int, nlen1, nlen2)); 1243ff94bc40SHeiko Schocher if (cmp < 0 || (cmp == 0 && nlen1 < nlen2)) { 1244ff94bc40SHeiko Schocher err = 0; 1245ff94bc40SHeiko Schocher goto out_free; 1246ff94bc40SHeiko Schocher } 1247ff94bc40SHeiko Schocher if (cmp == 0 && nlen1 == nlen2) 1248*0195a7bbSHeiko Schocher ubifs_err(c, "2 xent/dent nodes with the same name"); 1249ff94bc40SHeiko Schocher else 1250*0195a7bbSHeiko Schocher ubifs_err(c, "bad order of colliding key %s", 1251ff94bc40SHeiko Schocher dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); 1252ff94bc40SHeiko Schocher 1253*0195a7bbSHeiko Schocher ubifs_msg(c, "first node at %d:%d\n", zbr1->lnum, zbr1->offs); 1254ff94bc40SHeiko Schocher ubifs_dump_node(c, dent1); 1255*0195a7bbSHeiko Schocher ubifs_msg(c, "second node at %d:%d\n", zbr2->lnum, zbr2->offs); 1256ff94bc40SHeiko Schocher ubifs_dump_node(c, dent2); 1257ff94bc40SHeiko Schocher 1258ff94bc40SHeiko Schocher out_free: 1259ff94bc40SHeiko Schocher kfree(dent2); 1260ff94bc40SHeiko Schocher kfree(dent1); 1261ff94bc40SHeiko Schocher return err; 1262ff94bc40SHeiko Schocher } 1263ff94bc40SHeiko Schocher 1264ff94bc40SHeiko Schocher /** 1265ff94bc40SHeiko Schocher * dbg_check_znode - check if znode is all right. 1266ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1267ff94bc40SHeiko Schocher * @zbr: zbranch which points to this znode 1268ff94bc40SHeiko Schocher * 1269ff94bc40SHeiko Schocher * This function makes sure that znode referred to by @zbr is all right. 1270ff94bc40SHeiko Schocher * Returns zero if it is, and %-EINVAL if it is not. 1271ff94bc40SHeiko Schocher */ 1272ff94bc40SHeiko Schocher static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr) 1273ff94bc40SHeiko Schocher { 1274ff94bc40SHeiko Schocher struct ubifs_znode *znode = zbr->znode; 1275ff94bc40SHeiko Schocher struct ubifs_znode *zp = znode->parent; 1276ff94bc40SHeiko Schocher int n, err, cmp; 1277ff94bc40SHeiko Schocher 1278ff94bc40SHeiko Schocher if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) { 1279ff94bc40SHeiko Schocher err = 1; 1280ff94bc40SHeiko Schocher goto out; 1281ff94bc40SHeiko Schocher } 1282ff94bc40SHeiko Schocher if (znode->level < 0) { 1283ff94bc40SHeiko Schocher err = 2; 1284ff94bc40SHeiko Schocher goto out; 1285ff94bc40SHeiko Schocher } 1286ff94bc40SHeiko Schocher if (znode->iip < 0 || znode->iip >= c->fanout) { 1287ff94bc40SHeiko Schocher err = 3; 1288ff94bc40SHeiko Schocher goto out; 1289ff94bc40SHeiko Schocher } 1290ff94bc40SHeiko Schocher 1291ff94bc40SHeiko Schocher if (zbr->len == 0) 1292ff94bc40SHeiko Schocher /* Only dirty zbranch may have no on-flash nodes */ 1293ff94bc40SHeiko Schocher if (!ubifs_zn_dirty(znode)) { 1294ff94bc40SHeiko Schocher err = 4; 1295ff94bc40SHeiko Schocher goto out; 1296ff94bc40SHeiko Schocher } 1297ff94bc40SHeiko Schocher 1298ff94bc40SHeiko Schocher if (ubifs_zn_dirty(znode)) { 1299ff94bc40SHeiko Schocher /* 1300ff94bc40SHeiko Schocher * If znode is dirty, its parent has to be dirty as well. The 1301ff94bc40SHeiko Schocher * order of the operation is important, so we have to have 1302ff94bc40SHeiko Schocher * memory barriers. 1303ff94bc40SHeiko Schocher */ 1304ff94bc40SHeiko Schocher smp_mb(); 1305ff94bc40SHeiko Schocher if (zp && !ubifs_zn_dirty(zp)) { 1306ff94bc40SHeiko Schocher /* 1307ff94bc40SHeiko Schocher * The dirty flag is atomic and is cleared outside the 1308ff94bc40SHeiko Schocher * TNC mutex, so znode's dirty flag may now have 1309ff94bc40SHeiko Schocher * been cleared. The child is always cleared before the 1310ff94bc40SHeiko Schocher * parent, so we just need to check again. 1311ff94bc40SHeiko Schocher */ 1312ff94bc40SHeiko Schocher smp_mb(); 1313ff94bc40SHeiko Schocher if (ubifs_zn_dirty(znode)) { 1314ff94bc40SHeiko Schocher err = 5; 1315ff94bc40SHeiko Schocher goto out; 1316ff94bc40SHeiko Schocher } 1317ff94bc40SHeiko Schocher } 1318ff94bc40SHeiko Schocher } 1319ff94bc40SHeiko Schocher 1320ff94bc40SHeiko Schocher if (zp) { 1321ff94bc40SHeiko Schocher const union ubifs_key *min, *max; 1322ff94bc40SHeiko Schocher 1323ff94bc40SHeiko Schocher if (znode->level != zp->level - 1) { 1324ff94bc40SHeiko Schocher err = 6; 1325ff94bc40SHeiko Schocher goto out; 1326ff94bc40SHeiko Schocher } 1327ff94bc40SHeiko Schocher 1328ff94bc40SHeiko Schocher /* Make sure the 'parent' pointer in our znode is correct */ 1329ff94bc40SHeiko Schocher err = ubifs_search_zbranch(c, zp, &zbr->key, &n); 1330ff94bc40SHeiko Schocher if (!err) { 1331ff94bc40SHeiko Schocher /* This zbranch does not exist in the parent */ 1332ff94bc40SHeiko Schocher err = 7; 1333ff94bc40SHeiko Schocher goto out; 1334ff94bc40SHeiko Schocher } 1335ff94bc40SHeiko Schocher 1336ff94bc40SHeiko Schocher if (znode->iip >= zp->child_cnt) { 1337ff94bc40SHeiko Schocher err = 8; 1338ff94bc40SHeiko Schocher goto out; 1339ff94bc40SHeiko Schocher } 1340ff94bc40SHeiko Schocher 1341ff94bc40SHeiko Schocher if (znode->iip != n) { 1342ff94bc40SHeiko Schocher /* This may happen only in case of collisions */ 1343ff94bc40SHeiko Schocher if (keys_cmp(c, &zp->zbranch[n].key, 1344ff94bc40SHeiko Schocher &zp->zbranch[znode->iip].key)) { 1345ff94bc40SHeiko Schocher err = 9; 1346ff94bc40SHeiko Schocher goto out; 1347ff94bc40SHeiko Schocher } 1348ff94bc40SHeiko Schocher n = znode->iip; 1349ff94bc40SHeiko Schocher } 1350ff94bc40SHeiko Schocher 1351ff94bc40SHeiko Schocher /* 1352ff94bc40SHeiko Schocher * Make sure that the first key in our znode is greater than or 1353ff94bc40SHeiko Schocher * equal to the key in the pointing zbranch. 1354ff94bc40SHeiko Schocher */ 1355ff94bc40SHeiko Schocher min = &zbr->key; 1356ff94bc40SHeiko Schocher cmp = keys_cmp(c, min, &znode->zbranch[0].key); 1357ff94bc40SHeiko Schocher if (cmp == 1) { 1358ff94bc40SHeiko Schocher err = 10; 1359ff94bc40SHeiko Schocher goto out; 1360ff94bc40SHeiko Schocher } 1361ff94bc40SHeiko Schocher 1362ff94bc40SHeiko Schocher if (n + 1 < zp->child_cnt) { 1363ff94bc40SHeiko Schocher max = &zp->zbranch[n + 1].key; 1364ff94bc40SHeiko Schocher 1365ff94bc40SHeiko Schocher /* 1366ff94bc40SHeiko Schocher * Make sure the last key in our znode is less or 1367ff94bc40SHeiko Schocher * equivalent than the key in the zbranch which goes 1368ff94bc40SHeiko Schocher * after our pointing zbranch. 1369ff94bc40SHeiko Schocher */ 1370ff94bc40SHeiko Schocher cmp = keys_cmp(c, max, 1371ff94bc40SHeiko Schocher &znode->zbranch[znode->child_cnt - 1].key); 1372ff94bc40SHeiko Schocher if (cmp == -1) { 1373ff94bc40SHeiko Schocher err = 11; 1374ff94bc40SHeiko Schocher goto out; 1375ff94bc40SHeiko Schocher } 1376ff94bc40SHeiko Schocher } 1377ff94bc40SHeiko Schocher } else { 1378ff94bc40SHeiko Schocher /* This may only be root znode */ 1379ff94bc40SHeiko Schocher if (zbr != &c->zroot) { 1380ff94bc40SHeiko Schocher err = 12; 1381ff94bc40SHeiko Schocher goto out; 1382ff94bc40SHeiko Schocher } 1383ff94bc40SHeiko Schocher } 1384ff94bc40SHeiko Schocher 1385ff94bc40SHeiko Schocher /* 1386ff94bc40SHeiko Schocher * Make sure that next key is greater or equivalent then the previous 1387ff94bc40SHeiko Schocher * one. 1388ff94bc40SHeiko Schocher */ 1389ff94bc40SHeiko Schocher for (n = 1; n < znode->child_cnt; n++) { 1390ff94bc40SHeiko Schocher cmp = keys_cmp(c, &znode->zbranch[n - 1].key, 1391ff94bc40SHeiko Schocher &znode->zbranch[n].key); 1392ff94bc40SHeiko Schocher if (cmp > 0) { 1393ff94bc40SHeiko Schocher err = 13; 1394ff94bc40SHeiko Schocher goto out; 1395ff94bc40SHeiko Schocher } 1396ff94bc40SHeiko Schocher if (cmp == 0) { 1397ff94bc40SHeiko Schocher /* This can only be keys with colliding hash */ 1398ff94bc40SHeiko Schocher if (!is_hash_key(c, &znode->zbranch[n].key)) { 1399ff94bc40SHeiko Schocher err = 14; 1400ff94bc40SHeiko Schocher goto out; 1401ff94bc40SHeiko Schocher } 1402ff94bc40SHeiko Schocher 1403ff94bc40SHeiko Schocher if (znode->level != 0 || c->replaying) 1404ff94bc40SHeiko Schocher continue; 1405ff94bc40SHeiko Schocher 1406ff94bc40SHeiko Schocher /* 1407ff94bc40SHeiko Schocher * Colliding keys should follow binary order of 1408ff94bc40SHeiko Schocher * corresponding xentry/dentry names. 1409ff94bc40SHeiko Schocher */ 1410ff94bc40SHeiko Schocher err = dbg_check_key_order(c, &znode->zbranch[n - 1], 1411ff94bc40SHeiko Schocher &znode->zbranch[n]); 1412ff94bc40SHeiko Schocher if (err < 0) 1413ff94bc40SHeiko Schocher return err; 1414ff94bc40SHeiko Schocher if (err) { 1415ff94bc40SHeiko Schocher err = 15; 1416ff94bc40SHeiko Schocher goto out; 1417ff94bc40SHeiko Schocher } 1418ff94bc40SHeiko Schocher } 1419ff94bc40SHeiko Schocher } 1420ff94bc40SHeiko Schocher 1421ff94bc40SHeiko Schocher for (n = 0; n < znode->child_cnt; n++) { 1422ff94bc40SHeiko Schocher if (!znode->zbranch[n].znode && 1423ff94bc40SHeiko Schocher (znode->zbranch[n].lnum == 0 || 1424ff94bc40SHeiko Schocher znode->zbranch[n].len == 0)) { 1425ff94bc40SHeiko Schocher err = 16; 1426ff94bc40SHeiko Schocher goto out; 1427ff94bc40SHeiko Schocher } 1428ff94bc40SHeiko Schocher 1429ff94bc40SHeiko Schocher if (znode->zbranch[n].lnum != 0 && 1430ff94bc40SHeiko Schocher znode->zbranch[n].len == 0) { 1431ff94bc40SHeiko Schocher err = 17; 1432ff94bc40SHeiko Schocher goto out; 1433ff94bc40SHeiko Schocher } 1434ff94bc40SHeiko Schocher 1435ff94bc40SHeiko Schocher if (znode->zbranch[n].lnum == 0 && 1436ff94bc40SHeiko Schocher znode->zbranch[n].len != 0) { 1437ff94bc40SHeiko Schocher err = 18; 1438ff94bc40SHeiko Schocher goto out; 1439ff94bc40SHeiko Schocher } 1440ff94bc40SHeiko Schocher 1441ff94bc40SHeiko Schocher if (znode->zbranch[n].lnum == 0 && 1442ff94bc40SHeiko Schocher znode->zbranch[n].offs != 0) { 1443ff94bc40SHeiko Schocher err = 19; 1444ff94bc40SHeiko Schocher goto out; 1445ff94bc40SHeiko Schocher } 1446ff94bc40SHeiko Schocher 1447ff94bc40SHeiko Schocher if (znode->level != 0 && znode->zbranch[n].znode) 1448ff94bc40SHeiko Schocher if (znode->zbranch[n].znode->parent != znode) { 1449ff94bc40SHeiko Schocher err = 20; 1450ff94bc40SHeiko Schocher goto out; 1451ff94bc40SHeiko Schocher } 1452ff94bc40SHeiko Schocher } 1453ff94bc40SHeiko Schocher 1454ff94bc40SHeiko Schocher return 0; 1455ff94bc40SHeiko Schocher 1456ff94bc40SHeiko Schocher out: 1457*0195a7bbSHeiko Schocher ubifs_err(c, "failed, error %d", err); 1458*0195a7bbSHeiko Schocher ubifs_msg(c, "dump of the znode"); 1459ff94bc40SHeiko Schocher ubifs_dump_znode(c, znode); 1460ff94bc40SHeiko Schocher if (zp) { 1461*0195a7bbSHeiko Schocher ubifs_msg(c, "dump of the parent znode"); 1462ff94bc40SHeiko Schocher ubifs_dump_znode(c, zp); 1463ff94bc40SHeiko Schocher } 1464ff94bc40SHeiko Schocher dump_stack(); 1465ff94bc40SHeiko Schocher return -EINVAL; 1466ff94bc40SHeiko Schocher } 1467ff94bc40SHeiko Schocher #else 1468ff94bc40SHeiko Schocher 1469ff94bc40SHeiko Schocher int dbg_check_dir(struct ubifs_info *c, const struct inode *dir) 1470ff94bc40SHeiko Schocher { 1471ff94bc40SHeiko Schocher return 0; 1472ff94bc40SHeiko Schocher } 1473ff94bc40SHeiko Schocher 1474ff94bc40SHeiko Schocher void dbg_debugfs_exit_fs(struct ubifs_info *c) 1475ff94bc40SHeiko Schocher { 1476ff94bc40SHeiko Schocher return; 1477ff94bc40SHeiko Schocher } 1478ff94bc40SHeiko Schocher 1479ff94bc40SHeiko Schocher int ubifs_debugging_init(struct ubifs_info *c) 1480ff94bc40SHeiko Schocher { 1481ff94bc40SHeiko Schocher return 0; 1482ff94bc40SHeiko Schocher } 1483ff94bc40SHeiko Schocher void ubifs_debugging_exit(struct ubifs_info *c) 1484ff94bc40SHeiko Schocher { 1485ff94bc40SHeiko Schocher } 1486ff94bc40SHeiko Schocher int dbg_check_filesystem(struct ubifs_info *c) 1487ff94bc40SHeiko Schocher { 1488ff94bc40SHeiko Schocher return 0; 1489ff94bc40SHeiko Schocher } 1490ff94bc40SHeiko Schocher int dbg_debugfs_init_fs(struct ubifs_info *c) 1491ff94bc40SHeiko Schocher { 1492ff94bc40SHeiko Schocher return 0; 1493ff94bc40SHeiko Schocher } 1494ff94bc40SHeiko Schocher #endif 1495ff94bc40SHeiko Schocher 1496ff94bc40SHeiko Schocher #ifndef __UBOOT__ 1497ff94bc40SHeiko Schocher /** 1498ff94bc40SHeiko Schocher * dbg_check_tnc - check TNC tree. 1499ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1500ff94bc40SHeiko Schocher * @extra: do extra checks that are possible at start commit 1501ff94bc40SHeiko Schocher * 1502ff94bc40SHeiko Schocher * This function traverses whole TNC tree and checks every znode. Returns zero 1503ff94bc40SHeiko Schocher * if everything is all right and %-EINVAL if something is wrong with TNC. 1504ff94bc40SHeiko Schocher */ 1505ff94bc40SHeiko Schocher int dbg_check_tnc(struct ubifs_info *c, int extra) 1506ff94bc40SHeiko Schocher { 1507ff94bc40SHeiko Schocher struct ubifs_znode *znode; 1508ff94bc40SHeiko Schocher long clean_cnt = 0, dirty_cnt = 0; 1509ff94bc40SHeiko Schocher int err, last; 1510ff94bc40SHeiko Schocher 1511ff94bc40SHeiko Schocher if (!dbg_is_chk_index(c)) 1512ff94bc40SHeiko Schocher return 0; 1513ff94bc40SHeiko Schocher 1514ff94bc40SHeiko Schocher ubifs_assert(mutex_is_locked(&c->tnc_mutex)); 1515ff94bc40SHeiko Schocher if (!c->zroot.znode) 1516ff94bc40SHeiko Schocher return 0; 1517ff94bc40SHeiko Schocher 1518ff94bc40SHeiko Schocher znode = ubifs_tnc_postorder_first(c->zroot.znode); 1519ff94bc40SHeiko Schocher while (1) { 1520ff94bc40SHeiko Schocher struct ubifs_znode *prev; 1521ff94bc40SHeiko Schocher struct ubifs_zbranch *zbr; 1522ff94bc40SHeiko Schocher 1523ff94bc40SHeiko Schocher if (!znode->parent) 1524ff94bc40SHeiko Schocher zbr = &c->zroot; 1525ff94bc40SHeiko Schocher else 1526ff94bc40SHeiko Schocher zbr = &znode->parent->zbranch[znode->iip]; 1527ff94bc40SHeiko Schocher 1528ff94bc40SHeiko Schocher err = dbg_check_znode(c, zbr); 1529ff94bc40SHeiko Schocher if (err) 1530ff94bc40SHeiko Schocher return err; 1531ff94bc40SHeiko Schocher 1532ff94bc40SHeiko Schocher if (extra) { 1533ff94bc40SHeiko Schocher if (ubifs_zn_dirty(znode)) 1534ff94bc40SHeiko Schocher dirty_cnt += 1; 1535ff94bc40SHeiko Schocher else 1536ff94bc40SHeiko Schocher clean_cnt += 1; 1537ff94bc40SHeiko Schocher } 1538ff94bc40SHeiko Schocher 1539ff94bc40SHeiko Schocher prev = znode; 1540ff94bc40SHeiko Schocher znode = ubifs_tnc_postorder_next(znode); 1541ff94bc40SHeiko Schocher if (!znode) 1542ff94bc40SHeiko Schocher break; 1543ff94bc40SHeiko Schocher 1544ff94bc40SHeiko Schocher /* 1545ff94bc40SHeiko Schocher * If the last key of this znode is equivalent to the first key 1546ff94bc40SHeiko Schocher * of the next znode (collision), then check order of the keys. 1547ff94bc40SHeiko Schocher */ 1548ff94bc40SHeiko Schocher last = prev->child_cnt - 1; 1549ff94bc40SHeiko Schocher if (prev->level == 0 && znode->level == 0 && !c->replaying && 1550ff94bc40SHeiko Schocher !keys_cmp(c, &prev->zbranch[last].key, 1551ff94bc40SHeiko Schocher &znode->zbranch[0].key)) { 1552ff94bc40SHeiko Schocher err = dbg_check_key_order(c, &prev->zbranch[last], 1553ff94bc40SHeiko Schocher &znode->zbranch[0]); 1554ff94bc40SHeiko Schocher if (err < 0) 1555ff94bc40SHeiko Schocher return err; 1556ff94bc40SHeiko Schocher if (err) { 1557*0195a7bbSHeiko Schocher ubifs_msg(c, "first znode"); 1558ff94bc40SHeiko Schocher ubifs_dump_znode(c, prev); 1559*0195a7bbSHeiko Schocher ubifs_msg(c, "second znode"); 1560ff94bc40SHeiko Schocher ubifs_dump_znode(c, znode); 1561ff94bc40SHeiko Schocher return -EINVAL; 1562ff94bc40SHeiko Schocher } 1563ff94bc40SHeiko Schocher } 1564ff94bc40SHeiko Schocher } 1565ff94bc40SHeiko Schocher 1566ff94bc40SHeiko Schocher if (extra) { 1567ff94bc40SHeiko Schocher if (clean_cnt != atomic_long_read(&c->clean_zn_cnt)) { 1568*0195a7bbSHeiko Schocher ubifs_err(c, "incorrect clean_zn_cnt %ld, calculated %ld", 1569ff94bc40SHeiko Schocher atomic_long_read(&c->clean_zn_cnt), 1570ff94bc40SHeiko Schocher clean_cnt); 1571ff94bc40SHeiko Schocher return -EINVAL; 1572ff94bc40SHeiko Schocher } 1573ff94bc40SHeiko Schocher if (dirty_cnt != atomic_long_read(&c->dirty_zn_cnt)) { 1574*0195a7bbSHeiko Schocher ubifs_err(c, "incorrect dirty_zn_cnt %ld, calculated %ld", 1575ff94bc40SHeiko Schocher atomic_long_read(&c->dirty_zn_cnt), 1576ff94bc40SHeiko Schocher dirty_cnt); 1577ff94bc40SHeiko Schocher return -EINVAL; 1578ff94bc40SHeiko Schocher } 1579ff94bc40SHeiko Schocher } 1580ff94bc40SHeiko Schocher 1581ff94bc40SHeiko Schocher return 0; 1582ff94bc40SHeiko Schocher } 1583ff94bc40SHeiko Schocher #else 1584ff94bc40SHeiko Schocher int dbg_check_tnc(struct ubifs_info *c, int extra) 1585ff94bc40SHeiko Schocher { 1586ff94bc40SHeiko Schocher return 0; 1587ff94bc40SHeiko Schocher } 1588ff94bc40SHeiko Schocher #endif 1589ff94bc40SHeiko Schocher 1590ff94bc40SHeiko Schocher /** 1591ff94bc40SHeiko Schocher * dbg_walk_index - walk the on-flash index. 1592ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1593ff94bc40SHeiko Schocher * @leaf_cb: called for each leaf node 1594ff94bc40SHeiko Schocher * @znode_cb: called for each indexing node 1595ff94bc40SHeiko Schocher * @priv: private data which is passed to callbacks 1596ff94bc40SHeiko Schocher * 1597ff94bc40SHeiko Schocher * This function walks the UBIFS index and calls the @leaf_cb for each leaf 1598ff94bc40SHeiko Schocher * node and @znode_cb for each indexing node. Returns zero in case of success 1599ff94bc40SHeiko Schocher * and a negative error code in case of failure. 1600ff94bc40SHeiko Schocher * 1601ff94bc40SHeiko Schocher * It would be better if this function removed every znode it pulled to into 1602ff94bc40SHeiko Schocher * the TNC, so that the behavior more closely matched the non-debugging 1603ff94bc40SHeiko Schocher * behavior. 1604ff94bc40SHeiko Schocher */ 1605ff94bc40SHeiko Schocher int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, 1606ff94bc40SHeiko Schocher dbg_znode_callback znode_cb, void *priv) 1607ff94bc40SHeiko Schocher { 1608ff94bc40SHeiko Schocher int err; 1609ff94bc40SHeiko Schocher struct ubifs_zbranch *zbr; 1610ff94bc40SHeiko Schocher struct ubifs_znode *znode, *child; 1611ff94bc40SHeiko Schocher 1612ff94bc40SHeiko Schocher mutex_lock(&c->tnc_mutex); 1613ff94bc40SHeiko Schocher /* If the root indexing node is not in TNC - pull it */ 1614ff94bc40SHeiko Schocher if (!c->zroot.znode) { 1615ff94bc40SHeiko Schocher c->zroot.znode = ubifs_load_znode(c, &c->zroot, NULL, 0); 1616ff94bc40SHeiko Schocher if (IS_ERR(c->zroot.znode)) { 1617ff94bc40SHeiko Schocher err = PTR_ERR(c->zroot.znode); 1618ff94bc40SHeiko Schocher c->zroot.znode = NULL; 1619ff94bc40SHeiko Schocher goto out_unlock; 1620ff94bc40SHeiko Schocher } 1621ff94bc40SHeiko Schocher } 1622ff94bc40SHeiko Schocher 1623ff94bc40SHeiko Schocher /* 1624ff94bc40SHeiko Schocher * We are going to traverse the indexing tree in the postorder manner. 1625ff94bc40SHeiko Schocher * Go down and find the leftmost indexing node where we are going to 1626ff94bc40SHeiko Schocher * start from. 1627ff94bc40SHeiko Schocher */ 1628ff94bc40SHeiko Schocher znode = c->zroot.znode; 1629ff94bc40SHeiko Schocher while (znode->level > 0) { 1630ff94bc40SHeiko Schocher zbr = &znode->zbranch[0]; 1631ff94bc40SHeiko Schocher child = zbr->znode; 1632ff94bc40SHeiko Schocher if (!child) { 1633ff94bc40SHeiko Schocher child = ubifs_load_znode(c, zbr, znode, 0); 1634ff94bc40SHeiko Schocher if (IS_ERR(child)) { 1635ff94bc40SHeiko Schocher err = PTR_ERR(child); 1636ff94bc40SHeiko Schocher goto out_unlock; 1637ff94bc40SHeiko Schocher } 1638ff94bc40SHeiko Schocher zbr->znode = child; 1639ff94bc40SHeiko Schocher } 1640ff94bc40SHeiko Schocher 1641ff94bc40SHeiko Schocher znode = child; 1642ff94bc40SHeiko Schocher } 1643ff94bc40SHeiko Schocher 1644ff94bc40SHeiko Schocher /* Iterate over all indexing nodes */ 1645ff94bc40SHeiko Schocher while (1) { 1646ff94bc40SHeiko Schocher int idx; 1647ff94bc40SHeiko Schocher 1648ff94bc40SHeiko Schocher cond_resched(); 1649ff94bc40SHeiko Schocher 1650ff94bc40SHeiko Schocher if (znode_cb) { 1651ff94bc40SHeiko Schocher err = znode_cb(c, znode, priv); 1652ff94bc40SHeiko Schocher if (err) { 1653*0195a7bbSHeiko Schocher ubifs_err(c, "znode checking function returned error %d", 1654ff94bc40SHeiko Schocher err); 1655ff94bc40SHeiko Schocher ubifs_dump_znode(c, znode); 1656ff94bc40SHeiko Schocher goto out_dump; 1657ff94bc40SHeiko Schocher } 1658ff94bc40SHeiko Schocher } 1659ff94bc40SHeiko Schocher if (leaf_cb && znode->level == 0) { 1660ff94bc40SHeiko Schocher for (idx = 0; idx < znode->child_cnt; idx++) { 1661ff94bc40SHeiko Schocher zbr = &znode->zbranch[idx]; 1662ff94bc40SHeiko Schocher err = leaf_cb(c, zbr, priv); 1663ff94bc40SHeiko Schocher if (err) { 1664*0195a7bbSHeiko Schocher ubifs_err(c, "leaf checking function returned error %d, for leaf at LEB %d:%d", 1665ff94bc40SHeiko Schocher err, zbr->lnum, zbr->offs); 1666ff94bc40SHeiko Schocher goto out_dump; 1667ff94bc40SHeiko Schocher } 1668ff94bc40SHeiko Schocher } 1669ff94bc40SHeiko Schocher } 1670ff94bc40SHeiko Schocher 1671ff94bc40SHeiko Schocher if (!znode->parent) 1672ff94bc40SHeiko Schocher break; 1673ff94bc40SHeiko Schocher 1674ff94bc40SHeiko Schocher idx = znode->iip + 1; 1675ff94bc40SHeiko Schocher znode = znode->parent; 1676ff94bc40SHeiko Schocher if (idx < znode->child_cnt) { 1677ff94bc40SHeiko Schocher /* Switch to the next index in the parent */ 1678ff94bc40SHeiko Schocher zbr = &znode->zbranch[idx]; 1679ff94bc40SHeiko Schocher child = zbr->znode; 1680ff94bc40SHeiko Schocher if (!child) { 1681ff94bc40SHeiko Schocher child = ubifs_load_znode(c, zbr, znode, idx); 1682ff94bc40SHeiko Schocher if (IS_ERR(child)) { 1683ff94bc40SHeiko Schocher err = PTR_ERR(child); 1684ff94bc40SHeiko Schocher goto out_unlock; 1685ff94bc40SHeiko Schocher } 1686ff94bc40SHeiko Schocher zbr->znode = child; 1687ff94bc40SHeiko Schocher } 1688ff94bc40SHeiko Schocher znode = child; 1689ff94bc40SHeiko Schocher } else 1690ff94bc40SHeiko Schocher /* 1691ff94bc40SHeiko Schocher * This is the last child, switch to the parent and 1692ff94bc40SHeiko Schocher * continue. 1693ff94bc40SHeiko Schocher */ 1694ff94bc40SHeiko Schocher continue; 1695ff94bc40SHeiko Schocher 1696ff94bc40SHeiko Schocher /* Go to the lowest leftmost znode in the new sub-tree */ 1697ff94bc40SHeiko Schocher while (znode->level > 0) { 1698ff94bc40SHeiko Schocher zbr = &znode->zbranch[0]; 1699ff94bc40SHeiko Schocher child = zbr->znode; 1700ff94bc40SHeiko Schocher if (!child) { 1701ff94bc40SHeiko Schocher child = ubifs_load_znode(c, zbr, znode, 0); 1702ff94bc40SHeiko Schocher if (IS_ERR(child)) { 1703ff94bc40SHeiko Schocher err = PTR_ERR(child); 1704ff94bc40SHeiko Schocher goto out_unlock; 1705ff94bc40SHeiko Schocher } 1706ff94bc40SHeiko Schocher zbr->znode = child; 1707ff94bc40SHeiko Schocher } 1708ff94bc40SHeiko Schocher znode = child; 1709ff94bc40SHeiko Schocher } 1710ff94bc40SHeiko Schocher } 1711ff94bc40SHeiko Schocher 1712ff94bc40SHeiko Schocher mutex_unlock(&c->tnc_mutex); 1713ff94bc40SHeiko Schocher return 0; 1714ff94bc40SHeiko Schocher 1715ff94bc40SHeiko Schocher out_dump: 1716ff94bc40SHeiko Schocher if (znode->parent) 1717ff94bc40SHeiko Schocher zbr = &znode->parent->zbranch[znode->iip]; 1718ff94bc40SHeiko Schocher else 1719ff94bc40SHeiko Schocher zbr = &c->zroot; 1720*0195a7bbSHeiko Schocher ubifs_msg(c, "dump of znode at LEB %d:%d", zbr->lnum, zbr->offs); 1721ff94bc40SHeiko Schocher ubifs_dump_znode(c, znode); 1722ff94bc40SHeiko Schocher out_unlock: 1723ff94bc40SHeiko Schocher mutex_unlock(&c->tnc_mutex); 1724ff94bc40SHeiko Schocher return err; 1725ff94bc40SHeiko Schocher } 1726ff94bc40SHeiko Schocher 1727ff94bc40SHeiko Schocher /** 1728ff94bc40SHeiko Schocher * add_size - add znode size to partially calculated index size. 1729ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1730ff94bc40SHeiko Schocher * @znode: znode to add size for 1731ff94bc40SHeiko Schocher * @priv: partially calculated index size 1732ff94bc40SHeiko Schocher * 1733ff94bc40SHeiko Schocher * This is a helper function for 'dbg_check_idx_size()' which is called for 1734ff94bc40SHeiko Schocher * every indexing node and adds its size to the 'long long' variable pointed to 1735ff94bc40SHeiko Schocher * by @priv. 1736ff94bc40SHeiko Schocher */ 1737ff94bc40SHeiko Schocher static int add_size(struct ubifs_info *c, struct ubifs_znode *znode, void *priv) 1738ff94bc40SHeiko Schocher { 1739ff94bc40SHeiko Schocher long long *idx_size = priv; 1740ff94bc40SHeiko Schocher int add; 1741ff94bc40SHeiko Schocher 1742ff94bc40SHeiko Schocher add = ubifs_idx_node_sz(c, znode->child_cnt); 1743ff94bc40SHeiko Schocher add = ALIGN(add, 8); 1744ff94bc40SHeiko Schocher *idx_size += add; 1745ff94bc40SHeiko Schocher return 0; 1746ff94bc40SHeiko Schocher } 1747ff94bc40SHeiko Schocher 1748ff94bc40SHeiko Schocher /** 1749ff94bc40SHeiko Schocher * dbg_check_idx_size - check index size. 1750ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1751ff94bc40SHeiko Schocher * @idx_size: size to check 1752ff94bc40SHeiko Schocher * 1753ff94bc40SHeiko Schocher * This function walks the UBIFS index, calculates its size and checks that the 1754ff94bc40SHeiko Schocher * size is equivalent to @idx_size. Returns zero in case of success and a 1755ff94bc40SHeiko Schocher * negative error code in case of failure. 1756ff94bc40SHeiko Schocher */ 1757ff94bc40SHeiko Schocher int dbg_check_idx_size(struct ubifs_info *c, long long idx_size) 1758ff94bc40SHeiko Schocher { 1759ff94bc40SHeiko Schocher int err; 1760ff94bc40SHeiko Schocher long long calc = 0; 1761ff94bc40SHeiko Schocher 1762ff94bc40SHeiko Schocher if (!dbg_is_chk_index(c)) 1763ff94bc40SHeiko Schocher return 0; 1764ff94bc40SHeiko Schocher 1765ff94bc40SHeiko Schocher err = dbg_walk_index(c, NULL, add_size, &calc); 1766ff94bc40SHeiko Schocher if (err) { 1767*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while walking the index", err); 1768ff94bc40SHeiko Schocher return err; 1769ff94bc40SHeiko Schocher } 1770ff94bc40SHeiko Schocher 1771ff94bc40SHeiko Schocher if (calc != idx_size) { 1772*0195a7bbSHeiko Schocher ubifs_err(c, "index size check failed: calculated size is %lld, should be %lld", 1773ff94bc40SHeiko Schocher calc, idx_size); 1774ff94bc40SHeiko Schocher dump_stack(); 1775ff94bc40SHeiko Schocher return -EINVAL; 1776ff94bc40SHeiko Schocher } 1777ff94bc40SHeiko Schocher 1778ff94bc40SHeiko Schocher return 0; 1779ff94bc40SHeiko Schocher } 1780ff94bc40SHeiko Schocher 1781ff94bc40SHeiko Schocher #ifndef __UBOOT__ 1782ff94bc40SHeiko Schocher /** 1783ff94bc40SHeiko Schocher * struct fsck_inode - information about an inode used when checking the file-system. 1784ff94bc40SHeiko Schocher * @rb: link in the RB-tree of inodes 1785ff94bc40SHeiko Schocher * @inum: inode number 1786ff94bc40SHeiko Schocher * @mode: inode type, permissions, etc 1787ff94bc40SHeiko Schocher * @nlink: inode link count 1788ff94bc40SHeiko Schocher * @xattr_cnt: count of extended attributes 1789ff94bc40SHeiko Schocher * @references: how many directory/xattr entries refer this inode (calculated 1790ff94bc40SHeiko Schocher * while walking the index) 1791ff94bc40SHeiko Schocher * @calc_cnt: for directory inode count of child directories 1792ff94bc40SHeiko Schocher * @size: inode size (read from on-flash inode) 1793ff94bc40SHeiko Schocher * @xattr_sz: summary size of all extended attributes (read from on-flash 1794ff94bc40SHeiko Schocher * inode) 1795ff94bc40SHeiko Schocher * @calc_sz: for directories calculated directory size 1796ff94bc40SHeiko Schocher * @calc_xcnt: count of extended attributes 1797ff94bc40SHeiko Schocher * @calc_xsz: calculated summary size of all extended attributes 1798ff94bc40SHeiko Schocher * @xattr_nms: sum of lengths of all extended attribute names belonging to this 1799ff94bc40SHeiko Schocher * inode (read from on-flash inode) 1800ff94bc40SHeiko Schocher * @calc_xnms: calculated sum of lengths of all extended attribute names 1801ff94bc40SHeiko Schocher */ 1802ff94bc40SHeiko Schocher struct fsck_inode { 1803ff94bc40SHeiko Schocher struct rb_node rb; 1804ff94bc40SHeiko Schocher ino_t inum; 1805ff94bc40SHeiko Schocher umode_t mode; 1806ff94bc40SHeiko Schocher unsigned int nlink; 1807ff94bc40SHeiko Schocher unsigned int xattr_cnt; 1808ff94bc40SHeiko Schocher int references; 1809ff94bc40SHeiko Schocher int calc_cnt; 1810ff94bc40SHeiko Schocher long long size; 1811ff94bc40SHeiko Schocher unsigned int xattr_sz; 1812ff94bc40SHeiko Schocher long long calc_sz; 1813ff94bc40SHeiko Schocher long long calc_xcnt; 1814ff94bc40SHeiko Schocher long long calc_xsz; 1815ff94bc40SHeiko Schocher unsigned int xattr_nms; 1816ff94bc40SHeiko Schocher long long calc_xnms; 1817ff94bc40SHeiko Schocher }; 1818ff94bc40SHeiko Schocher 1819ff94bc40SHeiko Schocher /** 1820ff94bc40SHeiko Schocher * struct fsck_data - private FS checking information. 1821ff94bc40SHeiko Schocher * @inodes: RB-tree of all inodes (contains @struct fsck_inode objects) 1822ff94bc40SHeiko Schocher */ 1823ff94bc40SHeiko Schocher struct fsck_data { 1824ff94bc40SHeiko Schocher struct rb_root inodes; 1825ff94bc40SHeiko Schocher }; 1826ff94bc40SHeiko Schocher 1827ff94bc40SHeiko Schocher /** 1828ff94bc40SHeiko Schocher * add_inode - add inode information to RB-tree of inodes. 1829ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1830ff94bc40SHeiko Schocher * @fsckd: FS checking information 1831ff94bc40SHeiko Schocher * @ino: raw UBIFS inode to add 1832ff94bc40SHeiko Schocher * 1833ff94bc40SHeiko Schocher * This is a helper function for 'check_leaf()' which adds information about 1834ff94bc40SHeiko Schocher * inode @ino to the RB-tree of inodes. Returns inode information pointer in 1835ff94bc40SHeiko Schocher * case of success and a negative error code in case of failure. 1836ff94bc40SHeiko Schocher */ 1837ff94bc40SHeiko Schocher static struct fsck_inode *add_inode(struct ubifs_info *c, 1838ff94bc40SHeiko Schocher struct fsck_data *fsckd, 1839ff94bc40SHeiko Schocher struct ubifs_ino_node *ino) 1840ff94bc40SHeiko Schocher { 1841ff94bc40SHeiko Schocher struct rb_node **p, *parent = NULL; 1842ff94bc40SHeiko Schocher struct fsck_inode *fscki; 1843ff94bc40SHeiko Schocher ino_t inum = key_inum_flash(c, &ino->key); 1844ff94bc40SHeiko Schocher struct inode *inode; 1845ff94bc40SHeiko Schocher struct ubifs_inode *ui; 1846ff94bc40SHeiko Schocher 1847ff94bc40SHeiko Schocher p = &fsckd->inodes.rb_node; 1848ff94bc40SHeiko Schocher while (*p) { 1849ff94bc40SHeiko Schocher parent = *p; 1850ff94bc40SHeiko Schocher fscki = rb_entry(parent, struct fsck_inode, rb); 1851ff94bc40SHeiko Schocher if (inum < fscki->inum) 1852ff94bc40SHeiko Schocher p = &(*p)->rb_left; 1853ff94bc40SHeiko Schocher else if (inum > fscki->inum) 1854ff94bc40SHeiko Schocher p = &(*p)->rb_right; 1855ff94bc40SHeiko Schocher else 1856ff94bc40SHeiko Schocher return fscki; 1857ff94bc40SHeiko Schocher } 1858ff94bc40SHeiko Schocher 1859ff94bc40SHeiko Schocher if (inum > c->highest_inum) { 1860*0195a7bbSHeiko Schocher ubifs_err(c, "too high inode number, max. is %lu", 1861ff94bc40SHeiko Schocher (unsigned long)c->highest_inum); 1862ff94bc40SHeiko Schocher return ERR_PTR(-EINVAL); 1863ff94bc40SHeiko Schocher } 1864ff94bc40SHeiko Schocher 1865ff94bc40SHeiko Schocher fscki = kzalloc(sizeof(struct fsck_inode), GFP_NOFS); 1866ff94bc40SHeiko Schocher if (!fscki) 1867ff94bc40SHeiko Schocher return ERR_PTR(-ENOMEM); 1868ff94bc40SHeiko Schocher 1869ff94bc40SHeiko Schocher inode = ilookup(c->vfs_sb, inum); 1870ff94bc40SHeiko Schocher 1871ff94bc40SHeiko Schocher fscki->inum = inum; 1872ff94bc40SHeiko Schocher /* 1873ff94bc40SHeiko Schocher * If the inode is present in the VFS inode cache, use it instead of 1874ff94bc40SHeiko Schocher * the on-flash inode which might be out-of-date. E.g., the size might 1875ff94bc40SHeiko Schocher * be out-of-date. If we do not do this, the following may happen, for 1876ff94bc40SHeiko Schocher * example: 1877ff94bc40SHeiko Schocher * 1. A power cut happens 1878ff94bc40SHeiko Schocher * 2. We mount the file-system R/O, the replay process fixes up the 1879ff94bc40SHeiko Schocher * inode size in the VFS cache, but on on-flash. 1880ff94bc40SHeiko Schocher * 3. 'check_leaf()' fails because it hits a data node beyond inode 1881ff94bc40SHeiko Schocher * size. 1882ff94bc40SHeiko Schocher */ 1883ff94bc40SHeiko Schocher if (!inode) { 1884ff94bc40SHeiko Schocher fscki->nlink = le32_to_cpu(ino->nlink); 1885ff94bc40SHeiko Schocher fscki->size = le64_to_cpu(ino->size); 1886ff94bc40SHeiko Schocher fscki->xattr_cnt = le32_to_cpu(ino->xattr_cnt); 1887ff94bc40SHeiko Schocher fscki->xattr_sz = le32_to_cpu(ino->xattr_size); 1888ff94bc40SHeiko Schocher fscki->xattr_nms = le32_to_cpu(ino->xattr_names); 1889ff94bc40SHeiko Schocher fscki->mode = le32_to_cpu(ino->mode); 1890ff94bc40SHeiko Schocher } else { 1891ff94bc40SHeiko Schocher ui = ubifs_inode(inode); 1892ff94bc40SHeiko Schocher fscki->nlink = inode->i_nlink; 1893ff94bc40SHeiko Schocher fscki->size = inode->i_size; 1894ff94bc40SHeiko Schocher fscki->xattr_cnt = ui->xattr_cnt; 1895ff94bc40SHeiko Schocher fscki->xattr_sz = ui->xattr_size; 1896ff94bc40SHeiko Schocher fscki->xattr_nms = ui->xattr_names; 1897ff94bc40SHeiko Schocher fscki->mode = inode->i_mode; 1898ff94bc40SHeiko Schocher iput(inode); 1899ff94bc40SHeiko Schocher } 1900ff94bc40SHeiko Schocher 1901ff94bc40SHeiko Schocher if (S_ISDIR(fscki->mode)) { 1902ff94bc40SHeiko Schocher fscki->calc_sz = UBIFS_INO_NODE_SZ; 1903ff94bc40SHeiko Schocher fscki->calc_cnt = 2; 1904ff94bc40SHeiko Schocher } 1905ff94bc40SHeiko Schocher 1906ff94bc40SHeiko Schocher rb_link_node(&fscki->rb, parent, p); 1907ff94bc40SHeiko Schocher rb_insert_color(&fscki->rb, &fsckd->inodes); 1908ff94bc40SHeiko Schocher 1909ff94bc40SHeiko Schocher return fscki; 1910ff94bc40SHeiko Schocher } 1911ff94bc40SHeiko Schocher 1912ff94bc40SHeiko Schocher /** 1913ff94bc40SHeiko Schocher * search_inode - search inode in the RB-tree of inodes. 1914ff94bc40SHeiko Schocher * @fsckd: FS checking information 1915ff94bc40SHeiko Schocher * @inum: inode number to search 1916ff94bc40SHeiko Schocher * 1917ff94bc40SHeiko Schocher * This is a helper function for 'check_leaf()' which searches inode @inum in 1918ff94bc40SHeiko Schocher * the RB-tree of inodes and returns an inode information pointer or %NULL if 1919ff94bc40SHeiko Schocher * the inode was not found. 1920ff94bc40SHeiko Schocher */ 1921ff94bc40SHeiko Schocher static struct fsck_inode *search_inode(struct fsck_data *fsckd, ino_t inum) 1922ff94bc40SHeiko Schocher { 1923ff94bc40SHeiko Schocher struct rb_node *p; 1924ff94bc40SHeiko Schocher struct fsck_inode *fscki; 1925ff94bc40SHeiko Schocher 1926ff94bc40SHeiko Schocher p = fsckd->inodes.rb_node; 1927ff94bc40SHeiko Schocher while (p) { 1928ff94bc40SHeiko Schocher fscki = rb_entry(p, struct fsck_inode, rb); 1929ff94bc40SHeiko Schocher if (inum < fscki->inum) 1930ff94bc40SHeiko Schocher p = p->rb_left; 1931ff94bc40SHeiko Schocher else if (inum > fscki->inum) 1932ff94bc40SHeiko Schocher p = p->rb_right; 1933ff94bc40SHeiko Schocher else 1934ff94bc40SHeiko Schocher return fscki; 1935ff94bc40SHeiko Schocher } 1936ff94bc40SHeiko Schocher return NULL; 1937ff94bc40SHeiko Schocher } 1938ff94bc40SHeiko Schocher 1939ff94bc40SHeiko Schocher /** 1940ff94bc40SHeiko Schocher * read_add_inode - read inode node and add it to RB-tree of inodes. 1941ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 1942ff94bc40SHeiko Schocher * @fsckd: FS checking information 1943ff94bc40SHeiko Schocher * @inum: inode number to read 1944ff94bc40SHeiko Schocher * 1945ff94bc40SHeiko Schocher * This is a helper function for 'check_leaf()' which finds inode node @inum in 1946ff94bc40SHeiko Schocher * the index, reads it, and adds it to the RB-tree of inodes. Returns inode 1947ff94bc40SHeiko Schocher * information pointer in case of success and a negative error code in case of 1948ff94bc40SHeiko Schocher * failure. 1949ff94bc40SHeiko Schocher */ 1950ff94bc40SHeiko Schocher static struct fsck_inode *read_add_inode(struct ubifs_info *c, 1951ff94bc40SHeiko Schocher struct fsck_data *fsckd, ino_t inum) 1952ff94bc40SHeiko Schocher { 1953ff94bc40SHeiko Schocher int n, err; 1954ff94bc40SHeiko Schocher union ubifs_key key; 1955ff94bc40SHeiko Schocher struct ubifs_znode *znode; 1956ff94bc40SHeiko Schocher struct ubifs_zbranch *zbr; 1957ff94bc40SHeiko Schocher struct ubifs_ino_node *ino; 1958ff94bc40SHeiko Schocher struct fsck_inode *fscki; 1959ff94bc40SHeiko Schocher 1960ff94bc40SHeiko Schocher fscki = search_inode(fsckd, inum); 1961ff94bc40SHeiko Schocher if (fscki) 1962ff94bc40SHeiko Schocher return fscki; 1963ff94bc40SHeiko Schocher 1964ff94bc40SHeiko Schocher ino_key_init(c, &key, inum); 1965ff94bc40SHeiko Schocher err = ubifs_lookup_level0(c, &key, &znode, &n); 1966ff94bc40SHeiko Schocher if (!err) { 1967*0195a7bbSHeiko Schocher ubifs_err(c, "inode %lu not found in index", (unsigned long)inum); 1968ff94bc40SHeiko Schocher return ERR_PTR(-ENOENT); 1969ff94bc40SHeiko Schocher } else if (err < 0) { 1970*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while looking up inode %lu", 1971ff94bc40SHeiko Schocher err, (unsigned long)inum); 1972ff94bc40SHeiko Schocher return ERR_PTR(err); 1973ff94bc40SHeiko Schocher } 1974ff94bc40SHeiko Schocher 1975ff94bc40SHeiko Schocher zbr = &znode->zbranch[n]; 1976ff94bc40SHeiko Schocher if (zbr->len < UBIFS_INO_NODE_SZ) { 1977*0195a7bbSHeiko Schocher ubifs_err(c, "bad node %lu node length %d", 1978ff94bc40SHeiko Schocher (unsigned long)inum, zbr->len); 1979ff94bc40SHeiko Schocher return ERR_PTR(-EINVAL); 1980ff94bc40SHeiko Schocher } 1981ff94bc40SHeiko Schocher 1982ff94bc40SHeiko Schocher ino = kmalloc(zbr->len, GFP_NOFS); 1983ff94bc40SHeiko Schocher if (!ino) 1984ff94bc40SHeiko Schocher return ERR_PTR(-ENOMEM); 1985ff94bc40SHeiko Schocher 1986ff94bc40SHeiko Schocher err = ubifs_tnc_read_node(c, zbr, ino); 1987ff94bc40SHeiko Schocher if (err) { 1988*0195a7bbSHeiko Schocher ubifs_err(c, "cannot read inode node at LEB %d:%d, error %d", 1989ff94bc40SHeiko Schocher zbr->lnum, zbr->offs, err); 1990ff94bc40SHeiko Schocher kfree(ino); 1991ff94bc40SHeiko Schocher return ERR_PTR(err); 1992ff94bc40SHeiko Schocher } 1993ff94bc40SHeiko Schocher 1994ff94bc40SHeiko Schocher fscki = add_inode(c, fsckd, ino); 1995ff94bc40SHeiko Schocher kfree(ino); 1996ff94bc40SHeiko Schocher if (IS_ERR(fscki)) { 1997*0195a7bbSHeiko Schocher ubifs_err(c, "error %ld while adding inode %lu node", 1998ff94bc40SHeiko Schocher PTR_ERR(fscki), (unsigned long)inum); 1999ff94bc40SHeiko Schocher return fscki; 2000ff94bc40SHeiko Schocher } 2001ff94bc40SHeiko Schocher 2002ff94bc40SHeiko Schocher return fscki; 2003ff94bc40SHeiko Schocher } 2004ff94bc40SHeiko Schocher 2005ff94bc40SHeiko Schocher /** 2006ff94bc40SHeiko Schocher * check_leaf - check leaf node. 2007ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2008ff94bc40SHeiko Schocher * @zbr: zbranch of the leaf node to check 2009ff94bc40SHeiko Schocher * @priv: FS checking information 2010ff94bc40SHeiko Schocher * 2011ff94bc40SHeiko Schocher * This is a helper function for 'dbg_check_filesystem()' which is called for 2012ff94bc40SHeiko Schocher * every single leaf node while walking the indexing tree. It checks that the 2013ff94bc40SHeiko Schocher * leaf node referred from the indexing tree exists, has correct CRC, and does 2014ff94bc40SHeiko Schocher * some other basic validation. This function is also responsible for building 2015ff94bc40SHeiko Schocher * an RB-tree of inodes - it adds all inodes into the RB-tree. It also 2016ff94bc40SHeiko Schocher * calculates reference count, size, etc for each inode in order to later 2017ff94bc40SHeiko Schocher * compare them to the information stored inside the inodes and detect possible 2018ff94bc40SHeiko Schocher * inconsistencies. Returns zero in case of success and a negative error code 2019ff94bc40SHeiko Schocher * in case of failure. 2020ff94bc40SHeiko Schocher */ 2021ff94bc40SHeiko Schocher static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, 2022ff94bc40SHeiko Schocher void *priv) 2023ff94bc40SHeiko Schocher { 2024ff94bc40SHeiko Schocher ino_t inum; 2025ff94bc40SHeiko Schocher void *node; 2026ff94bc40SHeiko Schocher struct ubifs_ch *ch; 2027ff94bc40SHeiko Schocher int err, type = key_type(c, &zbr->key); 2028ff94bc40SHeiko Schocher struct fsck_inode *fscki; 2029ff94bc40SHeiko Schocher 2030ff94bc40SHeiko Schocher if (zbr->len < UBIFS_CH_SZ) { 2031*0195a7bbSHeiko Schocher ubifs_err(c, "bad leaf length %d (LEB %d:%d)", 2032ff94bc40SHeiko Schocher zbr->len, zbr->lnum, zbr->offs); 2033ff94bc40SHeiko Schocher return -EINVAL; 2034ff94bc40SHeiko Schocher } 2035ff94bc40SHeiko Schocher 2036ff94bc40SHeiko Schocher node = kmalloc(zbr->len, GFP_NOFS); 2037ff94bc40SHeiko Schocher if (!node) 2038ff94bc40SHeiko Schocher return -ENOMEM; 2039ff94bc40SHeiko Schocher 2040ff94bc40SHeiko Schocher err = ubifs_tnc_read_node(c, zbr, node); 2041ff94bc40SHeiko Schocher if (err) { 2042*0195a7bbSHeiko Schocher ubifs_err(c, "cannot read leaf node at LEB %d:%d, error %d", 2043ff94bc40SHeiko Schocher zbr->lnum, zbr->offs, err); 2044ff94bc40SHeiko Schocher goto out_free; 2045ff94bc40SHeiko Schocher } 2046ff94bc40SHeiko Schocher 2047ff94bc40SHeiko Schocher /* If this is an inode node, add it to RB-tree of inodes */ 2048ff94bc40SHeiko Schocher if (type == UBIFS_INO_KEY) { 2049ff94bc40SHeiko Schocher fscki = add_inode(c, priv, node); 2050ff94bc40SHeiko Schocher if (IS_ERR(fscki)) { 2051ff94bc40SHeiko Schocher err = PTR_ERR(fscki); 2052*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while adding inode node", err); 2053ff94bc40SHeiko Schocher goto out_dump; 2054ff94bc40SHeiko Schocher } 2055ff94bc40SHeiko Schocher goto out; 2056ff94bc40SHeiko Schocher } 2057ff94bc40SHeiko Schocher 2058ff94bc40SHeiko Schocher if (type != UBIFS_DENT_KEY && type != UBIFS_XENT_KEY && 2059ff94bc40SHeiko Schocher type != UBIFS_DATA_KEY) { 2060*0195a7bbSHeiko Schocher ubifs_err(c, "unexpected node type %d at LEB %d:%d", 2061ff94bc40SHeiko Schocher type, zbr->lnum, zbr->offs); 2062ff94bc40SHeiko Schocher err = -EINVAL; 2063ff94bc40SHeiko Schocher goto out_free; 2064ff94bc40SHeiko Schocher } 2065ff94bc40SHeiko Schocher 2066ff94bc40SHeiko Schocher ch = node; 2067ff94bc40SHeiko Schocher if (le64_to_cpu(ch->sqnum) > c->max_sqnum) { 2068*0195a7bbSHeiko Schocher ubifs_err(c, "too high sequence number, max. is %llu", 2069ff94bc40SHeiko Schocher c->max_sqnum); 2070ff94bc40SHeiko Schocher err = -EINVAL; 2071ff94bc40SHeiko Schocher goto out_dump; 2072ff94bc40SHeiko Schocher } 2073ff94bc40SHeiko Schocher 2074ff94bc40SHeiko Schocher if (type == UBIFS_DATA_KEY) { 2075ff94bc40SHeiko Schocher long long blk_offs; 2076ff94bc40SHeiko Schocher struct ubifs_data_node *dn = node; 2077ff94bc40SHeiko Schocher 2078*0195a7bbSHeiko Schocher ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ); 2079*0195a7bbSHeiko Schocher 2080ff94bc40SHeiko Schocher /* 2081ff94bc40SHeiko Schocher * Search the inode node this data node belongs to and insert 2082ff94bc40SHeiko Schocher * it to the RB-tree of inodes. 2083ff94bc40SHeiko Schocher */ 2084ff94bc40SHeiko Schocher inum = key_inum_flash(c, &dn->key); 2085ff94bc40SHeiko Schocher fscki = read_add_inode(c, priv, inum); 2086ff94bc40SHeiko Schocher if (IS_ERR(fscki)) { 2087ff94bc40SHeiko Schocher err = PTR_ERR(fscki); 2088*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while processing data node and trying to find inode node %lu", 2089ff94bc40SHeiko Schocher err, (unsigned long)inum); 2090ff94bc40SHeiko Schocher goto out_dump; 2091ff94bc40SHeiko Schocher } 2092ff94bc40SHeiko Schocher 2093ff94bc40SHeiko Schocher /* Make sure the data node is within inode size */ 2094ff94bc40SHeiko Schocher blk_offs = key_block_flash(c, &dn->key); 2095ff94bc40SHeiko Schocher blk_offs <<= UBIFS_BLOCK_SHIFT; 2096ff94bc40SHeiko Schocher blk_offs += le32_to_cpu(dn->size); 2097ff94bc40SHeiko Schocher if (blk_offs > fscki->size) { 2098*0195a7bbSHeiko Schocher ubifs_err(c, "data node at LEB %d:%d is not within inode size %lld", 2099ff94bc40SHeiko Schocher zbr->lnum, zbr->offs, fscki->size); 2100ff94bc40SHeiko Schocher err = -EINVAL; 2101ff94bc40SHeiko Schocher goto out_dump; 2102ff94bc40SHeiko Schocher } 2103ff94bc40SHeiko Schocher } else { 2104ff94bc40SHeiko Schocher int nlen; 2105ff94bc40SHeiko Schocher struct ubifs_dent_node *dent = node; 2106ff94bc40SHeiko Schocher struct fsck_inode *fscki1; 2107ff94bc40SHeiko Schocher 2108*0195a7bbSHeiko Schocher ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ); 2109*0195a7bbSHeiko Schocher 2110ff94bc40SHeiko Schocher err = ubifs_validate_entry(c, dent); 2111ff94bc40SHeiko Schocher if (err) 2112ff94bc40SHeiko Schocher goto out_dump; 2113ff94bc40SHeiko Schocher 2114ff94bc40SHeiko Schocher /* 2115ff94bc40SHeiko Schocher * Search the inode node this entry refers to and the parent 2116ff94bc40SHeiko Schocher * inode node and insert them to the RB-tree of inodes. 2117ff94bc40SHeiko Schocher */ 2118ff94bc40SHeiko Schocher inum = le64_to_cpu(dent->inum); 2119ff94bc40SHeiko Schocher fscki = read_add_inode(c, priv, inum); 2120ff94bc40SHeiko Schocher if (IS_ERR(fscki)) { 2121ff94bc40SHeiko Schocher err = PTR_ERR(fscki); 2122*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while processing entry node and trying to find inode node %lu", 2123ff94bc40SHeiko Schocher err, (unsigned long)inum); 2124ff94bc40SHeiko Schocher goto out_dump; 2125ff94bc40SHeiko Schocher } 2126ff94bc40SHeiko Schocher 2127ff94bc40SHeiko Schocher /* Count how many direntries or xentries refers this inode */ 2128ff94bc40SHeiko Schocher fscki->references += 1; 2129ff94bc40SHeiko Schocher 2130ff94bc40SHeiko Schocher inum = key_inum_flash(c, &dent->key); 2131ff94bc40SHeiko Schocher fscki1 = read_add_inode(c, priv, inum); 2132ff94bc40SHeiko Schocher if (IS_ERR(fscki1)) { 2133ff94bc40SHeiko Schocher err = PTR_ERR(fscki1); 2134*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while processing entry node and trying to find parent inode node %lu", 2135ff94bc40SHeiko Schocher err, (unsigned long)inum); 2136ff94bc40SHeiko Schocher goto out_dump; 2137ff94bc40SHeiko Schocher } 2138ff94bc40SHeiko Schocher 2139ff94bc40SHeiko Schocher nlen = le16_to_cpu(dent->nlen); 2140ff94bc40SHeiko Schocher if (type == UBIFS_XENT_KEY) { 2141ff94bc40SHeiko Schocher fscki1->calc_xcnt += 1; 2142ff94bc40SHeiko Schocher fscki1->calc_xsz += CALC_DENT_SIZE(nlen); 2143ff94bc40SHeiko Schocher fscki1->calc_xsz += CALC_XATTR_BYTES(fscki->size); 2144ff94bc40SHeiko Schocher fscki1->calc_xnms += nlen; 2145ff94bc40SHeiko Schocher } else { 2146ff94bc40SHeiko Schocher fscki1->calc_sz += CALC_DENT_SIZE(nlen); 2147ff94bc40SHeiko Schocher if (dent->type == UBIFS_ITYPE_DIR) 2148ff94bc40SHeiko Schocher fscki1->calc_cnt += 1; 2149ff94bc40SHeiko Schocher } 2150ff94bc40SHeiko Schocher } 2151ff94bc40SHeiko Schocher 2152ff94bc40SHeiko Schocher out: 2153ff94bc40SHeiko Schocher kfree(node); 2154ff94bc40SHeiko Schocher return 0; 2155ff94bc40SHeiko Schocher 2156ff94bc40SHeiko Schocher out_dump: 2157*0195a7bbSHeiko Schocher ubifs_msg(c, "dump of node at LEB %d:%d", zbr->lnum, zbr->offs); 2158ff94bc40SHeiko Schocher ubifs_dump_node(c, node); 2159ff94bc40SHeiko Schocher out_free: 2160ff94bc40SHeiko Schocher kfree(node); 2161ff94bc40SHeiko Schocher return err; 2162ff94bc40SHeiko Schocher } 2163ff94bc40SHeiko Schocher 2164ff94bc40SHeiko Schocher /** 2165ff94bc40SHeiko Schocher * free_inodes - free RB-tree of inodes. 2166ff94bc40SHeiko Schocher * @fsckd: FS checking information 2167ff94bc40SHeiko Schocher */ 2168ff94bc40SHeiko Schocher static void free_inodes(struct fsck_data *fsckd) 2169ff94bc40SHeiko Schocher { 2170ff94bc40SHeiko Schocher struct fsck_inode *fscki, *n; 2171ff94bc40SHeiko Schocher 2172ff94bc40SHeiko Schocher rbtree_postorder_for_each_entry_safe(fscki, n, &fsckd->inodes, rb) 2173ff94bc40SHeiko Schocher kfree(fscki); 2174ff94bc40SHeiko Schocher } 2175ff94bc40SHeiko Schocher 2176ff94bc40SHeiko Schocher /** 2177ff94bc40SHeiko Schocher * check_inodes - checks all inodes. 2178ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2179ff94bc40SHeiko Schocher * @fsckd: FS checking information 2180ff94bc40SHeiko Schocher * 2181ff94bc40SHeiko Schocher * This is a helper function for 'dbg_check_filesystem()' which walks the 2182ff94bc40SHeiko Schocher * RB-tree of inodes after the index scan has been finished, and checks that 2183ff94bc40SHeiko Schocher * inode nlink, size, etc are correct. Returns zero if inodes are fine, 2184ff94bc40SHeiko Schocher * %-EINVAL if not, and a negative error code in case of failure. 2185ff94bc40SHeiko Schocher */ 2186ff94bc40SHeiko Schocher static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd) 2187ff94bc40SHeiko Schocher { 2188ff94bc40SHeiko Schocher int n, err; 2189ff94bc40SHeiko Schocher union ubifs_key key; 2190ff94bc40SHeiko Schocher struct ubifs_znode *znode; 2191ff94bc40SHeiko Schocher struct ubifs_zbranch *zbr; 2192ff94bc40SHeiko Schocher struct ubifs_ino_node *ino; 2193ff94bc40SHeiko Schocher struct fsck_inode *fscki; 2194ff94bc40SHeiko Schocher struct rb_node *this = rb_first(&fsckd->inodes); 2195ff94bc40SHeiko Schocher 2196ff94bc40SHeiko Schocher while (this) { 2197ff94bc40SHeiko Schocher fscki = rb_entry(this, struct fsck_inode, rb); 2198ff94bc40SHeiko Schocher this = rb_next(this); 2199ff94bc40SHeiko Schocher 2200ff94bc40SHeiko Schocher if (S_ISDIR(fscki->mode)) { 2201ff94bc40SHeiko Schocher /* 2202ff94bc40SHeiko Schocher * Directories have to have exactly one reference (they 2203ff94bc40SHeiko Schocher * cannot have hardlinks), although root inode is an 2204ff94bc40SHeiko Schocher * exception. 2205ff94bc40SHeiko Schocher */ 2206ff94bc40SHeiko Schocher if (fscki->inum != UBIFS_ROOT_INO && 2207ff94bc40SHeiko Schocher fscki->references != 1) { 2208*0195a7bbSHeiko Schocher ubifs_err(c, "directory inode %lu has %d direntries which refer it, but should be 1", 2209ff94bc40SHeiko Schocher (unsigned long)fscki->inum, 2210ff94bc40SHeiko Schocher fscki->references); 2211ff94bc40SHeiko Schocher goto out_dump; 2212ff94bc40SHeiko Schocher } 2213ff94bc40SHeiko Schocher if (fscki->inum == UBIFS_ROOT_INO && 2214ff94bc40SHeiko Schocher fscki->references != 0) { 2215*0195a7bbSHeiko Schocher ubifs_err(c, "root inode %lu has non-zero (%d) direntries which refer it", 2216ff94bc40SHeiko Schocher (unsigned long)fscki->inum, 2217ff94bc40SHeiko Schocher fscki->references); 2218ff94bc40SHeiko Schocher goto out_dump; 2219ff94bc40SHeiko Schocher } 2220ff94bc40SHeiko Schocher if (fscki->calc_sz != fscki->size) { 2221*0195a7bbSHeiko Schocher ubifs_err(c, "directory inode %lu size is %lld, but calculated size is %lld", 2222ff94bc40SHeiko Schocher (unsigned long)fscki->inum, 2223ff94bc40SHeiko Schocher fscki->size, fscki->calc_sz); 2224ff94bc40SHeiko Schocher goto out_dump; 2225ff94bc40SHeiko Schocher } 2226ff94bc40SHeiko Schocher if (fscki->calc_cnt != fscki->nlink) { 2227*0195a7bbSHeiko Schocher ubifs_err(c, "directory inode %lu nlink is %d, but calculated nlink is %d", 2228ff94bc40SHeiko Schocher (unsigned long)fscki->inum, 2229ff94bc40SHeiko Schocher fscki->nlink, fscki->calc_cnt); 2230ff94bc40SHeiko Schocher goto out_dump; 2231ff94bc40SHeiko Schocher } 2232ff94bc40SHeiko Schocher } else { 2233ff94bc40SHeiko Schocher if (fscki->references != fscki->nlink) { 2234*0195a7bbSHeiko Schocher ubifs_err(c, "inode %lu nlink is %d, but calculated nlink is %d", 2235ff94bc40SHeiko Schocher (unsigned long)fscki->inum, 2236ff94bc40SHeiko Schocher fscki->nlink, fscki->references); 2237ff94bc40SHeiko Schocher goto out_dump; 2238ff94bc40SHeiko Schocher } 2239ff94bc40SHeiko Schocher } 2240ff94bc40SHeiko Schocher if (fscki->xattr_sz != fscki->calc_xsz) { 2241*0195a7bbSHeiko Schocher ubifs_err(c, "inode %lu has xattr size %u, but calculated size is %lld", 2242ff94bc40SHeiko Schocher (unsigned long)fscki->inum, fscki->xattr_sz, 2243ff94bc40SHeiko Schocher fscki->calc_xsz); 2244ff94bc40SHeiko Schocher goto out_dump; 2245ff94bc40SHeiko Schocher } 2246ff94bc40SHeiko Schocher if (fscki->xattr_cnt != fscki->calc_xcnt) { 2247*0195a7bbSHeiko Schocher ubifs_err(c, "inode %lu has %u xattrs, but calculated count is %lld", 2248ff94bc40SHeiko Schocher (unsigned long)fscki->inum, 2249ff94bc40SHeiko Schocher fscki->xattr_cnt, fscki->calc_xcnt); 2250ff94bc40SHeiko Schocher goto out_dump; 2251ff94bc40SHeiko Schocher } 2252ff94bc40SHeiko Schocher if (fscki->xattr_nms != fscki->calc_xnms) { 2253*0195a7bbSHeiko Schocher ubifs_err(c, "inode %lu has xattr names' size %u, but calculated names' size is %lld", 2254ff94bc40SHeiko Schocher (unsigned long)fscki->inum, fscki->xattr_nms, 2255ff94bc40SHeiko Schocher fscki->calc_xnms); 2256ff94bc40SHeiko Schocher goto out_dump; 2257ff94bc40SHeiko Schocher } 2258ff94bc40SHeiko Schocher } 2259ff94bc40SHeiko Schocher 2260ff94bc40SHeiko Schocher return 0; 2261ff94bc40SHeiko Schocher 2262ff94bc40SHeiko Schocher out_dump: 2263ff94bc40SHeiko Schocher /* Read the bad inode and dump it */ 2264ff94bc40SHeiko Schocher ino_key_init(c, &key, fscki->inum); 2265ff94bc40SHeiko Schocher err = ubifs_lookup_level0(c, &key, &znode, &n); 2266ff94bc40SHeiko Schocher if (!err) { 2267*0195a7bbSHeiko Schocher ubifs_err(c, "inode %lu not found in index", 2268ff94bc40SHeiko Schocher (unsigned long)fscki->inum); 2269ff94bc40SHeiko Schocher return -ENOENT; 2270ff94bc40SHeiko Schocher } else if (err < 0) { 2271*0195a7bbSHeiko Schocher ubifs_err(c, "error %d while looking up inode %lu", 2272ff94bc40SHeiko Schocher err, (unsigned long)fscki->inum); 2273ff94bc40SHeiko Schocher return err; 2274ff94bc40SHeiko Schocher } 2275ff94bc40SHeiko Schocher 2276ff94bc40SHeiko Schocher zbr = &znode->zbranch[n]; 2277ff94bc40SHeiko Schocher ino = kmalloc(zbr->len, GFP_NOFS); 2278ff94bc40SHeiko Schocher if (!ino) 2279ff94bc40SHeiko Schocher return -ENOMEM; 2280ff94bc40SHeiko Schocher 2281ff94bc40SHeiko Schocher err = ubifs_tnc_read_node(c, zbr, ino); 2282ff94bc40SHeiko Schocher if (err) { 2283*0195a7bbSHeiko Schocher ubifs_err(c, "cannot read inode node at LEB %d:%d, error %d", 2284ff94bc40SHeiko Schocher zbr->lnum, zbr->offs, err); 2285ff94bc40SHeiko Schocher kfree(ino); 2286ff94bc40SHeiko Schocher return err; 2287ff94bc40SHeiko Schocher } 2288ff94bc40SHeiko Schocher 2289*0195a7bbSHeiko Schocher ubifs_msg(c, "dump of the inode %lu sitting in LEB %d:%d", 2290ff94bc40SHeiko Schocher (unsigned long)fscki->inum, zbr->lnum, zbr->offs); 2291ff94bc40SHeiko Schocher ubifs_dump_node(c, ino); 2292ff94bc40SHeiko Schocher kfree(ino); 2293ff94bc40SHeiko Schocher return -EINVAL; 2294ff94bc40SHeiko Schocher } 2295ff94bc40SHeiko Schocher 2296ff94bc40SHeiko Schocher /** 2297ff94bc40SHeiko Schocher * dbg_check_filesystem - check the file-system. 2298ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2299ff94bc40SHeiko Schocher * 2300ff94bc40SHeiko Schocher * This function checks the file system, namely: 2301ff94bc40SHeiko Schocher * o makes sure that all leaf nodes exist and their CRCs are correct; 2302ff94bc40SHeiko Schocher * o makes sure inode nlink, size, xattr size/count are correct (for all 2303ff94bc40SHeiko Schocher * inodes). 2304ff94bc40SHeiko Schocher * 2305ff94bc40SHeiko Schocher * The function reads whole indexing tree and all nodes, so it is pretty 2306ff94bc40SHeiko Schocher * heavy-weight. Returns zero if the file-system is consistent, %-EINVAL if 2307ff94bc40SHeiko Schocher * not, and a negative error code in case of failure. 2308ff94bc40SHeiko Schocher */ 2309ff94bc40SHeiko Schocher int dbg_check_filesystem(struct ubifs_info *c) 2310ff94bc40SHeiko Schocher { 2311ff94bc40SHeiko Schocher int err; 2312ff94bc40SHeiko Schocher struct fsck_data fsckd; 2313ff94bc40SHeiko Schocher 2314ff94bc40SHeiko Schocher if (!dbg_is_chk_fs(c)) 2315ff94bc40SHeiko Schocher return 0; 2316ff94bc40SHeiko Schocher 2317ff94bc40SHeiko Schocher fsckd.inodes = RB_ROOT; 2318ff94bc40SHeiko Schocher err = dbg_walk_index(c, check_leaf, NULL, &fsckd); 2319ff94bc40SHeiko Schocher if (err) 2320ff94bc40SHeiko Schocher goto out_free; 2321ff94bc40SHeiko Schocher 2322ff94bc40SHeiko Schocher err = check_inodes(c, &fsckd); 2323ff94bc40SHeiko Schocher if (err) 2324ff94bc40SHeiko Schocher goto out_free; 2325ff94bc40SHeiko Schocher 2326ff94bc40SHeiko Schocher free_inodes(&fsckd); 2327ff94bc40SHeiko Schocher return 0; 2328ff94bc40SHeiko Schocher 2329ff94bc40SHeiko Schocher out_free: 2330*0195a7bbSHeiko Schocher ubifs_err(c, "file-system check failed with error %d", err); 2331ff94bc40SHeiko Schocher dump_stack(); 2332ff94bc40SHeiko Schocher free_inodes(&fsckd); 2333ff94bc40SHeiko Schocher return err; 2334ff94bc40SHeiko Schocher } 2335ff94bc40SHeiko Schocher 2336ff94bc40SHeiko Schocher /** 2337ff94bc40SHeiko Schocher * dbg_check_data_nodes_order - check that list of data nodes is sorted. 2338ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2339ff94bc40SHeiko Schocher * @head: the list of nodes ('struct ubifs_scan_node' objects) 2340ff94bc40SHeiko Schocher * 2341ff94bc40SHeiko Schocher * This function returns zero if the list of data nodes is sorted correctly, 2342ff94bc40SHeiko Schocher * and %-EINVAL if not. 2343ff94bc40SHeiko Schocher */ 2344ff94bc40SHeiko Schocher int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head) 2345ff94bc40SHeiko Schocher { 2346ff94bc40SHeiko Schocher struct list_head *cur; 2347ff94bc40SHeiko Schocher struct ubifs_scan_node *sa, *sb; 2348ff94bc40SHeiko Schocher 2349ff94bc40SHeiko Schocher if (!dbg_is_chk_gen(c)) 2350ff94bc40SHeiko Schocher return 0; 2351ff94bc40SHeiko Schocher 2352ff94bc40SHeiko Schocher for (cur = head->next; cur->next != head; cur = cur->next) { 2353ff94bc40SHeiko Schocher ino_t inuma, inumb; 2354ff94bc40SHeiko Schocher uint32_t blka, blkb; 2355ff94bc40SHeiko Schocher 2356ff94bc40SHeiko Schocher cond_resched(); 2357ff94bc40SHeiko Schocher sa = container_of(cur, struct ubifs_scan_node, list); 2358ff94bc40SHeiko Schocher sb = container_of(cur->next, struct ubifs_scan_node, list); 2359ff94bc40SHeiko Schocher 2360ff94bc40SHeiko Schocher if (sa->type != UBIFS_DATA_NODE) { 2361*0195a7bbSHeiko Schocher ubifs_err(c, "bad node type %d", sa->type); 2362ff94bc40SHeiko Schocher ubifs_dump_node(c, sa->node); 2363ff94bc40SHeiko Schocher return -EINVAL; 2364ff94bc40SHeiko Schocher } 2365ff94bc40SHeiko Schocher if (sb->type != UBIFS_DATA_NODE) { 2366*0195a7bbSHeiko Schocher ubifs_err(c, "bad node type %d", sb->type); 2367ff94bc40SHeiko Schocher ubifs_dump_node(c, sb->node); 2368ff94bc40SHeiko Schocher return -EINVAL; 2369ff94bc40SHeiko Schocher } 2370ff94bc40SHeiko Schocher 2371ff94bc40SHeiko Schocher inuma = key_inum(c, &sa->key); 2372ff94bc40SHeiko Schocher inumb = key_inum(c, &sb->key); 2373ff94bc40SHeiko Schocher 2374ff94bc40SHeiko Schocher if (inuma < inumb) 2375ff94bc40SHeiko Schocher continue; 2376ff94bc40SHeiko Schocher if (inuma > inumb) { 2377*0195a7bbSHeiko Schocher ubifs_err(c, "larger inum %lu goes before inum %lu", 2378ff94bc40SHeiko Schocher (unsigned long)inuma, (unsigned long)inumb); 2379ff94bc40SHeiko Schocher goto error_dump; 2380ff94bc40SHeiko Schocher } 2381ff94bc40SHeiko Schocher 2382ff94bc40SHeiko Schocher blka = key_block(c, &sa->key); 2383ff94bc40SHeiko Schocher blkb = key_block(c, &sb->key); 2384ff94bc40SHeiko Schocher 2385ff94bc40SHeiko Schocher if (blka > blkb) { 2386*0195a7bbSHeiko Schocher ubifs_err(c, "larger block %u goes before %u", blka, blkb); 2387ff94bc40SHeiko Schocher goto error_dump; 2388ff94bc40SHeiko Schocher } 2389ff94bc40SHeiko Schocher if (blka == blkb) { 2390*0195a7bbSHeiko Schocher ubifs_err(c, "two data nodes for the same block"); 2391ff94bc40SHeiko Schocher goto error_dump; 2392ff94bc40SHeiko Schocher } 2393ff94bc40SHeiko Schocher } 2394ff94bc40SHeiko Schocher 2395ff94bc40SHeiko Schocher return 0; 2396ff94bc40SHeiko Schocher 2397ff94bc40SHeiko Schocher error_dump: 2398ff94bc40SHeiko Schocher ubifs_dump_node(c, sa->node); 2399ff94bc40SHeiko Schocher ubifs_dump_node(c, sb->node); 2400ff94bc40SHeiko Schocher return -EINVAL; 2401ff94bc40SHeiko Schocher } 2402ff94bc40SHeiko Schocher 2403ff94bc40SHeiko Schocher /** 2404ff94bc40SHeiko Schocher * dbg_check_nondata_nodes_order - check that list of data nodes is sorted. 2405ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2406ff94bc40SHeiko Schocher * @head: the list of nodes ('struct ubifs_scan_node' objects) 2407ff94bc40SHeiko Schocher * 2408ff94bc40SHeiko Schocher * This function returns zero if the list of non-data nodes is sorted correctly, 2409ff94bc40SHeiko Schocher * and %-EINVAL if not. 2410ff94bc40SHeiko Schocher */ 2411ff94bc40SHeiko Schocher int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) 2412ff94bc40SHeiko Schocher { 2413ff94bc40SHeiko Schocher struct list_head *cur; 2414ff94bc40SHeiko Schocher struct ubifs_scan_node *sa, *sb; 2415ff94bc40SHeiko Schocher 2416ff94bc40SHeiko Schocher if (!dbg_is_chk_gen(c)) 2417ff94bc40SHeiko Schocher return 0; 2418ff94bc40SHeiko Schocher 2419ff94bc40SHeiko Schocher for (cur = head->next; cur->next != head; cur = cur->next) { 2420ff94bc40SHeiko Schocher ino_t inuma, inumb; 2421ff94bc40SHeiko Schocher uint32_t hasha, hashb; 2422ff94bc40SHeiko Schocher 2423ff94bc40SHeiko Schocher cond_resched(); 2424ff94bc40SHeiko Schocher sa = container_of(cur, struct ubifs_scan_node, list); 2425ff94bc40SHeiko Schocher sb = container_of(cur->next, struct ubifs_scan_node, list); 2426ff94bc40SHeiko Schocher 2427ff94bc40SHeiko Schocher if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE && 2428ff94bc40SHeiko Schocher sa->type != UBIFS_XENT_NODE) { 2429*0195a7bbSHeiko Schocher ubifs_err(c, "bad node type %d", sa->type); 2430ff94bc40SHeiko Schocher ubifs_dump_node(c, sa->node); 2431ff94bc40SHeiko Schocher return -EINVAL; 2432ff94bc40SHeiko Schocher } 2433ff94bc40SHeiko Schocher if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE && 2434ff94bc40SHeiko Schocher sa->type != UBIFS_XENT_NODE) { 2435*0195a7bbSHeiko Schocher ubifs_err(c, "bad node type %d", sb->type); 2436ff94bc40SHeiko Schocher ubifs_dump_node(c, sb->node); 2437ff94bc40SHeiko Schocher return -EINVAL; 2438ff94bc40SHeiko Schocher } 2439ff94bc40SHeiko Schocher 2440ff94bc40SHeiko Schocher if (sa->type != UBIFS_INO_NODE && sb->type == UBIFS_INO_NODE) { 2441*0195a7bbSHeiko Schocher ubifs_err(c, "non-inode node goes before inode node"); 2442ff94bc40SHeiko Schocher goto error_dump; 2443ff94bc40SHeiko Schocher } 2444ff94bc40SHeiko Schocher 2445ff94bc40SHeiko Schocher if (sa->type == UBIFS_INO_NODE && sb->type != UBIFS_INO_NODE) 2446ff94bc40SHeiko Schocher continue; 2447ff94bc40SHeiko Schocher 2448ff94bc40SHeiko Schocher if (sa->type == UBIFS_INO_NODE && sb->type == UBIFS_INO_NODE) { 2449ff94bc40SHeiko Schocher /* Inode nodes are sorted in descending size order */ 2450ff94bc40SHeiko Schocher if (sa->len < sb->len) { 2451*0195a7bbSHeiko Schocher ubifs_err(c, "smaller inode node goes first"); 2452ff94bc40SHeiko Schocher goto error_dump; 2453ff94bc40SHeiko Schocher } 2454ff94bc40SHeiko Schocher continue; 2455ff94bc40SHeiko Schocher } 2456ff94bc40SHeiko Schocher 2457ff94bc40SHeiko Schocher /* 2458ff94bc40SHeiko Schocher * This is either a dentry or xentry, which should be sorted in 2459ff94bc40SHeiko Schocher * ascending (parent ino, hash) order. 2460ff94bc40SHeiko Schocher */ 2461ff94bc40SHeiko Schocher inuma = key_inum(c, &sa->key); 2462ff94bc40SHeiko Schocher inumb = key_inum(c, &sb->key); 2463ff94bc40SHeiko Schocher 2464ff94bc40SHeiko Schocher if (inuma < inumb) 2465ff94bc40SHeiko Schocher continue; 2466ff94bc40SHeiko Schocher if (inuma > inumb) { 2467*0195a7bbSHeiko Schocher ubifs_err(c, "larger inum %lu goes before inum %lu", 2468ff94bc40SHeiko Schocher (unsigned long)inuma, (unsigned long)inumb); 2469ff94bc40SHeiko Schocher goto error_dump; 2470ff94bc40SHeiko Schocher } 2471ff94bc40SHeiko Schocher 2472ff94bc40SHeiko Schocher hasha = key_block(c, &sa->key); 2473ff94bc40SHeiko Schocher hashb = key_block(c, &sb->key); 2474ff94bc40SHeiko Schocher 2475ff94bc40SHeiko Schocher if (hasha > hashb) { 2476*0195a7bbSHeiko Schocher ubifs_err(c, "larger hash %u goes before %u", 2477ff94bc40SHeiko Schocher hasha, hashb); 2478ff94bc40SHeiko Schocher goto error_dump; 2479ff94bc40SHeiko Schocher } 2480ff94bc40SHeiko Schocher } 2481ff94bc40SHeiko Schocher 2482ff94bc40SHeiko Schocher return 0; 2483ff94bc40SHeiko Schocher 2484ff94bc40SHeiko Schocher error_dump: 2485*0195a7bbSHeiko Schocher ubifs_msg(c, "dumping first node"); 2486ff94bc40SHeiko Schocher ubifs_dump_node(c, sa->node); 2487*0195a7bbSHeiko Schocher ubifs_msg(c, "dumping second node"); 2488ff94bc40SHeiko Schocher ubifs_dump_node(c, sb->node); 2489ff94bc40SHeiko Schocher return -EINVAL; 2490ff94bc40SHeiko Schocher return 0; 2491ff94bc40SHeiko Schocher } 2492ff94bc40SHeiko Schocher 2493ff94bc40SHeiko Schocher static inline int chance(unsigned int n, unsigned int out_of) 2494ff94bc40SHeiko Schocher { 2495ff94bc40SHeiko Schocher return !!((prandom_u32() % out_of) + 1 <= n); 2496ff94bc40SHeiko Schocher 2497ff94bc40SHeiko Schocher } 2498ff94bc40SHeiko Schocher 2499ff94bc40SHeiko Schocher static int power_cut_emulated(struct ubifs_info *c, int lnum, int write) 2500ff94bc40SHeiko Schocher { 2501ff94bc40SHeiko Schocher struct ubifs_debug_info *d = c->dbg; 2502ff94bc40SHeiko Schocher 2503ff94bc40SHeiko Schocher ubifs_assert(dbg_is_tst_rcvry(c)); 2504ff94bc40SHeiko Schocher 2505ff94bc40SHeiko Schocher if (!d->pc_cnt) { 2506ff94bc40SHeiko Schocher /* First call - decide delay to the power cut */ 2507ff94bc40SHeiko Schocher if (chance(1, 2)) { 2508ff94bc40SHeiko Schocher unsigned long delay; 2509ff94bc40SHeiko Schocher 2510ff94bc40SHeiko Schocher if (chance(1, 2)) { 2511ff94bc40SHeiko Schocher d->pc_delay = 1; 2512*0195a7bbSHeiko Schocher /* Fail within 1 minute */ 2513ff94bc40SHeiko Schocher delay = prandom_u32() % 60000; 2514ff94bc40SHeiko Schocher d->pc_timeout = jiffies; 2515ff94bc40SHeiko Schocher d->pc_timeout += msecs_to_jiffies(delay); 2516*0195a7bbSHeiko Schocher ubifs_warn(c, "failing after %lums", delay); 2517ff94bc40SHeiko Schocher } else { 2518ff94bc40SHeiko Schocher d->pc_delay = 2; 2519ff94bc40SHeiko Schocher delay = prandom_u32() % 10000; 2520ff94bc40SHeiko Schocher /* Fail within 10000 operations */ 2521ff94bc40SHeiko Schocher d->pc_cnt_max = delay; 2522*0195a7bbSHeiko Schocher ubifs_warn(c, "failing after %lu calls", delay); 2523ff94bc40SHeiko Schocher } 2524ff94bc40SHeiko Schocher } 2525ff94bc40SHeiko Schocher 2526ff94bc40SHeiko Schocher d->pc_cnt += 1; 2527ff94bc40SHeiko Schocher } 2528ff94bc40SHeiko Schocher 2529ff94bc40SHeiko Schocher /* Determine if failure delay has expired */ 2530ff94bc40SHeiko Schocher if (d->pc_delay == 1 && time_before(jiffies, d->pc_timeout)) 2531ff94bc40SHeiko Schocher return 0; 2532ff94bc40SHeiko Schocher if (d->pc_delay == 2 && d->pc_cnt++ < d->pc_cnt_max) 2533ff94bc40SHeiko Schocher return 0; 2534ff94bc40SHeiko Schocher 2535ff94bc40SHeiko Schocher if (lnum == UBIFS_SB_LNUM) { 2536ff94bc40SHeiko Schocher if (write && chance(1, 2)) 2537ff94bc40SHeiko Schocher return 0; 2538ff94bc40SHeiko Schocher if (chance(19, 20)) 2539ff94bc40SHeiko Schocher return 0; 2540*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in super block LEB %d", lnum); 2541ff94bc40SHeiko Schocher } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) { 2542ff94bc40SHeiko Schocher if (chance(19, 20)) 2543ff94bc40SHeiko Schocher return 0; 2544*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in master LEB %d", lnum); 2545ff94bc40SHeiko Schocher } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) { 2546ff94bc40SHeiko Schocher if (write && chance(99, 100)) 2547ff94bc40SHeiko Schocher return 0; 2548ff94bc40SHeiko Schocher if (chance(399, 400)) 2549ff94bc40SHeiko Schocher return 0; 2550*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in log LEB %d", lnum); 2551ff94bc40SHeiko Schocher } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) { 2552ff94bc40SHeiko Schocher if (write && chance(7, 8)) 2553ff94bc40SHeiko Schocher return 0; 2554ff94bc40SHeiko Schocher if (chance(19, 20)) 2555ff94bc40SHeiko Schocher return 0; 2556*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in LPT LEB %d", lnum); 2557ff94bc40SHeiko Schocher } else if (lnum >= c->orph_first && lnum <= c->orph_last) { 2558ff94bc40SHeiko Schocher if (write && chance(1, 2)) 2559ff94bc40SHeiko Schocher return 0; 2560ff94bc40SHeiko Schocher if (chance(9, 10)) 2561ff94bc40SHeiko Schocher return 0; 2562*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in orphan LEB %d", lnum); 2563ff94bc40SHeiko Schocher } else if (lnum == c->ihead_lnum) { 2564ff94bc40SHeiko Schocher if (chance(99, 100)) 2565ff94bc40SHeiko Schocher return 0; 2566*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in index head LEB %d", lnum); 2567ff94bc40SHeiko Schocher } else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) { 2568ff94bc40SHeiko Schocher if (chance(9, 10)) 2569ff94bc40SHeiko Schocher return 0; 2570*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in GC head LEB %d", lnum); 2571ff94bc40SHeiko Schocher } else if (write && !RB_EMPTY_ROOT(&c->buds) && 2572ff94bc40SHeiko Schocher !ubifs_search_bud(c, lnum)) { 2573ff94bc40SHeiko Schocher if (chance(19, 20)) 2574ff94bc40SHeiko Schocher return 0; 2575*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in non-bud LEB %d", lnum); 2576ff94bc40SHeiko Schocher } else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND || 2577ff94bc40SHeiko Schocher c->cmt_state == COMMIT_RUNNING_REQUIRED) { 2578ff94bc40SHeiko Schocher if (chance(999, 1000)) 2579ff94bc40SHeiko Schocher return 0; 2580*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in bud LEB %d commit running", lnum); 2581ff94bc40SHeiko Schocher } else { 2582ff94bc40SHeiko Schocher if (chance(9999, 10000)) 2583ff94bc40SHeiko Schocher return 0; 2584*0195a7bbSHeiko Schocher ubifs_warn(c, "failing in bud LEB %d commit not running", lnum); 2585ff94bc40SHeiko Schocher } 2586ff94bc40SHeiko Schocher 2587ff94bc40SHeiko Schocher d->pc_happened = 1; 2588*0195a7bbSHeiko Schocher ubifs_warn(c, "========== Power cut emulated =========="); 2589ff94bc40SHeiko Schocher dump_stack(); 2590ff94bc40SHeiko Schocher return 1; 2591ff94bc40SHeiko Schocher } 2592ff94bc40SHeiko Schocher 2593ff94bc40SHeiko Schocher static int corrupt_data(const struct ubifs_info *c, const void *buf, 2594ff94bc40SHeiko Schocher unsigned int len) 2595ff94bc40SHeiko Schocher { 2596ff94bc40SHeiko Schocher unsigned int from, to, ffs = chance(1, 2); 2597ff94bc40SHeiko Schocher unsigned char *p = (void *)buf; 2598ff94bc40SHeiko Schocher 2599ff94bc40SHeiko Schocher from = prandom_u32() % len; 2600ff94bc40SHeiko Schocher /* Corruption span max to end of write unit */ 2601ff94bc40SHeiko Schocher to = min(len, ALIGN(from + 1, c->max_write_size)); 2602ff94bc40SHeiko Schocher 2603*0195a7bbSHeiko Schocher ubifs_warn(c, "filled bytes %u-%u with %s", from, to - 1, 2604ff94bc40SHeiko Schocher ffs ? "0xFFs" : "random data"); 2605ff94bc40SHeiko Schocher 2606ff94bc40SHeiko Schocher if (ffs) 2607ff94bc40SHeiko Schocher memset(p + from, 0xFF, to - from); 2608ff94bc40SHeiko Schocher else 2609ff94bc40SHeiko Schocher prandom_bytes(p + from, to - from); 2610ff94bc40SHeiko Schocher 2611ff94bc40SHeiko Schocher return to; 2612ff94bc40SHeiko Schocher } 2613ff94bc40SHeiko Schocher 2614ff94bc40SHeiko Schocher int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, 2615ff94bc40SHeiko Schocher int offs, int len) 2616ff94bc40SHeiko Schocher { 2617ff94bc40SHeiko Schocher int err, failing; 2618ff94bc40SHeiko Schocher 2619ff94bc40SHeiko Schocher if (c->dbg->pc_happened) 2620ff94bc40SHeiko Schocher return -EROFS; 2621ff94bc40SHeiko Schocher 2622ff94bc40SHeiko Schocher failing = power_cut_emulated(c, lnum, 1); 2623ff94bc40SHeiko Schocher if (failing) { 2624ff94bc40SHeiko Schocher len = corrupt_data(c, buf, len); 2625*0195a7bbSHeiko Schocher ubifs_warn(c, "actually write %d bytes to LEB %d:%d (the buffer was corrupted)", 2626ff94bc40SHeiko Schocher len, lnum, offs); 2627ff94bc40SHeiko Schocher } 2628ff94bc40SHeiko Schocher err = ubi_leb_write(c->ubi, lnum, buf, offs, len); 2629ff94bc40SHeiko Schocher if (err) 2630ff94bc40SHeiko Schocher return err; 2631ff94bc40SHeiko Schocher if (failing) 2632ff94bc40SHeiko Schocher return -EROFS; 2633ff94bc40SHeiko Schocher return 0; 2634ff94bc40SHeiko Schocher } 2635ff94bc40SHeiko Schocher 2636ff94bc40SHeiko Schocher int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, 2637ff94bc40SHeiko Schocher int len) 2638ff94bc40SHeiko Schocher { 2639ff94bc40SHeiko Schocher int err; 2640ff94bc40SHeiko Schocher 2641ff94bc40SHeiko Schocher if (c->dbg->pc_happened) 2642ff94bc40SHeiko Schocher return -EROFS; 2643ff94bc40SHeiko Schocher if (power_cut_emulated(c, lnum, 1)) 2644ff94bc40SHeiko Schocher return -EROFS; 2645ff94bc40SHeiko Schocher err = ubi_leb_change(c->ubi, lnum, buf, len); 2646ff94bc40SHeiko Schocher if (err) 2647ff94bc40SHeiko Schocher return err; 2648ff94bc40SHeiko Schocher if (power_cut_emulated(c, lnum, 1)) 2649ff94bc40SHeiko Schocher return -EROFS; 2650ff94bc40SHeiko Schocher return 0; 2651ff94bc40SHeiko Schocher } 2652ff94bc40SHeiko Schocher 2653ff94bc40SHeiko Schocher int dbg_leb_unmap(struct ubifs_info *c, int lnum) 2654ff94bc40SHeiko Schocher { 2655ff94bc40SHeiko Schocher int err; 2656ff94bc40SHeiko Schocher 2657ff94bc40SHeiko Schocher if (c->dbg->pc_happened) 2658ff94bc40SHeiko Schocher return -EROFS; 2659ff94bc40SHeiko Schocher if (power_cut_emulated(c, lnum, 0)) 2660ff94bc40SHeiko Schocher return -EROFS; 2661ff94bc40SHeiko Schocher err = ubi_leb_unmap(c->ubi, lnum); 2662ff94bc40SHeiko Schocher if (err) 2663ff94bc40SHeiko Schocher return err; 2664ff94bc40SHeiko Schocher if (power_cut_emulated(c, lnum, 0)) 2665ff94bc40SHeiko Schocher return -EROFS; 2666ff94bc40SHeiko Schocher return 0; 2667ff94bc40SHeiko Schocher } 2668ff94bc40SHeiko Schocher 2669ff94bc40SHeiko Schocher int dbg_leb_map(struct ubifs_info *c, int lnum) 2670ff94bc40SHeiko Schocher { 2671ff94bc40SHeiko Schocher int err; 2672ff94bc40SHeiko Schocher 2673ff94bc40SHeiko Schocher if (c->dbg->pc_happened) 2674ff94bc40SHeiko Schocher return -EROFS; 2675ff94bc40SHeiko Schocher if (power_cut_emulated(c, lnum, 0)) 2676ff94bc40SHeiko Schocher return -EROFS; 2677ff94bc40SHeiko Schocher err = ubi_leb_map(c->ubi, lnum); 2678ff94bc40SHeiko Schocher if (err) 2679ff94bc40SHeiko Schocher return err; 2680ff94bc40SHeiko Schocher if (power_cut_emulated(c, lnum, 0)) 2681ff94bc40SHeiko Schocher return -EROFS; 2682ff94bc40SHeiko Schocher return 0; 2683ff94bc40SHeiko Schocher } 2684ff94bc40SHeiko Schocher 2685ff94bc40SHeiko Schocher /* 2686ff94bc40SHeiko Schocher * Root directory for UBIFS stuff in debugfs. Contains sub-directories which 2687ff94bc40SHeiko Schocher * contain the stuff specific to particular file-system mounts. 2688ff94bc40SHeiko Schocher */ 2689ff94bc40SHeiko Schocher static struct dentry *dfs_rootdir; 2690ff94bc40SHeiko Schocher 2691ff94bc40SHeiko Schocher static int dfs_file_open(struct inode *inode, struct file *file) 2692ff94bc40SHeiko Schocher { 2693ff94bc40SHeiko Schocher file->private_data = inode->i_private; 2694ff94bc40SHeiko Schocher return nonseekable_open(inode, file); 2695ff94bc40SHeiko Schocher } 2696ff94bc40SHeiko Schocher 2697ff94bc40SHeiko Schocher /** 2698ff94bc40SHeiko Schocher * provide_user_output - provide output to the user reading a debugfs file. 2699ff94bc40SHeiko Schocher * @val: boolean value for the answer 2700ff94bc40SHeiko Schocher * @u: the buffer to store the answer at 2701ff94bc40SHeiko Schocher * @count: size of the buffer 2702ff94bc40SHeiko Schocher * @ppos: position in the @u output buffer 2703ff94bc40SHeiko Schocher * 2704ff94bc40SHeiko Schocher * This is a simple helper function which stores @val boolean value in the user 2705ff94bc40SHeiko Schocher * buffer when the user reads one of UBIFS debugfs files. Returns amount of 2706ff94bc40SHeiko Schocher * bytes written to @u in case of success and a negative error code in case of 2707ff94bc40SHeiko Schocher * failure. 2708ff94bc40SHeiko Schocher */ 2709ff94bc40SHeiko Schocher static int provide_user_output(int val, char __user *u, size_t count, 2710ff94bc40SHeiko Schocher loff_t *ppos) 2711ff94bc40SHeiko Schocher { 2712ff94bc40SHeiko Schocher char buf[3]; 2713ff94bc40SHeiko Schocher 2714ff94bc40SHeiko Schocher if (val) 2715ff94bc40SHeiko Schocher buf[0] = '1'; 2716ff94bc40SHeiko Schocher else 2717ff94bc40SHeiko Schocher buf[0] = '0'; 2718ff94bc40SHeiko Schocher buf[1] = '\n'; 2719ff94bc40SHeiko Schocher buf[2] = 0x00; 2720ff94bc40SHeiko Schocher 2721ff94bc40SHeiko Schocher return simple_read_from_buffer(u, count, ppos, buf, 2); 2722ff94bc40SHeiko Schocher } 2723ff94bc40SHeiko Schocher 2724ff94bc40SHeiko Schocher static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count, 2725ff94bc40SHeiko Schocher loff_t *ppos) 2726ff94bc40SHeiko Schocher { 2727ff94bc40SHeiko Schocher struct dentry *dent = file->f_path.dentry; 2728ff94bc40SHeiko Schocher struct ubifs_info *c = file->private_data; 2729ff94bc40SHeiko Schocher struct ubifs_debug_info *d = c->dbg; 2730ff94bc40SHeiko Schocher int val; 2731ff94bc40SHeiko Schocher 2732ff94bc40SHeiko Schocher if (dent == d->dfs_chk_gen) 2733ff94bc40SHeiko Schocher val = d->chk_gen; 2734ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_index) 2735ff94bc40SHeiko Schocher val = d->chk_index; 2736ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_orph) 2737ff94bc40SHeiko Schocher val = d->chk_orph; 2738ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_lprops) 2739ff94bc40SHeiko Schocher val = d->chk_lprops; 2740ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_fs) 2741ff94bc40SHeiko Schocher val = d->chk_fs; 2742ff94bc40SHeiko Schocher else if (dent == d->dfs_tst_rcvry) 2743ff94bc40SHeiko Schocher val = d->tst_rcvry; 2744ff94bc40SHeiko Schocher else if (dent == d->dfs_ro_error) 2745ff94bc40SHeiko Schocher val = c->ro_error; 2746ff94bc40SHeiko Schocher else 2747ff94bc40SHeiko Schocher return -EINVAL; 2748ff94bc40SHeiko Schocher 2749ff94bc40SHeiko Schocher return provide_user_output(val, u, count, ppos); 2750ff94bc40SHeiko Schocher } 2751ff94bc40SHeiko Schocher 2752ff94bc40SHeiko Schocher /** 2753ff94bc40SHeiko Schocher * interpret_user_input - interpret user debugfs file input. 2754ff94bc40SHeiko Schocher * @u: user-provided buffer with the input 2755ff94bc40SHeiko Schocher * @count: buffer size 2756ff94bc40SHeiko Schocher * 2757ff94bc40SHeiko Schocher * This is a helper function which interpret user input to a boolean UBIFS 2758ff94bc40SHeiko Schocher * debugfs file. Returns %0 or %1 in case of success and a negative error code 2759ff94bc40SHeiko Schocher * in case of failure. 2760ff94bc40SHeiko Schocher */ 2761ff94bc40SHeiko Schocher static int interpret_user_input(const char __user *u, size_t count) 2762ff94bc40SHeiko Schocher { 2763ff94bc40SHeiko Schocher size_t buf_size; 2764ff94bc40SHeiko Schocher char buf[8]; 2765ff94bc40SHeiko Schocher 2766ff94bc40SHeiko Schocher buf_size = min_t(size_t, count, (sizeof(buf) - 1)); 2767ff94bc40SHeiko Schocher if (copy_from_user(buf, u, buf_size)) 2768ff94bc40SHeiko Schocher return -EFAULT; 2769ff94bc40SHeiko Schocher 2770ff94bc40SHeiko Schocher if (buf[0] == '1') 2771ff94bc40SHeiko Schocher return 1; 2772ff94bc40SHeiko Schocher else if (buf[0] == '0') 2773ff94bc40SHeiko Schocher return 0; 2774ff94bc40SHeiko Schocher 2775ff94bc40SHeiko Schocher return -EINVAL; 2776ff94bc40SHeiko Schocher } 2777ff94bc40SHeiko Schocher 2778ff94bc40SHeiko Schocher static ssize_t dfs_file_write(struct file *file, const char __user *u, 2779ff94bc40SHeiko Schocher size_t count, loff_t *ppos) 2780ff94bc40SHeiko Schocher { 2781ff94bc40SHeiko Schocher struct ubifs_info *c = file->private_data; 2782ff94bc40SHeiko Schocher struct ubifs_debug_info *d = c->dbg; 2783ff94bc40SHeiko Schocher struct dentry *dent = file->f_path.dentry; 2784ff94bc40SHeiko Schocher int val; 2785ff94bc40SHeiko Schocher 2786ff94bc40SHeiko Schocher /* 2787ff94bc40SHeiko Schocher * TODO: this is racy - the file-system might have already been 2788ff94bc40SHeiko Schocher * unmounted and we'd oops in this case. The plan is to fix it with 2789ff94bc40SHeiko Schocher * help of 'iterate_supers_type()' which we should have in v3.0: when 2790ff94bc40SHeiko Schocher * a debugfs opened, we rember FS's UUID in file->private_data. Then 2791ff94bc40SHeiko Schocher * whenever we access the FS via a debugfs file, we iterate all UBIFS 2792ff94bc40SHeiko Schocher * superblocks and fine the one with the same UUID, and take the 2793ff94bc40SHeiko Schocher * locking right. 2794ff94bc40SHeiko Schocher * 2795ff94bc40SHeiko Schocher * The other way to go suggested by Al Viro is to create a separate 2796ff94bc40SHeiko Schocher * 'ubifs-debug' file-system instead. 2797ff94bc40SHeiko Schocher */ 2798ff94bc40SHeiko Schocher if (file->f_path.dentry == d->dfs_dump_lprops) { 2799ff94bc40SHeiko Schocher ubifs_dump_lprops(c); 2800ff94bc40SHeiko Schocher return count; 2801ff94bc40SHeiko Schocher } 2802ff94bc40SHeiko Schocher if (file->f_path.dentry == d->dfs_dump_budg) { 2803ff94bc40SHeiko Schocher ubifs_dump_budg(c, &c->bi); 2804ff94bc40SHeiko Schocher return count; 2805ff94bc40SHeiko Schocher } 2806ff94bc40SHeiko Schocher if (file->f_path.dentry == d->dfs_dump_tnc) { 2807ff94bc40SHeiko Schocher mutex_lock(&c->tnc_mutex); 2808ff94bc40SHeiko Schocher ubifs_dump_tnc(c); 2809ff94bc40SHeiko Schocher mutex_unlock(&c->tnc_mutex); 2810ff94bc40SHeiko Schocher return count; 2811ff94bc40SHeiko Schocher } 2812ff94bc40SHeiko Schocher 2813ff94bc40SHeiko Schocher val = interpret_user_input(u, count); 2814ff94bc40SHeiko Schocher if (val < 0) 2815ff94bc40SHeiko Schocher return val; 2816ff94bc40SHeiko Schocher 2817ff94bc40SHeiko Schocher if (dent == d->dfs_chk_gen) 2818ff94bc40SHeiko Schocher d->chk_gen = val; 2819ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_index) 2820ff94bc40SHeiko Schocher d->chk_index = val; 2821ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_orph) 2822ff94bc40SHeiko Schocher d->chk_orph = val; 2823ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_lprops) 2824ff94bc40SHeiko Schocher d->chk_lprops = val; 2825ff94bc40SHeiko Schocher else if (dent == d->dfs_chk_fs) 2826ff94bc40SHeiko Schocher d->chk_fs = val; 2827ff94bc40SHeiko Schocher else if (dent == d->dfs_tst_rcvry) 2828ff94bc40SHeiko Schocher d->tst_rcvry = val; 2829ff94bc40SHeiko Schocher else if (dent == d->dfs_ro_error) 2830ff94bc40SHeiko Schocher c->ro_error = !!val; 2831ff94bc40SHeiko Schocher else 2832ff94bc40SHeiko Schocher return -EINVAL; 2833ff94bc40SHeiko Schocher 2834ff94bc40SHeiko Schocher return count; 2835ff94bc40SHeiko Schocher } 2836ff94bc40SHeiko Schocher 2837ff94bc40SHeiko Schocher static const struct file_operations dfs_fops = { 2838ff94bc40SHeiko Schocher .open = dfs_file_open, 2839ff94bc40SHeiko Schocher .read = dfs_file_read, 2840ff94bc40SHeiko Schocher .write = dfs_file_write, 2841ff94bc40SHeiko Schocher .owner = THIS_MODULE, 2842ff94bc40SHeiko Schocher .llseek = no_llseek, 2843ff94bc40SHeiko Schocher }; 2844ff94bc40SHeiko Schocher 2845ff94bc40SHeiko Schocher /** 2846ff94bc40SHeiko Schocher * dbg_debugfs_init_fs - initialize debugfs for UBIFS instance. 2847ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2848ff94bc40SHeiko Schocher * 2849ff94bc40SHeiko Schocher * This function creates all debugfs files for this instance of UBIFS. Returns 2850ff94bc40SHeiko Schocher * zero in case of success and a negative error code in case of failure. 2851ff94bc40SHeiko Schocher * 2852ff94bc40SHeiko Schocher * Note, the only reason we have not merged this function with the 2853ff94bc40SHeiko Schocher * 'ubifs_debugging_init()' function is because it is better to initialize 2854ff94bc40SHeiko Schocher * debugfs interfaces at the very end of the mount process, and remove them at 2855ff94bc40SHeiko Schocher * the very beginning of the mount process. 2856ff94bc40SHeiko Schocher */ 2857ff94bc40SHeiko Schocher int dbg_debugfs_init_fs(struct ubifs_info *c) 2858ff94bc40SHeiko Schocher { 2859ff94bc40SHeiko Schocher int err, n; 2860ff94bc40SHeiko Schocher const char *fname; 2861ff94bc40SHeiko Schocher struct dentry *dent; 2862ff94bc40SHeiko Schocher struct ubifs_debug_info *d = c->dbg; 2863ff94bc40SHeiko Schocher 2864ff94bc40SHeiko Schocher if (!IS_ENABLED(CONFIG_DEBUG_FS)) 2865ff94bc40SHeiko Schocher return 0; 2866ff94bc40SHeiko Schocher 2867ff94bc40SHeiko Schocher n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, 2868ff94bc40SHeiko Schocher c->vi.ubi_num, c->vi.vol_id); 2869ff94bc40SHeiko Schocher if (n == UBIFS_DFS_DIR_LEN) { 2870ff94bc40SHeiko Schocher /* The array size is too small */ 2871ff94bc40SHeiko Schocher fname = UBIFS_DFS_DIR_NAME; 2872ff94bc40SHeiko Schocher dent = ERR_PTR(-EINVAL); 2873ff94bc40SHeiko Schocher goto out; 2874ff94bc40SHeiko Schocher } 2875ff94bc40SHeiko Schocher 2876ff94bc40SHeiko Schocher fname = d->dfs_dir_name; 2877ff94bc40SHeiko Schocher dent = debugfs_create_dir(fname, dfs_rootdir); 2878ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2879ff94bc40SHeiko Schocher goto out; 2880ff94bc40SHeiko Schocher d->dfs_dir = dent; 2881ff94bc40SHeiko Schocher 2882ff94bc40SHeiko Schocher fname = "dump_lprops"; 2883ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); 2884ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2885ff94bc40SHeiko Schocher goto out_remove; 2886ff94bc40SHeiko Schocher d->dfs_dump_lprops = dent; 2887ff94bc40SHeiko Schocher 2888ff94bc40SHeiko Schocher fname = "dump_budg"; 2889ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); 2890ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2891ff94bc40SHeiko Schocher goto out_remove; 2892ff94bc40SHeiko Schocher d->dfs_dump_budg = dent; 2893ff94bc40SHeiko Schocher 2894ff94bc40SHeiko Schocher fname = "dump_tnc"; 2895ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); 2896ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2897ff94bc40SHeiko Schocher goto out_remove; 2898ff94bc40SHeiko Schocher d->dfs_dump_tnc = dent; 2899ff94bc40SHeiko Schocher 2900ff94bc40SHeiko Schocher fname = "chk_general"; 2901ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2902ff94bc40SHeiko Schocher &dfs_fops); 2903ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2904ff94bc40SHeiko Schocher goto out_remove; 2905ff94bc40SHeiko Schocher d->dfs_chk_gen = dent; 2906ff94bc40SHeiko Schocher 2907ff94bc40SHeiko Schocher fname = "chk_index"; 2908ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2909ff94bc40SHeiko Schocher &dfs_fops); 2910ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2911ff94bc40SHeiko Schocher goto out_remove; 2912ff94bc40SHeiko Schocher d->dfs_chk_index = dent; 2913ff94bc40SHeiko Schocher 2914ff94bc40SHeiko Schocher fname = "chk_orphans"; 2915ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2916ff94bc40SHeiko Schocher &dfs_fops); 2917ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2918ff94bc40SHeiko Schocher goto out_remove; 2919ff94bc40SHeiko Schocher d->dfs_chk_orph = dent; 2920ff94bc40SHeiko Schocher 2921ff94bc40SHeiko Schocher fname = "chk_lprops"; 2922ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2923ff94bc40SHeiko Schocher &dfs_fops); 2924ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2925ff94bc40SHeiko Schocher goto out_remove; 2926ff94bc40SHeiko Schocher d->dfs_chk_lprops = dent; 2927ff94bc40SHeiko Schocher 2928ff94bc40SHeiko Schocher fname = "chk_fs"; 2929ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2930ff94bc40SHeiko Schocher &dfs_fops); 2931ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2932ff94bc40SHeiko Schocher goto out_remove; 2933ff94bc40SHeiko Schocher d->dfs_chk_fs = dent; 2934ff94bc40SHeiko Schocher 2935ff94bc40SHeiko Schocher fname = "tst_recovery"; 2936ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2937ff94bc40SHeiko Schocher &dfs_fops); 2938ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2939ff94bc40SHeiko Schocher goto out_remove; 2940ff94bc40SHeiko Schocher d->dfs_tst_rcvry = dent; 2941ff94bc40SHeiko Schocher 2942ff94bc40SHeiko Schocher fname = "ro_error"; 2943ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, 2944ff94bc40SHeiko Schocher &dfs_fops); 2945ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 2946ff94bc40SHeiko Schocher goto out_remove; 2947ff94bc40SHeiko Schocher d->dfs_ro_error = dent; 2948ff94bc40SHeiko Schocher 2949ff94bc40SHeiko Schocher return 0; 2950ff94bc40SHeiko Schocher 2951ff94bc40SHeiko Schocher out_remove: 2952ff94bc40SHeiko Schocher debugfs_remove_recursive(d->dfs_dir); 2953ff94bc40SHeiko Schocher out: 2954ff94bc40SHeiko Schocher err = dent ? PTR_ERR(dent) : -ENODEV; 2955*0195a7bbSHeiko Schocher ubifs_err(c, "cannot create \"%s\" debugfs file or directory, error %d\n", 2956ff94bc40SHeiko Schocher fname, err); 2957ff94bc40SHeiko Schocher return err; 2958ff94bc40SHeiko Schocher } 2959ff94bc40SHeiko Schocher 2960ff94bc40SHeiko Schocher /** 2961ff94bc40SHeiko Schocher * dbg_debugfs_exit_fs - remove all debugfs files. 2962ff94bc40SHeiko Schocher * @c: UBIFS file-system description object 2963ff94bc40SHeiko Schocher */ 2964ff94bc40SHeiko Schocher void dbg_debugfs_exit_fs(struct ubifs_info *c) 2965ff94bc40SHeiko Schocher { 2966ff94bc40SHeiko Schocher if (IS_ENABLED(CONFIG_DEBUG_FS)) 2967ff94bc40SHeiko Schocher debugfs_remove_recursive(c->dbg->dfs_dir); 2968ff94bc40SHeiko Schocher } 2969ff94bc40SHeiko Schocher 2970ff94bc40SHeiko Schocher struct ubifs_global_debug_info ubifs_dbg; 2971ff94bc40SHeiko Schocher 2972ff94bc40SHeiko Schocher static struct dentry *dfs_chk_gen; 2973ff94bc40SHeiko Schocher static struct dentry *dfs_chk_index; 2974ff94bc40SHeiko Schocher static struct dentry *dfs_chk_orph; 2975ff94bc40SHeiko Schocher static struct dentry *dfs_chk_lprops; 2976ff94bc40SHeiko Schocher static struct dentry *dfs_chk_fs; 2977ff94bc40SHeiko Schocher static struct dentry *dfs_tst_rcvry; 2978ff94bc40SHeiko Schocher 2979ff94bc40SHeiko Schocher static ssize_t dfs_global_file_read(struct file *file, char __user *u, 2980ff94bc40SHeiko Schocher size_t count, loff_t *ppos) 2981ff94bc40SHeiko Schocher { 2982ff94bc40SHeiko Schocher struct dentry *dent = file->f_path.dentry; 2983ff94bc40SHeiko Schocher int val; 2984ff94bc40SHeiko Schocher 2985ff94bc40SHeiko Schocher if (dent == dfs_chk_gen) 2986ff94bc40SHeiko Schocher val = ubifs_dbg.chk_gen; 2987ff94bc40SHeiko Schocher else if (dent == dfs_chk_index) 2988ff94bc40SHeiko Schocher val = ubifs_dbg.chk_index; 2989ff94bc40SHeiko Schocher else if (dent == dfs_chk_orph) 2990ff94bc40SHeiko Schocher val = ubifs_dbg.chk_orph; 2991ff94bc40SHeiko Schocher else if (dent == dfs_chk_lprops) 2992ff94bc40SHeiko Schocher val = ubifs_dbg.chk_lprops; 2993ff94bc40SHeiko Schocher else if (dent == dfs_chk_fs) 2994ff94bc40SHeiko Schocher val = ubifs_dbg.chk_fs; 2995ff94bc40SHeiko Schocher else if (dent == dfs_tst_rcvry) 2996ff94bc40SHeiko Schocher val = ubifs_dbg.tst_rcvry; 2997ff94bc40SHeiko Schocher else 2998ff94bc40SHeiko Schocher return -EINVAL; 2999ff94bc40SHeiko Schocher 3000ff94bc40SHeiko Schocher return provide_user_output(val, u, count, ppos); 3001ff94bc40SHeiko Schocher } 3002ff94bc40SHeiko Schocher 3003ff94bc40SHeiko Schocher static ssize_t dfs_global_file_write(struct file *file, const char __user *u, 3004ff94bc40SHeiko Schocher size_t count, loff_t *ppos) 3005ff94bc40SHeiko Schocher { 3006ff94bc40SHeiko Schocher struct dentry *dent = file->f_path.dentry; 3007ff94bc40SHeiko Schocher int val; 3008ff94bc40SHeiko Schocher 3009ff94bc40SHeiko Schocher val = interpret_user_input(u, count); 3010ff94bc40SHeiko Schocher if (val < 0) 3011ff94bc40SHeiko Schocher return val; 3012ff94bc40SHeiko Schocher 3013ff94bc40SHeiko Schocher if (dent == dfs_chk_gen) 3014ff94bc40SHeiko Schocher ubifs_dbg.chk_gen = val; 3015ff94bc40SHeiko Schocher else if (dent == dfs_chk_index) 3016ff94bc40SHeiko Schocher ubifs_dbg.chk_index = val; 3017ff94bc40SHeiko Schocher else if (dent == dfs_chk_orph) 3018ff94bc40SHeiko Schocher ubifs_dbg.chk_orph = val; 3019ff94bc40SHeiko Schocher else if (dent == dfs_chk_lprops) 3020ff94bc40SHeiko Schocher ubifs_dbg.chk_lprops = val; 3021ff94bc40SHeiko Schocher else if (dent == dfs_chk_fs) 3022ff94bc40SHeiko Schocher ubifs_dbg.chk_fs = val; 3023ff94bc40SHeiko Schocher else if (dent == dfs_tst_rcvry) 3024ff94bc40SHeiko Schocher ubifs_dbg.tst_rcvry = val; 3025ff94bc40SHeiko Schocher else 3026ff94bc40SHeiko Schocher return -EINVAL; 3027ff94bc40SHeiko Schocher 3028ff94bc40SHeiko Schocher return count; 3029ff94bc40SHeiko Schocher } 3030ff94bc40SHeiko Schocher 3031ff94bc40SHeiko Schocher static const struct file_operations dfs_global_fops = { 3032ff94bc40SHeiko Schocher .read = dfs_global_file_read, 3033ff94bc40SHeiko Schocher .write = dfs_global_file_write, 3034ff94bc40SHeiko Schocher .owner = THIS_MODULE, 3035ff94bc40SHeiko Schocher .llseek = no_llseek, 3036ff94bc40SHeiko Schocher }; 3037ff94bc40SHeiko Schocher 3038ff94bc40SHeiko Schocher /** 3039ff94bc40SHeiko Schocher * dbg_debugfs_init - initialize debugfs file-system. 3040ff94bc40SHeiko Schocher * 3041ff94bc40SHeiko Schocher * UBIFS uses debugfs file-system to expose various debugging knobs to 3042ff94bc40SHeiko Schocher * user-space. This function creates "ubifs" directory in the debugfs 3043ff94bc40SHeiko Schocher * file-system. Returns zero in case of success and a negative error code in 3044ff94bc40SHeiko Schocher * case of failure. 3045ff94bc40SHeiko Schocher */ 3046ff94bc40SHeiko Schocher int dbg_debugfs_init(void) 3047ff94bc40SHeiko Schocher { 3048ff94bc40SHeiko Schocher int err; 3049ff94bc40SHeiko Schocher const char *fname; 3050ff94bc40SHeiko Schocher struct dentry *dent; 3051ff94bc40SHeiko Schocher 3052ff94bc40SHeiko Schocher if (!IS_ENABLED(CONFIG_DEBUG_FS)) 3053ff94bc40SHeiko Schocher return 0; 3054ff94bc40SHeiko Schocher 3055ff94bc40SHeiko Schocher fname = "ubifs"; 3056ff94bc40SHeiko Schocher dent = debugfs_create_dir(fname, NULL); 3057ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3058ff94bc40SHeiko Schocher goto out; 3059ff94bc40SHeiko Schocher dfs_rootdir = dent; 3060ff94bc40SHeiko Schocher 3061ff94bc40SHeiko Schocher fname = "chk_general"; 3062ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, 3063ff94bc40SHeiko Schocher &dfs_global_fops); 3064ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3065ff94bc40SHeiko Schocher goto out_remove; 3066ff94bc40SHeiko Schocher dfs_chk_gen = dent; 3067ff94bc40SHeiko Schocher 3068ff94bc40SHeiko Schocher fname = "chk_index"; 3069ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, 3070ff94bc40SHeiko Schocher &dfs_global_fops); 3071ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3072ff94bc40SHeiko Schocher goto out_remove; 3073ff94bc40SHeiko Schocher dfs_chk_index = dent; 3074ff94bc40SHeiko Schocher 3075ff94bc40SHeiko Schocher fname = "chk_orphans"; 3076ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, 3077ff94bc40SHeiko Schocher &dfs_global_fops); 3078ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3079ff94bc40SHeiko Schocher goto out_remove; 3080ff94bc40SHeiko Schocher dfs_chk_orph = dent; 3081ff94bc40SHeiko Schocher 3082ff94bc40SHeiko Schocher fname = "chk_lprops"; 3083ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, 3084ff94bc40SHeiko Schocher &dfs_global_fops); 3085ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3086ff94bc40SHeiko Schocher goto out_remove; 3087ff94bc40SHeiko Schocher dfs_chk_lprops = dent; 3088ff94bc40SHeiko Schocher 3089ff94bc40SHeiko Schocher fname = "chk_fs"; 3090ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, 3091ff94bc40SHeiko Schocher &dfs_global_fops); 3092ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3093ff94bc40SHeiko Schocher goto out_remove; 3094ff94bc40SHeiko Schocher dfs_chk_fs = dent; 3095ff94bc40SHeiko Schocher 3096ff94bc40SHeiko Schocher fname = "tst_recovery"; 3097ff94bc40SHeiko Schocher dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, 3098ff94bc40SHeiko Schocher &dfs_global_fops); 3099ff94bc40SHeiko Schocher if (IS_ERR_OR_NULL(dent)) 3100ff94bc40SHeiko Schocher goto out_remove; 3101ff94bc40SHeiko Schocher dfs_tst_rcvry = dent; 3102ff94bc40SHeiko Schocher 3103ff94bc40SHeiko Schocher return 0; 3104ff94bc40SHeiko Schocher 3105ff94bc40SHeiko Schocher out_remove: 3106ff94bc40SHeiko Schocher debugfs_remove_recursive(dfs_rootdir); 3107ff94bc40SHeiko Schocher out: 3108ff94bc40SHeiko Schocher err = dent ? PTR_ERR(dent) : -ENODEV; 3109*0195a7bbSHeiko Schocher pr_err("UBIFS error (pid %d): cannot create \"%s\" debugfs file or directory, error %d\n", 3110*0195a7bbSHeiko Schocher current->pid, fname, err); 3111ff94bc40SHeiko Schocher return err; 3112ff94bc40SHeiko Schocher } 3113ff94bc40SHeiko Schocher 3114ff94bc40SHeiko Schocher /** 3115ff94bc40SHeiko Schocher * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system. 3116ff94bc40SHeiko Schocher */ 3117ff94bc40SHeiko Schocher void dbg_debugfs_exit(void) 3118ff94bc40SHeiko Schocher { 3119ff94bc40SHeiko Schocher if (IS_ENABLED(CONFIG_DEBUG_FS)) 3120ff94bc40SHeiko Schocher debugfs_remove_recursive(dfs_rootdir); 31219eefe2a2SStefan Roese } 31229eefe2a2SStefan Roese 31239eefe2a2SStefan Roese /** 31249eefe2a2SStefan Roese * ubifs_debugging_init - initialize UBIFS debugging. 31259eefe2a2SStefan Roese * @c: UBIFS file-system description object 31269eefe2a2SStefan Roese * 31279eefe2a2SStefan Roese * This function initializes debugging-related data for the file system. 31289eefe2a2SStefan Roese * Returns zero in case of success and a negative error code in case of 31299eefe2a2SStefan Roese * failure. 31309eefe2a2SStefan Roese */ 31319eefe2a2SStefan Roese int ubifs_debugging_init(struct ubifs_info *c) 31329eefe2a2SStefan Roese { 31339eefe2a2SStefan Roese c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL); 31349eefe2a2SStefan Roese if (!c->dbg) 31359eefe2a2SStefan Roese return -ENOMEM; 31369eefe2a2SStefan Roese 31379eefe2a2SStefan Roese return 0; 31389eefe2a2SStefan Roese } 31399eefe2a2SStefan Roese 31409eefe2a2SStefan Roese /** 31419eefe2a2SStefan Roese * ubifs_debugging_exit - free debugging data. 31429eefe2a2SStefan Roese * @c: UBIFS file-system description object 31439eefe2a2SStefan Roese */ 31449eefe2a2SStefan Roese void ubifs_debugging_exit(struct ubifs_info *c) 31459eefe2a2SStefan Roese { 31469eefe2a2SStefan Roese kfree(c->dbg); 31479eefe2a2SStefan Roese } 3148ff94bc40SHeiko Schocher #endif 3149