Imported reiserfsprogs-3.6.2
This commit is contained in:
1 parent
e7102bdb66
commit
b69459eb80
86 files changed
+23136
-13423
No files matched your search
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*/
|
||||
|
||||
#include "debugreiserfs.h"
|
||||
|
||||
|
||||
static int str2int (char * str, int * res)
|
||||
{
|
||||
int val;
|
||||
char * tmp;
|
||||
|
||||
val = (int) strtol (str, &tmp, 0);
|
||||
if (tmp == str)
|
||||
/* could not convert string into a number */
|
||||
return 0;
|
||||
*res = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void edit_journal_params (struct journal_params * jp)
|
||||
{
|
||||
char * str;
|
||||
size_t n;
|
||||
int num;
|
||||
|
||||
printf ("Journal parameters:\n");
|
||||
printf ("\tDevice: current: %x: new:", get_jp_journal_dev (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_dev (jp, num);
|
||||
|
||||
printf ("\tFirst block: current: %d: new:",
|
||||
get_jp_journal_1st_block (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_1st_block (jp, num);
|
||||
|
||||
printf ("\tSize: current: %d: new:", get_jp_journal_size (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_size (jp, num);
|
||||
|
||||
printf ("\tMagic number: current: %d: new:", get_jp_journal_magic (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_magic (jp, num);
|
||||
|
||||
printf ("\tMax transaction size: current: %d: new:",
|
||||
get_jp_journal_max_trans_len (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_max_trans_len (jp, num);
|
||||
|
||||
printf ("\tMax batch size: current: %d: new:",
|
||||
get_jp_journal_max_batch (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_max_batch (jp, num);
|
||||
|
||||
printf ("\tMax commit age: current: %d: new:",
|
||||
get_jp_journal_max_commit_age (jp));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_jp_journal_max_commit_age (jp, num);
|
||||
}
|
||||
|
||||
|
||||
/* this allows to edit all super block fields */
|
||||
static void edit_super_block (reiserfs_filsys_t * fs)
|
||||
{
|
||||
char * str;
|
||||
size_t n;
|
||||
int num;
|
||||
|
||||
|
||||
str = 0;
|
||||
n = 0;
|
||||
|
||||
/* bs_block_count */
|
||||
printf ("\tBlock count: current: %u: new:",
|
||||
get_sb_block_count (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_block_count (fs->fs_ondisk_sb, num);
|
||||
|
||||
|
||||
/* sb_free_blocks */
|
||||
printf ("\tFree block count: current: %u: new:",
|
||||
get_sb_free_blocks (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_free_blocks (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* sb_root_block */
|
||||
printf ("\tRoot block: current: %u: new:",
|
||||
get_sb_root_block (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_root_block (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* sb_journal */
|
||||
edit_journal_params (sb_jp (fs->fs_ondisk_sb));
|
||||
|
||||
/* sb_blocksize */
|
||||
printf ("\tBlocksize: current: %u: new:",
|
||||
get_sb_block_size (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_block_size (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* sb_oid_maxsize */
|
||||
printf ("\tMax objectid size: current: %u: new:",
|
||||
get_sb_oid_maxsize (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_oid_maxsize (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* sb_oid_cursize */
|
||||
printf ("\tCur objectid size: current: %u: new:",
|
||||
get_sb_oid_cursize (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_oid_cursize (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* sb_state */
|
||||
printf ("\tUmount state: current: %u: new:",
|
||||
get_sb_umount_state (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_umount_state (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* char s_magic [10]; */
|
||||
printf ("\tMagic: current: \"%s\": new:", fs->fs_ondisk_sb->s_v1.s_magic);
|
||||
getline (&str, &n, stdin);
|
||||
if (strcmp (str, "\n"))
|
||||
strncpy (fs->fs_ondisk_sb->s_v1.s_magic, str, n > 10 ? 10 : n);
|
||||
|
||||
/* __u16 sb_fsck_state; */
|
||||
printf ("\tFielsystem state: current: %u: new:", get_sb_fs_state (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_fs_state (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* __u32 sb_hash_function_code; */
|
||||
printf ("\tHash code: current: %u: new (tea %d, r5 %d, rupasov %d):",
|
||||
get_sb_hash_code (fs->fs_ondisk_sb), TEA_HASH, R5_HASH, YURA_HASH);
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_hash_code (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* __u16 sb_tree_height; */
|
||||
printf ("\tTree height: current: %u: new:",
|
||||
get_sb_tree_height (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_tree_height (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* __u16 sb_bmap_nr; */
|
||||
printf ("\tNumber of bitmaps: current: %u: new:",
|
||||
get_sb_bmap_nr (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_bmap_nr (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* __u16 sb_version; */
|
||||
printf ("\tFilesystem format: current: %u: new:",
|
||||
le16_to_cpu (fs->fs_ondisk_sb->s_v1.sb_version));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_version (fs->fs_ondisk_sb, num);
|
||||
|
||||
/* __u16 sb_reserved_for_journal; */
|
||||
printf ("\tSpace reserved for journal: current: %u: new:",
|
||||
get_sb_reserved_for_journal (fs->fs_ondisk_sb));
|
||||
getline (&str, &n, stdin);
|
||||
if (str2int (str, &num))
|
||||
set_sb_reserved_for_journal (fs->fs_ondisk_sb, num);
|
||||
|
||||
|
||||
print_block (stdout, fs, fs->fs_super_bh);
|
||||
if (user_confirmed (stderr, "Is this ok ? [N/Yes]: ", "Yes\n")) {
|
||||
mark_buffer_dirty (fs->fs_super_bh);
|
||||
bwrite (fs->fs_super_bh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void corrupt_clobber_hash (char * name, struct item_head * ih,
|
||||
struct reiserfs_de_head * deh)
|
||||
{
|
||||
printf ("\tCorrupting deh_offset of entry \"%s\" of [%u %u]\n", name,
|
||||
get_key_dirid (&ih->ih_key), get_key_objectid (&ih->ih_key));
|
||||
set_deh_offset (deh, 700);
|
||||
}
|
||||
|
||||
|
||||
/* this reads list of desired corruptions from stdin and perform the
|
||||
corruptions. Format of that list:
|
||||
A hash_code
|
||||
C name objectid - 'C'ut entry 'name' from directory item with 'objectid'
|
||||
H name objectid - clobber 'H'hash of entry 'name' of directory 'objectid'
|
||||
I item_num pos_in_item make pos_in_item-th slot of indirect item to point out of device
|
||||
O item_num - destroy item 'O'rder - make 'item_num'-th to have key bigger than 'item_num' + 1-th item
|
||||
D item_num - 'D'elete item_num-th item
|
||||
S item_num value - change file size (item_num-th item must be stat data)
|
||||
F item_num value - change sd_first_direct_byte of stat data
|
||||
J item_num objectid
|
||||
E name objectid new - change entry's deh_objectid to new
|
||||
P - print the block
|
||||
*/
|
||||
void do_corrupt_one_block (reiserfs_filsys_t * fs)
|
||||
{
|
||||
struct buffer_head * bh;
|
||||
int i, j;
|
||||
struct item_head * ih;
|
||||
int item_num;
|
||||
char * line = 0;
|
||||
size_t n = 0;
|
||||
char code, name [100];
|
||||
__u32 objectid, new_objectid;
|
||||
int value;
|
||||
int hash_code;
|
||||
int pos_in_item;
|
||||
unsigned long block;
|
||||
int type, format;
|
||||
|
||||
|
||||
block = certain_block (fs);
|
||||
if (block == fs->fs_super_bh->b_blocknr) {
|
||||
edit_super_block (fs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fs->fs_bitmap2) {
|
||||
struct buffer_head * bm_bh;
|
||||
unsigned long bm_block;
|
||||
|
||||
if (spread_bitmaps (fs))
|
||||
bm_block = ( block / (fs->fs_blocksize * 8) ) ?
|
||||
(block / (fs->fs_blocksize * 8)) * (fs->fs_blocksize * 8) :
|
||||
fs->fs_super_bh->b_blocknr + 1;
|
||||
else
|
||||
bm_block = fs->fs_super_bh->b_blocknr + 1 + (block / (fs->fs_blocksize * 8));
|
||||
|
||||
bm_bh = bread (fs->fs_dev, bm_block, fs->fs_blocksize);
|
||||
if (bm_bh) {
|
||||
if ( test_bit((block % (fs->fs_blocksize * 8)), bm_bh->b_data) )
|
||||
fprintf (stderr, "%lu is used in ondisk bitmap\n", block);
|
||||
else
|
||||
fprintf (stderr, "%lu is free in ondisk bitmap\n", block);
|
||||
|
||||
brelse (bm_bh);
|
||||
}
|
||||
} else {
|
||||
if (reiserfs_bitmap_test_bit (fs->fs_bitmap2, block))
|
||||
fprintf (stderr, "%lu is used in ondisk bitmap\n", block);
|
||||
else
|
||||
fprintf (stderr, "%lu is free in ondisk bitmap\n", block);
|
||||
}
|
||||
|
||||
bh = bread (fs->fs_dev, block, fs->fs_blocksize);
|
||||
if (!bh) {
|
||||
printf ("corrupt_one_block: bread fialed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (who_is_this (bh->b_data, fs->fs_blocksize) != THE_LEAF) {
|
||||
printf ("Can not corrupt not a leaf node\n");
|
||||
brelse (bh);
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("Corrupting block %lu..\n", bh->b_blocknr);
|
||||
|
||||
while (getline (&line, &n, stdin) != -1) {
|
||||
switch (line[0]) {
|
||||
case '#':
|
||||
case '\n':
|
||||
continue;
|
||||
case '?':
|
||||
printf ("A hash_code - reset hAsh code in super block\n"
|
||||
"T item_num type (0, 1, 2, 3) format (0, 1)\n"
|
||||
"C name objectid - Cut entry 'name' from directory item with 'objectid'\n"
|
||||
"H name objectid - clobber Hash of entry 'name' of directory 'objectid'\n"
|
||||
"I item_num pos_in_item make pos_in_tem-th slot of Indirect item to point out of device\n"
|
||||
"O item_num - destroy item Order - make 'item_num'-th to have key bigger than 'item_num' + 1-th item\n"
|
||||
"D item_num - Delete item_num-th item\n"
|
||||
"S item_num value - change file Size (item_num-th item must be stat data)\n"
|
||||
"F item_num value - change sd_First_direct_byte of stat data\n"
|
||||
"J item_num objectid - set 'obJectid' of 'item_num'-th item\n"
|
||||
"E name objectid objectid - set deh_objectid of an entry to objectid\n");
|
||||
|
||||
continue;
|
||||
|
||||
case 'P':
|
||||
print_block (stderr, fs, bh, 3, -1, -1);
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
/* corrupt hash record in super block */
|
||||
if (sscanf (line, "%c %d\n", &code, &hash_code) != 2) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C': /* cut entry */
|
||||
case 'H': /* make hash wrong */
|
||||
if (sscanf (line, "%c %s %u\n", &code, name, &objectid) != 3) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T': /* set type of item */
|
||||
if (sscanf (line, "%c %d %d %d\n", &code, &item_num, &type, &format) != 4) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'J': /* set objectid : used to simulate objectid sharing problem */
|
||||
if (sscanf (line, "%c %d %d\n", &code, &item_num, &objectid) != 3) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'E': /* set objectid : used to simulate objectid sharing problem */
|
||||
if (sscanf (line, "%c %s %u %d\n", &code, name, &objectid, &new_objectid) != 4) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I': /* break unformatted node pointer */
|
||||
if (sscanf (line, "%c %d %d\n", &code, &item_num, &pos_in_item) != 3) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D': /* delete item */
|
||||
case 'O': /* make item out of order */
|
||||
if (sscanf (line, "%c %d\n", &code, &item_num) != 2) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S': /* corrupt st_size */
|
||||
case 'F': /* st_first_direct_byte */
|
||||
if (sscanf (line, "%c %d %d\n", &code, &item_num, &value) != 3) {
|
||||
printf ("Wrong format \'%c\'\n", line [0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == 'A') {
|
||||
reiserfs_warning (stderr, "Changing %s to %s\n", code2name (get_sb_hash_code (fs->fs_ondisk_sb)),
|
||||
code2name (hash_code));
|
||||
set_sb_hash_code (fs->fs_ondisk_sb, hash_code);
|
||||
mark_buffer_dirty (fs->fs_super_bh);
|
||||
continue;
|
||||
}
|
||||
|
||||
ih = B_N_PITEM_HEAD (bh, 0);
|
||||
for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) {
|
||||
struct reiserfs_de_head * deh;
|
||||
|
||||
if (code == 'T' && i == item_num) {
|
||||
set_ih_key_format (ih, format);
|
||||
set_type (format, &ih->ih_key, type);
|
||||
mark_buffer_dirty (bh);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (code == 'I' && i == item_num) {
|
||||
if (!is_indirect_ih (ih) || pos_in_item >= I_UNFM_NUM (ih)) {
|
||||
reiserfs_warning (stderr, "Not an indirect item or there is "
|
||||
"not so many unfm ptrs in it\n");
|
||||
continue;
|
||||
}
|
||||
* ((__u32 *)B_I_PITEM (bh, ih) + pos_in_item) = get_sb_block_count (fs->fs_ondisk_sb) + 100;
|
||||
mark_buffer_dirty (bh);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (code == 'J' && i == item_num) {
|
||||
set_key_objectid (&ih->ih_key, objectid);
|
||||
mark_buffer_dirty (bh);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (code == 'S' && i == item_num) {
|
||||
/* fixme: old stat data only */
|
||||
struct stat_data_v1 * sd;
|
||||
|
||||
sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
|
||||
reiserfs_warning (stderr, "Changing sd_size of %k from %d to %d\n",
|
||||
&ih->ih_key, sd_v1_size(sd), value);
|
||||
set_sd_v1_size( sd, value );
|
||||
mark_buffer_dirty (bh);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (code == 'F' && i == item_num) {
|
||||
/* fixme: old stat data only */
|
||||
struct stat_data_v1 * sd;
|
||||
|
||||
sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
|
||||
reiserfs_warning (stderr, "Changing sd_first_direct_byte of %k from %d to %d\n",
|
||||
&ih->ih_key, sd_v1_first_direct_byte(sd), value);
|
||||
set_sd_v1_first_direct_byte( sd, value );
|
||||
mark_buffer_dirty (bh);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (code == 'D' && i == item_num) {
|
||||
delete_item (fs, bh, item_num);
|
||||
mark_buffer_dirty (bh);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (code == 'O' && i == item_num) {
|
||||
/* destroy item order */
|
||||
struct key * key;
|
||||
if (i == get_blkh_nr_items (B_BLK_HEAD (bh)) - 1) {
|
||||
printf ("can not destroy order\n");
|
||||
continue;
|
||||
}
|
||||
key = &(ih + 1)->ih_key;
|
||||
set_key_dirid (&ih->ih_key, get_key_dirid (key) + 1);
|
||||
mark_buffer_dirty (bh);
|
||||
}
|
||||
|
||||
if (get_key_objectid (&ih->ih_key) != objectid || !is_direntry_ih (ih))
|
||||
continue;
|
||||
|
||||
deh = B_I_DEH (bh, ih);
|
||||
|
||||
for (j = 0; j < get_ih_entry_count (ih); j ++, deh ++) {
|
||||
/* look for proper entry */
|
||||
if (name_in_entry_length (ih, deh, j) != strlen (name) ||
|
||||
strncmp (name, name_in_entry (deh, j), strlen (name)))
|
||||
continue;
|
||||
|
||||
/* ok, required entry found, make a corruption */
|
||||
switch (code) {
|
||||
case 'C': /* cut entry */
|
||||
cut_entry (fs, bh, i, j, 1);
|
||||
mark_buffer_dirty (bh);
|
||||
|
||||
if (!B_IS_IN_TREE (bh)) {
|
||||
printf ("NOTE: block is deleted from the tree\n");
|
||||
exit (0);
|
||||
}
|
||||
goto cont;
|
||||
break;
|
||||
|
||||
case 'H': /* clobber hash */
|
||||
corrupt_clobber_hash (name, ih, deh);
|
||||
goto cont;
|
||||
break;
|
||||
|
||||
case 'E': /* change entry's deh_objectid */
|
||||
set_deh_objectid (deh, new_objectid);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("Unknown command found\n");
|
||||
}
|
||||
mark_buffer_dirty (bh);
|
||||
}
|
||||
}
|
||||
cont:
|
||||
}
|
||||
free (line);
|
||||
printf ("Done\n");
|
||||
brelse (bh);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user