| /* | |
| * This file is part of UBIFS. | |
| * | |
| * Copyright (C) 2006-2008 Nokia Corporation | |
| * | |
| * This program is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 as published by | |
| * the Free Software Foundation. | |
| * | |
| * This program is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| * more details. | |
| * | |
| * You should have received a copy of the GNU General Public License along with | |
| * this program; if not, write to the Free Software Foundation, Inc., 51 | |
| * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| * | |
| * Authors: Artem Bityutskiy (Битюцкий Артём) | |
| * Adrian Hunter | |
| */ | |
| /* | |
| * This file implements most of the debugging stuff which is compiled in only | |
| * when it is enabled. But some debugging check functions are implemented in | |
| * corresponding subsystem, just because they are closely related and utilize | |
| * various local functions of those subsystems. | |
| */ | |
| #define UBIFS_DBG_PRESERVE_UBI | |
| #include "ubifs.h" | |
| #ifdef CONFIG_UBIFS_FS_DEBUG | |
| DEFINE_SPINLOCK(dbg_lock); | |
| static char dbg_key_buf0[128]; | |
| static char dbg_key_buf1[128]; | |
| unsigned int ubifs_msg_flags = UBIFS_MSG_FLAGS_DEFAULT; | |
| unsigned int ubifs_chk_flags = UBIFS_CHK_FLAGS_DEFAULT; | |
| unsigned int ubifs_tst_flags; | |
| module_param_named(debug_msgs, ubifs_msg_flags, uint, S_IRUGO | S_IWUSR); | |
| module_param_named(debug_chks, ubifs_chk_flags, uint, S_IRUGO | S_IWUSR); | |
| module_param_named(debug_tsts, ubifs_tst_flags, uint, S_IRUGO | S_IWUSR); | |
| MODULE_PARM_DESC(debug_msgs, "Debug message type flags"); | |
| MODULE_PARM_DESC(debug_chks, "Debug check flags"); | |
| MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); | |
| static const char *get_key_type(int type) | |
| { | |
| switch (type) { | |
| case UBIFS_INO_KEY: | |
| return "inode"; | |
| case UBIFS_DENT_KEY: | |
| return "direntry"; | |
| case UBIFS_XENT_KEY: | |
| return "xentry"; | |
| case UBIFS_DATA_KEY: | |
| return "data"; | |
| case UBIFS_TRUN_KEY: | |
| return "truncate"; | |
| default: | |
| return "unknown/invalid key"; | |
| } | |
| } | |
| static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key, | |
| char *buffer) | |
| { | |
| char *p = buffer; | |
| int type = key_type(c, key); | |
| if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) { | |
| switch (type) { | |
| case UBIFS_INO_KEY: | |
| sprintf(p, "(%lu, %s)", (unsigned long)key_inum(c, key), | |
| get_key_type(type)); | |
| break; | |
| case UBIFS_DENT_KEY: | |
| case UBIFS_XENT_KEY: | |
| sprintf(p, "(%lu, %s, %#08x)", | |
| (unsigned long)key_inum(c, key), | |
| get_key_type(type), key_hash(c, key)); | |
| break; | |
| case UBIFS_DATA_KEY: | |
| sprintf(p, "(%lu, %s, %u)", | |
| (unsigned long)key_inum(c, key), | |
| get_key_type(type), key_block(c, key)); | |
| break; | |
| case UBIFS_TRUN_KEY: | |
| sprintf(p, "(%lu, %s)", | |
| (unsigned long)key_inum(c, key), | |
| get_key_type(type)); | |
| break; | |
| default: | |
| sprintf(p, "(bad key type: %#08x, %#08x)", | |
| key->u32[0], key->u32[1]); | |
| } | |
| } else | |
| sprintf(p, "bad key format %d", c->key_fmt); | |
| } | |
| const char *dbg_key_str0(const struct ubifs_info *c, const union ubifs_key *key) | |
| { | |
| /* dbg_lock must be held */ | |
| sprintf_key(c, key, dbg_key_buf0); | |
| return dbg_key_buf0; | |
| } | |
| const char *dbg_key_str1(const struct ubifs_info *c, const union ubifs_key *key) | |
| { | |
| /* dbg_lock must be held */ | |
| sprintf_key(c, key, dbg_key_buf1); | |
| return dbg_key_buf1; | |
| } | |
| /** | |
| * ubifs_debugging_init - initialize UBIFS debugging. | |
| * @c: UBIFS file-system description object | |
| * | |
| * This function initializes debugging-related data for the file system. | |
| * Returns zero in case of success and a negative error code in case of | |
| * failure. | |
| */ | |
| int ubifs_debugging_init(struct ubifs_info *c) | |
| { | |
| c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL); | |
| if (!c->dbg) | |
| return -ENOMEM; | |
| c->dbg->buf = vmalloc(c->leb_size); | |
| if (!c->dbg->buf) | |
| goto out; | |
| return 0; | |
| out: | |
| kfree(c->dbg); | |
| return -ENOMEM; | |
| } | |
| /** | |
| * ubifs_debugging_exit - free debugging data. | |
| * @c: UBIFS file-system description object | |
| */ | |
| void ubifs_debugging_exit(struct ubifs_info *c) | |
| { | |
| vfree(c->dbg->buf); | |
| kfree(c->dbg); | |
| } | |
| #endif /* CONFIG_UBIFS_FS_DEBUG */ |