157 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * 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 */
 |