📄 debugreiserfs.c
字号:
/* * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */#include "debugreiserfs.h"reiserfs_filsys_t * fs;#define print_usage_and_exit() {\fprintf (stderr, "Usage: %s [options] device\n\n\Options:\n\ -d\t\tprint blocks details of the internal tree\n\ -D\t\tprint blocks details of all used blocks\n\ -B file\textract list of badblocks\n\ -m\t\tprint bitmap blocks\n\ -o\t\tprint objectid map\n\n\ -J\t\tprint journal header\n\ -j filename\n\t\tprint journal located on the device 'filename'\n\ \t\tstores the journal in the specified file 'filename.\n\ -p\t\tsend filesystem metadata to stdout\n\ -u\t\tread stdin and unpack the metadata\n\ -S\t\thandle all blocks, not only used\n\ -1 block\tblock to print\n\ -q\t\tno speed info\n\ -V\t\tprint version and exit\n\n", argv[0]);\ exit (16);\}/* Undocumented options: -a map_file\n\tstore to the file the map of file. Is used with -n, -N, -r, -f\n -f \tprints the file map specified by -a.\n -n name\n\stcan device for specific name in reiserfs directories\n\ -N \tscan tree for specific key in reiserfs directories\n\ -k \tscan device either for specific key or for any metadata\n\ -r name\n\trecovers the file spacified by -a to the 'name' file.\n\ -S\t\tgo through whole device when running -p, -k or -n\n\ -U\t\tgo through unused blocks only when running -p, -k or -n\n\ -D\t\tprint blocks details scanning the device, not the tree as -d does\n\ -b bitmap_file\n\t\trunning -p, -k or -n read blocks marked in this bitmap only\n\ -C\tallow to change reiserfs metadata\n\ -J\tsearch block numbers in the journal\n\ -t\tstat the device\n\ -v\tverboes unpack, prints the block number of every block being unpacked\n\ -Z\tzero all data. To build a map of a file blocks by name: debugreiserfs device -a mapfile -n filename To build a map of a file blocks by key: debugreiserfs device -a mapfile -k To extract some: debugreiserfs device -a mapfile -r filename > backup*/#if 1struct reiserfs_fsstat { int nr_internals; int nr_leaves; int nr_files; int nr_directories; int nr_unformatted;} g_stat_info;#endifstatic void print_disk_tree (reiserfs_filsys_t * fs, unsigned long block_nr){ struct buffer_head * bh; int i, j, count; static int level = -1; if (level == -1) level = get_sb_tree_height (fs->fs_ondisk_sb); bh = bread (fs->fs_dev, block_nr, fs->fs_blocksize); if (!bh) { die ("Could not read block %lu\n", block_nr); } level --; if (level < 1) die ("level too small"); if (level != get_blkh_level (B_BLK_HEAD (bh))) { printf ("%d expected, %d found in %lu\n", level, get_blkh_level (B_BLK_HEAD (bh)), bh->b_blocknr); } if (is_internal_node (bh)) { struct disk_child * dc; g_stat_info.nr_internals ++; print_block (stdout, fs, bh, data(fs)->options & PRINT_TREE_DETAILS, -1, -1); dc = B_N_CHILD (bh, 0); count = B_NR_ITEMS(bh); for (i = 0; i <= count; i++, dc++) print_disk_tree (fs, get_dc_child_blocknr (dc)); } else if (is_leaf_node (bh)) { struct item_head *ih; g_stat_info.nr_leaves ++; print_block (stdout, fs, bh, data (fs)->options & PRINT_TREE_DETAILS, -1, -1); ih = B_N_PITEM_HEAD (bh, 0); count = leaf_item_number_estimate(bh); for (i = 0; i < count; i++, ih++) { if (is_indirect_ih(ih)) { __u32 * ind_item = (__u32 *)B_I_PITEM (bh, ih); for (j = 0; j < (int)I_UNFM_NUM (ih); j ++) { if (d32_get (ind_item, j)) { g_stat_info.nr_unformatted += 1; } } } } } else { print_block (stdout, fs, bh, data (fs)->options & PRINT_TREE_DETAILS, -1, -1); reiserfs_warning (stdout, "print_disk_tree: bad block " "type (%b)\n", bh); } brelse (bh); level ++;}static void print_disk_blocks (reiserfs_filsys_t * fs){ int type; unsigned long done = 0, total; struct buffer_head * bh; unsigned int j; total = reiserfs_bitmap_ones (input_bitmap(fs)); for (j = 0; j < get_sb_block_count (fs->fs_ondisk_sb); j ++) { if (!reiserfs_bitmap_test_bit (input_bitmap (fs), j)) continue; print_how_far (stderr, &done, total, 1, be_quiet (fs)); bh = bread (fs->fs_dev, j, fs->fs_blocksize); if (!bh) { reiserfs_warning (stderr, "could not read block %lu\n", j); continue; } type = who_is_this (bh->b_data, bh->b_size); if (type != THE_UNKNOWN) { print_block (stdout, fs, bh, PRINT_TREE_DETAILS | PRINT_DIRECT_ITEMS, -1, -1); } if (type == THE_INTERNAL) g_stat_info.nr_internals ++; else if (type == THE_LEAF || type == HAS_IH_ARRAY) g_stat_info.nr_leaves ++; brelse (bh); } fprintf (stderr, "\n");}void pack_one_block (reiserfs_filsys_t * fs, unsigned long block);static void print_one_block (reiserfs_filsys_t * fs, unsigned long block){ struct buffer_head * bh; 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 (misc_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 ("print_one_block: bread failed\n"); return; } if (debug_mode (fs) == DO_PACK) { pack_one_block (fs, bh->b_blocknr); brelse (bh); return; } if (who_is_this (bh->b_data, bh->b_size) != THE_UNKNOWN) print_block (stdout, fs, bh, PRINT_TREE_DETAILS, -1, -1); else printf ("Looks like unformatted\n"); brelse (bh); return;}/* debugreiserfs -p or -P compresses reiserfs meta data: super block, journal, bitmap blocks and blocks looking like leaves. It may save "bitmap" of blocks they packed in the file of special format. Reiserfsck can then load "bitmap" saved in that file and build the tree of blocks marked used in that "bitmap"*/char * where_to_save;char * badblocks_file;char * corruption_list_file;char *program_name;static char * parse_options (struct debugreiserfs_data * data, int argc, char * argv []){ int c; char * tmp; data->scan_area = USED_BLOCKS; data->mode = DO_DUMP; program_name = strrchr( argv[ 0 ], '/' ); if (program_name) program_name++; else program_name = argv[ 0 ]; while ((c = getopt (argc, argv, "a:b:C:F:SU1:pkn:Nfr:dDomj:JqtZl:LVB:uv")) != EOF) { switch (c) { case 'a': /* -r will read this, -n and -N will write to it */ asprintf (&data->map_file, "%s", optarg); break; case 'b': /* will load bitmap from a file and read only blocks marked in it. This is for -p and -k */ asprintf (&data->input_bitmap, "%s", optarg); data->scan_area = EXTERN_BITMAP; break; case 'S': /* have debugreiserfs -p or -k to read all the device */ data->scan_area = ALL_BLOCKS; break; case 'U': /* have debugreiserfs -p or -k to read unused blocks only */ data->scan_area = UNUSED_BLOCKS; break; case '1': /* print a single node */ data->block = strtol (optarg, &tmp, 0); if (*tmp) die ("parse_options: bad block number"); break; case 'C': data->mode = DO_CORRUPT_ONE; data->block = strtol (optarg, &tmp, 0); if (*tmp) { die ("parse_options: bad block number"); } break; case 'F': data->mode = DO_CORRUPT_FILE; if (asprintf (&corruption_list_file, "%s", optarg) == -1 ) { die ("parse_options: bad list corruption file"); } break; case 'p': data->mode = DO_PACK; break; case 'u': data->mode = DO_UNPACK; break; case 't': data->mode = DO_STAT; break; case 'k': /* read the device and print reiserfs blocks which contain defined key */ data->mode = DO_SCAN; break; case 'n': /* scan for names matching a specified pattern */ data->mode = DO_SCAN_FOR_NAME; data->pattern = optarg; /*asprintf (&data->pattern, "%s", optarg);*/ break; case 'N': /* search name in the tree */ data->mode = DO_LOOK_FOR_NAME; break; case 'f': data->mode = DO_FILE_MAP; break; case 'r': asprintf (&data->recovery_file, "%s", optarg); data->mode = DO_RECOVER; break; case 'd': /* print leaf details from internal tree */ data->options |= PRINT_TREE_DETAILS; break; case 'D': /* print leaf details accordingly the bitmap - can be used with -S */ data->options |= PRINT_DETAILS; break; case 'o': /* print objectid map */ data->options |= PRINT_OBJECTID_MAP; break; case 'm': /* print a block map */ case 'M': /* print a block map with details */ data->options |= PRINT_BITMAP; break; case 'j': /* -j must have a parameter */ data->options |= PRINT_JOURNAL; data->journal_device_name = optarg; break; case 'J': data->options |= PRINT_JOURNAL_HEADER; break; case 'R': /* read block numbers from stdin and look for them in the journal */ data->mode = DO_SCAN_JOURNAL; data->JJ ++; break; case 'B': /*disabled for a while*/ asprintf (&badblocks_file, "%s", optarg); data->mode = DO_EXTRACT_BADBLOCKS; break; case 'q': /* this makes packing to not show speed info during -p or -P */ data->options |= BE_QUIET; break; case 'Z': data->mode = DO_ZERO; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -