blob: 6afb8835a58e480e92f977bda8725dfd77154a77 [file] [log] [blame]
/*
* 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 */