📄 pass0.c
字号:
/* we were reading one block at time, and failed, so mark block bad */ fsck_progress ("%s: Reading of the block %lu failed\n", __FUNCTION__, i); continue; } if (fs->fs_badblocks_bm && reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) reiserfs_panic ("The block (%lu), specified in badblock list, was read.", i); if (not_data_block (fs, i)) { /* block which could not be pointed by indirect item */ if (!(block_of_journal (fs, i) && fsck_data(fs)->rebuild.use_journal_area)) reiserfs_panic ("The block (%lu) from non data area was read.", i); } pass_0_stat (fs)->dealt_with ++; what_node = who_is_this (bh->b_data, bh->b_size); if ( what_node != THE_LEAF && what_node != HAS_IH_ARRAY ) { brelse (bh); continue; } pass_0_stat (fs)->leaves ++; pass0_correct_leaf (fs, bh); brelse (bh); } fsck_progress ("\n"); /* just in case */ id_map_mark(proper_id_map (fs), REISERFS_ROOT_OBJECTID);}int is_used_leaf (unsigned long block){ return pass0_is_leaf (block);}/*int how_many_leaves_were_there (void){ return fsck_data (fs)->rebuild.leaves;}*//* these are used to correct uformatted node pointers */int is_bad_unformatted (unsigned long block){ return pass0_is_bad_unfm (block);}/* these are used to correct uformatted node pointers */int is_good_unformatted (unsigned long block){ return pass0_is_good_unfm (block);}/* this is for check only. With this we make sure that all pointers we put into tree on pass 1 do not point to leaves (FIXME), do not point to journal, bitmap, etc, do not point out of fs boundary (and are marked used in on-disk bitmap - this condition skipped for now). */int still_bad_unfm_ptr_1 (unsigned long block){ if (!block) return 0; if (pass0_is_leaf (block)) return 1; if (pass0_is_bad_unfm (block) && !is_bad_unfm_in_tree_once (block)) return 2; if (not_data_block (fs, block)) return 3; /* if (!was_block_used (block)) return 4; */ if (block >= get_sb_block_count (fs->fs_ondisk_sb)) return 5; return 0; }/* pointers to data block which get into tree are checked with this */int still_bad_unfm_ptr_2 (unsigned long block){ if (!block) return 0; if (is_block_used (block)) return 1; if (block >= get_sb_block_count (fs->fs_ondisk_sb)) return 1; return 0;}/* these are used to allocate blocks for tree building */int are_there_allocable_blocks (unsigned int amout_needed) { if (reiserfs_bitmap_zeros (fsck_allocable_bitmap (fs)) < amout_needed) { unsigned int zeros = 0, i; fsck_progress ("Not enough allocable blocks, checking bitmap..."); for (i = 0; i < fsck_allocable_bitmap (fs)->bm_bit_size; i ++) { if (!reiserfs_bitmap_test_bit (fsck_allocable_bitmap (fs), i)) zeros ++; } fsck_progress ("there are %u allocable blocks, btw\n", zeros); return 0; } return 1;}unsigned long alloc_block (void){ unsigned long block = 0; /* FIXME: start point could be used */ if (reiserfs_bitmap_find_zero_bit (fsck_allocable_bitmap (fs), &block)) { die ("alloc_block: Allocable blocks counter is wrong"); return 0; } reiserfs_bitmap_set_bit (fsck_allocable_bitmap (fs), block); return block;}void make_allocable (unsigned long block){ reiserfs_bitmap_clear_bit (fsck_allocable_bitmap (fs), block);}static void choose_hash_function (reiserfs_filsys_t * fs){ unsigned long max; unsigned int hash_code; int i; if (fsck_hash_defined (fs)) return; max = 0; hash_code = func2code (0); for (i = 0; i < fsck_data (fs)->rebuild.hash_amount; i ++) { /* remember hash whihc got more hits */ if (fsck_data (fs)->rebuild.hash_hits [i] > max) { hash_code = i; max = fsck_data (fs)->rebuild.hash_hits [i]; } if (fsck_data (fs)->rebuild.hash_hits [i]) fsck_log ("%lu directory entries were hashed with %s hash.\n", fsck_data (fs)->rebuild.hash_hits [i], code2name(i)); } if (max == 0 || hash_code == 0) { /* no names were found. take either super block value or default */ hash_code = get_sb_hash_code (fs->fs_ondisk_sb); if (!hash_code) hash_code = DEFAULT_HASH; fsck_log ("Could not find a hash in use. Using %s\n", code2name (hash_code)); } /* compare the most appropriate hash with the hash set in super block */ if (hash_code != get_sb_hash_code (fs->fs_ondisk_sb)) { fsck_progress ("Selected hash (%s) does not match to the hash set in the super block (%s).\n", code2name (hash_code), code2name (get_sb_hash_code (fs->fs_ondisk_sb))); set_sb_hash_code (fs->fs_ondisk_sb, hash_code); } fsck_progress ("\t%s hash is selected\n", code2name (hash_code)); reiserfs_hash (fs) = code2func (hash_code);}/* create bitmap of blocks the tree is to be built off *//* debugreiserfs and pass0 should share this code -s should showthe same as we could recover - test: zero first 32M */static void init_source_bitmap (reiserfs_filsys_t * fs){ FILE * fp; unsigned long block_count = get_sb_block_count (fs->fs_ondisk_sb); unsigned long i, j; unsigned long tmp; unsigned long block, reserved, bits_amount; switch (fsck_data (fs)->rebuild.scan_area) { case ALL_BLOCKS: fsck_source_bitmap (fs) = reiserfs_create_bitmap (block_count); reiserfs_bitmap_fill (fsck_source_bitmap (fs)); fsck_progress ("The whole partition (%d blocks) is to be scanned\n", reiserfs_bitmap_ones (fsck_source_bitmap (fs))); break; case USED_BLOCKS: fsck_progress ("Loading on-disk bitmap .. "); fsck_source_bitmap (fs) = reiserfs_create_bitmap (block_count); reiserfs_bitmap_copy (fsck_source_bitmap (fs), fs->fs_bitmap2); fsck_progress ("ok, %d blocks marked used\n", reiserfs_bitmap_ones (fsck_source_bitmap (fs))); break; case EXTERN_BITMAP: fp = fopen (fsck_data (fs)->rebuild.bitmap_file_name, "r"); if (!fp) { reiserfs_exit (EXIT_OPER, "Could not load bitmap: %s\n", strerror(errno)); } fsck_source_bitmap (fs) = reiserfs_bitmap_load (fp); if (!fsck_source_bitmap (fs)) { reiserfs_exit (EXIT_OPER, "Could not load fitmap from \"%s\"", fsck_data (fs)->rebuild.bitmap_file_name); } fsck_progress ("%d blocks marked used in extern bitmap\n", reiserfs_bitmap_ones (fsck_source_bitmap (fs))); fclose (fp); break; default: reiserfs_panic ("No area to scan specified"); } tmp = 0; /* unmark bitmaps */ block = fs->fs_super_bh->b_blocknr + 1; reserved = fsck_source_bitmap(fs)->bm_bit_size; for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) { if (!reiserfs_bitmap_test_bit (fsck_source_bitmap (fs), block)) { /* bitmap is definitely broken, mark all blocks of this bitmap block as used */ bits_amount = (reserved < fs->fs_blocksize * 8) ? reserved : fs->fs_blocksize * 8; fsck_log("%s: Bitmap %lu (of %lu bits) is wrong - mark all blocks [%lu - %lu] as used\n", __FUNCTION__, i, bits_amount, i * fs->fs_blocksize * 8, fs->fs_blocksize * 8 * i + bits_amount); for (j = i * fs->fs_blocksize * 8; j < i * fs->fs_blocksize * 8 + bits_amount; j++) { if (!reiserfs_bitmap_test_bit (fsck_source_bitmap(fs), j)) reiserfs_bitmap_set_bit (fsck_source_bitmap(fs), j); } } reiserfs_bitmap_clear_bit (fsck_source_bitmap (fs), block); reserved -= fs->fs_blocksize * 8; tmp ++; /* next block fo bitmap */ if (spread_bitmaps (fs)) block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); else block ++; } /* pass 0 will skip super block and journal areas and bitmap blocks, find how many blocks have to be read */ for (i = 0; i <= fs->fs_super_bh->b_blocknr; i ++) { if (!reiserfs_bitmap_test_bit (fsck_source_bitmap (fs), i)) continue; reiserfs_bitmap_clear_bit (fsck_source_bitmap (fs), i); tmp ++; } /* unmark journal area as used if journal is standard or it is non standard and initialy has been created on a main device */ reserved = get_size_of_journal_or_reserved_area (fs->fs_ondisk_sb); /* where does journal area (or reserved journal area) start from */ if (!is_new_sb_location (fs->fs_super_bh->b_blocknr, fs->fs_blocksize) && !is_old_sb_location (fs->fs_super_bh->b_blocknr, fs->fs_blocksize)) die ("init_source_bitmap: Wrong super block location, you must run --rebuild-sb."); block = get_journal_start_must (fs); for (i = block; i < reserved + block; i ++) { if (!reiserfs_bitmap_test_bit (fsck_source_bitmap (fs), i)) continue; reiserfs_bitmap_clear_bit (fsck_source_bitmap (fs), i); tmp ++; } if (fs->fs_badblocks_bm) for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { if (reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) reiserfs_bitmap_clear_bit (fsck_source_bitmap (fs), i); } fsck_source_bitmap (fs)->bm_set_bits = reiserfs_bitmap_ones (fsck_source_bitmap (fs)); fsck_progress ("Skipping %d blocks (super block, journal, " "bitmaps) %d blocks will be read\n", tmp, fsck_source_bitmap (fs)->bm_set_bits); }static void before_pass_0 (reiserfs_filsys_t * fs){ /* bitmap of blocks to be read */ init_source_bitmap (fs); /* bitmap of leaves, good and bad unformatted */ make_aux_bitmaps (fs); /* on pass0 all objectids will be marked here as used */ proper_id_map (fs) = id_map_init(); /* pass0 gathers statistics about hash hits */ hash_hits_init (fs);}static void save_pass_0_result (reiserfs_filsys_t * fs){ FILE * file; int retval; /* save bitmaps with which we will be able start reiserfs from pass 1 */ file = open_file ("temp_fsck_file.deleteme", "w+"); if (!file) return; reiserfs_begin_stage_info_save (file, PASS_0_DONE); reiserfs_bitmap_save (file, leaves_bitmap); reiserfs_bitmap_save (file, good_unfm_bitmap); reiserfs_bitmap_save (file, bad_unfm_bitmap); reiserfs_end_stage_info_save (file); close_file (file); retval = rename ("temp_fsck_file.deleteme", state_dump_file (fs)); if (retval != 0) fsck_progress ("%s: Could not rename the temporary file temp_fsck_file.deleteme to %s", __FUNCTION__, state_dump_file (fs));}/* file 'fp' must contain 3 bitmaps saved during last pass 0: bitmap of leaves, bitmaps of good and bad unfms*/void load_pass_0_result (FILE * fp, reiserfs_filsys_t * fs){ leaves_bitmap = reiserfs_bitmap_load (fp); good_unfm_bitmap = reiserfs_bitmap_load (fp); bad_unfm_bitmap = reiserfs_bitmap_load (fp); if (!leaves_bitmap || !good_unfm_bitmap || !bad_unfm_bitmap) fsck_exit ("State dump file seems corrupted. Run without -d"); fsck_source_bitmap (fs) = leaves_bitmap; /* on pass 1 we do not need proper objectid map */ fsck_progress ("Pass 0 result loaded. %d leaves, %d/%d good/bad data blocks\n", reiserfs_bitmap_ones (leaves_bitmap), reiserfs_bitmap_ones (good_unfm_bitmap), reiserfs_bitmap_ones (bad_unfm_bitmap));}static void after_pass_0 (reiserfs_filsys_t * fs){ time_t t; /* update super block: hash, objectid map, fsck state */ choose_hash_function (fs); id_map_flush(proper_id_map (fs), fs); set_sb_fs_state (fs->fs_ondisk_sb, PASS_0_DONE); mark_buffer_dirty (fs->fs_super_bh); /* write all dirty blocks */ fsck_progress ("Flushing.."); fs->fs_dirt = 1; reiserfs_flush (fs); fsck_progress ("finished\n"); stage_report (0, fs); /* free what we do not need anymore */ reiserfs_delete_bitmap (fsck_source_bitmap (fs)); fsck_source_bitmap (fs) = 0; if (!fsck_run_one_step (fs)) { if (fsck_user_confirmed (fs, "Continue? (Yes):", "Yes\n", 1)) { /* reiserfsck continues */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -