📄 super.c
字号:
/* * Copyright 2001-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */#include "fsck.h"#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)# include <uuid/uuid.h>#endif#define fsck_conditional_log(sb_found, fmt, list...) { \ if (sb_found) \ fsck_log(fmt, ## list); \}int what_fs_version (){ size_t n = 0; char * answer = 0; int version; printf("\nwhat the version of ReiserFS do you use[1-4]\n" "\t(1) 3.6.x\n" "\t(2) >=3.5.9 (introduced in the middle of 1999) (if you use linux 2.2, choose this one)\n" "\t(3) < 3.5.9 converted to new format (don't choose if unsure)\n" "\t(4) < 3.5.9 (this is very old format, don't choose if unsure)\n" "\t(X) exit\n"); getline (&answer, &n, stdin); version = atoi (answer); if (version < 1 || version > 4) die ("rebuild_sb: wrong version"); return version;}/*#define super_error(exit_code, text) { \ fsck_log(text); \ return exit_code; \} int check_sb (reiserfs_filsys_t * fs) { int magic = 0, version = 0; if (!is_blocksize_correct (fs->fs_blocksize)) super_error(-1, "Wrong blocksize found in the super block\n"); if (is_reiserfs_3_6_magic_string (sb)) magic = 2; else if (is_reiserfs_3_5_magic_string (sb)) magic = 1; else if (is_reiserfs_jr_magic_string (sb)) magic = 3; else super_error(-1, "Invalid magic found in the super block.\n"); if (magic == 1 || magic == 2) { if (fsck_data (fs)->journal_dev_name) fsck_log("Reiserfs with standard journal found, but there was specified a " "journal dev\n"); standard_journal = 1; } else { if (!fsck_data (fs)->journal_dev_name) super_error(-1, "Reiserfs with non standard journal found, but there was not " "specified any journal dev\n"); standard_journal = 0; } if (get_sb_version (sb) != REISERFS_FORMAT_3_6 && get_sb_version (sb) != REISERFS_FORMAT_3_5) super_error(-1, "Invalid format found in the super block.\n"); if (is_new_sb_location(fs->fs_super_bh->b_blocknr, fs->fs_blocksize)) { if (magic == 3) version = get_sb_version (sb) == REISERFS_FORMAT_3_6 ? 1 : 2; else version = magic == 2 ? 1 : 2; } else if (is_old_sb_location(fs->fs_super_bh->b_blocknr, fs->fs_blocksize)) { if (magic == 3) version = get_sb_version (sb) == REISERFS_FORMAT_3_6 ? 3 : 4; else version = magic == 2 ? 3 : 4; } else die("Super block in the wong block(%d).\n", fs->fs_super_bh->b_blocknr); if (version == 0) die ("FS format must be figured out here.\n"); if (get_sb_block_count (sb) > count_blocks (filename, fs->fs_blocksize)) super_error(-1, "Invalid block count found in the super block.\n"); if (get_sb_block_size (sb) != fs->fs_blocksize) super_error(-1, "Invalid block size found in the super block (%lu).\n", get_sb_block_size (sb));//Non needed from here p_oid_maxsize = (fs->fs_blocksize - reiserfs_super_block_size (sb)) / sizeof(__u32) / 2 * 2; if (get_sb_oid_maxsize (sb) != p_oid_maxsize) super_error(-1, "Invalid objectid map max size found in the super block (%lu).\n", get_sb_oid_maxsize (sb)); if (get_sb_oid_cursize (sb) == 1 || get_sb_oid_cursize (sb) > get_sb_oid_maxsize (sb)) super_error(-1, "Invalid objectid map found in the super block (%lu).\n", get_sb_oid_cursize (sb)); if (get_sb_root_block (sb) > block_count && get_sb_root_block (sb) != ~0) fsck_log("Invalid root block found in the super block (%lu).\n", get_sb_root_block (sb)); if (get_sb_free_blocks (sb) > block_count) fsck_log ("Invalid free block count found in the super block (%lu).\n", get_sb_free_blocks (sb)); if (get_sb_tree_height (sb) && ((get_sb_tree_height (sb) < DISK_LEAF_NODE_LEVEL + 1) || (get_sb_tree_height (sb) > MAX_HEIGHT) && (get_sb_tree_height (sb) != ~0))) super_error(-1, "Invalid tree height found in the super block (%lu).\n", get_sb_tree_height (sb)); if (get_sb_hash_code (sb) && code2name (get_sb_hash_code (sb)) == 0) super_error(-1, "Invalid hash found in the super block (%lu).\n", get_sb_hash_code (sb)); if (version == 1 || version == 3) { if (!uuid_is_correct(sb->s_uuid)) fsck_log ("Invalid uuid found, you should generate a new one.\n"); if (sb->s_flags & 0xfffffffe) fsck_log ("rebuild-sb: super block flags found (%u), zeroed\n", sb->s_flags); }//Not needed till here. p_bmap_nr = (block_count + (fs->fs_blocksize * 8 - 1)) / (fs->fs_blocksize * 8); if (get_sb_bmap_nr (sb) != p_bmap_nr) super_error(-1, "Invalid bitmap number found in the super block (%lu).\n", get_sb_bmap_nr (sb)); if (!fsck_skip_journal (fs) && standard_journal == 1) { if (get_jp_journal_dev (sb_jp(sb)) != 0) super_error(-1, "Invalid journal device found (%lu).\n", get_jp_journal_dev (sb_jp(sb))); if (get_jp_journal_1st_block (sb_jp(sb)) != get_journal_start_must (fs)) super_error(-1, "Invalid journal first block found (%lu).\n", get_jp_journal_1st_block (sb_jp(sb))); if (get_jp_journal_size (sb_jp(sb)) != journal_default_size(fs->fs_super_bh->b_blocknr, fs->fs_blocksize)) super_error(-1, "Invalid journal size found (%lu).\n", get_jp_journal_size (sb_jp(sb)) + 1); if (get_jp_journal_max_batch (sb_jp(sb)) != advise_journal_max_batch(get_jp_journal_max_trans_len (sb_jp(sb)))) { fsck_conditional_log (magic_was_found, "rebuild-sb: wrong journal max batch size occured (%lu), fixed (%d)\n", get_jp_journal_max_batch (sb_jp(sb)), advise_journal_max_batch(get_jp_journal_max_trans_len (sb_jp(sb)))); set_jp_journal_max_batch (sb_jp(sb), advise_journal_max_batch(get_jp_journal_max_trans_len (sb_jp(sb)))); } if (get_jp_journal_max_commit_age (sb_jp(sb)) != advise_journal_max_commit_age()) { fsck_conditional_log (magic_was_found, "rebuild-sb: wrong journal max commit age occured (%lu), fixed (%d)\n", get_jp_journal_max_commit_age (sb_jp(sb)), advise_journal_max_commit_age()); set_jp_journal_max_commit_age (sb_jp(sb), advise_journal_max_commit_age()); } if (get_jp_journal_max_trans_age (sb_jp(sb)) != advise_journal_max_trans_age()) { fsck_log ("rebuild-sb: wrong journal max commit age occured (%lu), fixed (0)\n", get_jp_journal_max_trans_age (sb_jp(sb)), advise_journal_max_trans_age()); set_jp_journal_max_trans_age (sb_jp(sb), advise_journal_max_trans_age()); } }*/void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * data){ int version = 0; struct reiserfs_super_block * ondisk_sb = 0; struct reiserfs_super_block * sb = 0; struct reiserfs_journal_header *j_head; int magic_was_found = 0; unsigned long block_count = 0; __u16 p_oid_maxsize; __u16 p_bmap_nr; __u32 p_jp_journal_1st_block = 0; __u32 p_jp_dev_size = 0; int standard_journal = -1; char * journal_dev_name = 0; char * tmp; int sb_size; char * answer = 0; size_t n = 0; struct stat stat_buf; int retval, exit_code = EXIT_OK;#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) char uuid[37]; uuid[36] = '\0';#endif if (!no_reiserfs_found (fs)) { sb = getmem (sizeof (*sb)); if (!is_opened_rw (fs)) { close (fs->fs_dev); fs->fs_dev = open (fs->fs_file_name, O_RDWR | O_LARGEFILE); } if (!is_blocksize_correct (fs->fs_blocksize)) { printf("\nCannot find a proper blocksize, enter block size [4096]: \n"); getline (&answer, &n, stdin); if (strcmp(answer, "\n")) { retval = (int) strtol (answer, &tmp, 0); if ((*tmp && strcmp(tmp, "\n")) || retval < 0) reiserfs_exit (EXIT_USER, "rebuild_sb: wrong block size specified\n"); if (!is_blocksize_correct (retval)) reiserfs_exit (EXIT_USER, "rebuild_sb: wrong block size specified, " "only power of 2 from 512-8192 interval are supported.\n"); } else retval = 4096; fs->fs_blocksize = retval; } if (!(block_count = count_blocks (filename, fs->fs_blocksize))) exit(EXIT_OPER); /* save ondisk_sb somewhere and work in temp area */ ondisk_sb = fs->fs_ondisk_sb; memcpy (sb, fs->fs_ondisk_sb, sizeof (*sb)); fs->fs_ondisk_sb = sb; if (is_reiserfs_3_6_magic_string (sb)) { /* 3_6 magic */ if (fsck_data (fs)->journal_dev_name) /* journal dev must not be specified with standard journal */ reiserfs_exit (EXIT_USER, "ReiserFS with default journal " "is found, but there was specified a journal device."); if (fs->fs_super_bh->b_blocknr == REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 1; else if (fs->fs_super_bh->b_blocknr == REISERFS_OLD_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 3; magic_was_found = 2; } else if (is_reiserfs_3_5_magic_string (sb)) { if (fsck_data (fs)->journal_dev_name) /* journal dev must not be specified with standard journal */ reiserfs_exit (EXIT_USER, "ReiserFS with default journal " "is found, but there was specified a journal device."); /* 3_5 magic */ if (fs->fs_super_bh->b_blocknr == REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 2; else if (fs->fs_super_bh->b_blocknr == REISERFS_OLD_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 4; magic_was_found = 1; } else if (is_reiserfs_jr_magic_string (sb)) { if (!fsck_data (fs)->journal_dev_name && !fsck_skip_journal(fs)) /* journal dev must be specified with non standard journal */ reiserfs_exit (EXIT_USER, "ReiserFS with non default journal " "is found, but there was not specified any journal device."); if (get_sb_version (sb) == REISERFS_FORMAT_3_6) { /*non-standard magic + sb_format == 3_6*/ if (fs->fs_super_bh->b_blocknr == REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 1; else if (fs->fs_super_bh->b_blocknr == REISERFS_OLD_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 3; magic_was_found = 3; } else if (get_sb_version (sb) == REISERFS_FORMAT_3_5) { /* non-standard magic + sb_format == 3_5 */ if (fs->fs_super_bh->b_blocknr == REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 2; else if (fs->fs_super_bh->b_blocknr == REISERFS_OLD_DISK_OFFSET_IN_BYTES / fs->fs_blocksize) version = 4; magic_was_found = 3; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -