blob: abb08a80d888366b74a4caf3c45c571066724c45 [file] [log] [blame]
/*
* Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would 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 the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libxfs.h"
#include "block.h"
#include "command.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "print.h"
#include "sb.h"
#include "inode.h"
#include "btblock.h"
#include "bmroot.h"
#include "agf.h"
#include "agfl.h"
#include "agi.h"
#include "io.h"
#include "output.h"
#include "write.h"
#include "attr.h"
#include "dquot.h"
#include "dir2.h"
#include "text.h"
#include "symlink.h"
#include "fuzz.h"
static const typ_t *findtyp(char *name);
static int type_f(int argc, char **argv);
const typ_t *cur_typ;
static const cmdinfo_t type_cmd =
{ "type", NULL, type_f, 0, 1, 1, N_("[newtype]"),
N_("set/show current data type"), NULL };
static const typ_t __typtab[] = {
{ TYP_AGF, "agf", handle_struct, agf_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_AGFL, "agfl", handle_struct, agfl_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_AGI, "agi", handle_struct, agi_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_ATTR, "attr", handle_struct, attr_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_hfld, NULL,
TYP_F_NO_CRC_OFF },
{ TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_hfld, NULL,
TYP_F_NO_CRC_OFF },
{ TYP_BNOBT, "bnobt", handle_struct, bnobt_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_CNTBT, "cntbt", handle_struct, cntbt_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RMAPBT, NULL },
{ TYP_REFCBT, NULL },
{ TYP_DATA, "data", handle_block, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_DIR2, "dir2", handle_struct, dir2_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_INOBT, "inobt", handle_struct, inobt_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_INODATA, "inodata", NULL, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_INODE, "inode", handle_struct, inode_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_LOG, "log", NULL, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RTBITMAP, "rtbitmap", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RTSUMMARY, "rtsummary", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_SB, "sb", handle_struct, sb_hfld, NULL, TYP_F_NO_CRC_OFF },
{ TYP_SYMLINK, "symlink", handle_string, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_TEXT, "text", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_FINOBT, "finobt", handle_struct, inobt_hfld, NULL,
TYP_F_NO_CRC_OFF },
{ TYP_NONE, NULL }
};
static const typ_t __typtab_crc[] = {
{ TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops,
XFS_AGF_CRC_OFF },
{ TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops,
XFS_AGFL_CRC_OFF },
{ TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops,
XFS_AGI_CRC_OFF },
{ TYP_ATTR, "attr3", handle_struct, attr3_hfld,
&xfs_attr3_db_buf_ops, TYP_F_CRC_FUNC, xfs_attr3_set_crc },
{ TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld,
&xfs_bmbt_buf_ops, XFS_BTREE_LBLOCK_CRC_OFF },
{ TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_crc_hfld,
&xfs_bmbt_buf_ops, XFS_BTREE_LBLOCK_CRC_OFF },
{ TYP_BNOBT, "bnobt", handle_struct, bnobt_crc_hfld,
&xfs_allocbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_CNTBT, "cntbt", handle_struct, cntbt_crc_hfld,
&xfs_allocbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_RMAPBT, "rmapbt", handle_struct, rmapbt_crc_hfld,
&xfs_rmapbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_REFCBT, "refcntbt", handle_struct, refcbt_crc_hfld,
&xfs_refcountbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_DATA, "data", handle_block, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_DIR2, "dir3", handle_struct, dir3_hfld,
&xfs_dir3_db_buf_ops, TYP_F_CRC_FUNC, xfs_dir3_set_crc },
{ TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld,
&xfs_dquot_buf_ops, TYP_F_CRC_FUNC, xfs_dquot_set_crc },
{ TYP_INOBT, "inobt", handle_struct, inobt_crc_hfld,
&xfs_inobt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_INODATA, "inodata", NULL, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_INODE, "inode", handle_struct, inode_crc_hfld,
&xfs_inode_buf_ops, TYP_F_CRC_FUNC, xfs_inode_set_crc },
{ TYP_LOG, "log", NULL, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RTBITMAP, "rtbitmap", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RTSUMMARY, "rtsummary", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_SB, "sb", handle_struct, sb_hfld, &xfs_sb_buf_ops,
XFS_SB_CRC_OFF },
{ TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld,
&xfs_symlink_buf_ops, XFS_SYMLINK_CRC_OFF },
{ TYP_TEXT, "text", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_FINOBT, "finobt", handle_struct, inobt_crc_hfld,
&xfs_inobt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_NONE, NULL }
};
static const typ_t __typtab_spcrc[] = {
{ TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops,
XFS_AGF_CRC_OFF },
{ TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops ,
XFS_AGFL_CRC_OFF },
{ TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops ,
XFS_AGI_CRC_OFF },
{ TYP_ATTR, "attr3", handle_struct, attr3_hfld,
&xfs_attr3_db_buf_ops, TYP_F_CRC_FUNC, xfs_attr3_set_crc },
{ TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld,
&xfs_bmbt_buf_ops, XFS_BTREE_LBLOCK_CRC_OFF },
{ TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_crc_hfld,
&xfs_bmbt_buf_ops, XFS_BTREE_LBLOCK_CRC_OFF },
{ TYP_BNOBT, "bnobt", handle_struct, bnobt_crc_hfld,
&xfs_allocbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_CNTBT, "cntbt", handle_struct, cntbt_crc_hfld,
&xfs_allocbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_RMAPBT, "rmapbt", handle_struct, rmapbt_crc_hfld,
&xfs_rmapbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_REFCBT, "refcntbt", handle_struct, refcbt_crc_hfld,
&xfs_refcountbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_DATA, "data", handle_block, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_DIR2, "dir3", handle_struct, dir3_hfld,
&xfs_dir3_db_buf_ops, TYP_F_CRC_FUNC, xfs_dir3_set_crc },
{ TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld,
&xfs_dquot_buf_ops, TYP_F_CRC_FUNC, xfs_dquot_set_crc },
{ TYP_INOBT, "inobt", handle_struct, inobt_spcrc_hfld,
&xfs_inobt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_INODATA, "inodata", NULL, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_INODE, "inode", handle_struct, inode_crc_hfld,
&xfs_inode_buf_ops, TYP_F_CRC_FUNC, xfs_inode_set_crc },
{ TYP_LOG, "log", NULL, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RTBITMAP, "rtbitmap", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_RTSUMMARY, "rtsummary", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_SB, "sb", handle_struct, sb_hfld, &xfs_sb_buf_ops,
XFS_SB_CRC_OFF },
{ TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld,
&xfs_symlink_buf_ops, XFS_SYMLINK_CRC_OFF },
{ TYP_TEXT, "text", handle_text, NULL, NULL, TYP_F_NO_CRC_OFF },
{ TYP_FINOBT, "finobt", handle_struct, inobt_crc_hfld,
&xfs_inobt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
{ TYP_NONE, NULL }
};
const typ_t *typtab = __typtab;
void
type_set_tab_crc(void)
{
typtab = __typtab_crc;
}
void
type_set_tab_spcrc(void)
{
typtab = __typtab_spcrc;
}
static const typ_t *
findtyp(
char *name)
{
const typ_t *tt;
for (tt = typtab; tt->typnm != TYP_NONE; tt++) {
ASSERT(tt->typnm == (typnm_t)(tt - typtab));
if (tt->name && strcmp(tt->name, name) == 0)
return tt;
}
return NULL;
}
static int
type_f(
int argc,
char **argv)
{
const typ_t *tt;
int count = 0;
if (argc == 1) {
if (cur_typ == NULL)
dbprintf(_("no current type\n"));
else
dbprintf(_("current type is \"%s\"\n"), cur_typ->name);
dbprintf(_("\n supported types are:\n "));
for (tt = typtab, count = 0; tt->typnm != TYP_NONE; tt++) {
if (tt->name == NULL)
continue;
if ((tt+1)->name != NULL) {
dbprintf("%s, ", tt->name);
if ((++count % 8) == 0)
dbprintf("\n ");
} else if ((tt+1)->typnm == TYP_NONE) {
dbprintf("%s\n", tt->name);
}
}
} else {
tt = findtyp(argv[1]);
if (tt == NULL) {
dbprintf(_("no such type %s\n"), argv[1]);
} else {
if (iocur_top->typ == NULL)
dbprintf(_("no current object\n"));
else {
cur_typ = tt;
set_iocur_type(tt);
}
}
}
return 0;
}
void
type_init(void)
{
add_command(&type_cmd);
}
/* read/write selectors for each major data type */
void
handle_struct(
int action,
const field_t *fields,
int argc,
char **argv)
{
switch (action) {
case DB_FUZZ:
fuzz_struct(fields, argc, argv);
break;
case DB_WRITE:
write_struct(fields, argc, argv);
break;
case DB_READ:
print_struct(fields, argc, argv);
break;
}
}
void
handle_string(
int action,
const field_t *fields,
int argc,
char **argv)
{
switch (action) {
case DB_WRITE:
write_string(fields, argc, argv);
break;
case DB_READ:
print_string(fields, argc, argv);
break;
case DB_FUZZ:
dbprintf(_("string fuzzing not supported.\n"));
break;
}
}
void
handle_block(
int action,
const field_t *fields,
int argc,
char **argv)
{
switch (action) {
case DB_WRITE:
write_block(fields, argc, argv);
break;
case DB_READ:
print_block(fields, argc, argv);
break;
case DB_FUZZ:
dbprintf(_("use 'blocktrash' or 'write' to fuzz a block.\n"));
break;
}
}
void
handle_text(
int action,
const field_t *fields,
int argc,
char **argv)
{
switch (action) {
case DB_FUZZ:
/* fall through */
case DB_WRITE:
dbprintf(_("text writing/fuzzing not supported.\n"));
break;
case DB_READ:
print_text(fields, argc, argv);
break;
}
}