| /* | 
 |  * 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 */ |