📄 pass1.c
字号:
ind_item = (__u32 *)B_I_PITEM (bh, ih); for (j = 0; j < I_UNFM_NUM (ih); j ++) { unfm_ptr = d32_get (ind_item, j); if (!unfm_ptr) continue; /* this corruption of indirect item had to be fixed in pass0 */ if (not_data_block (fs, unfm_ptr) || unfm_ptr >= get_sb_block_count (fs->fs_ondisk_sb)) /*!was_block_used (unfm_ptr))*/ reiserfs_panic ("%s: block %lu, item %d, pointer %d: The wrong pointer (%u) in the file %K. " "Must be fixed on pass0.", __FUNCTION__, bh->b_blocknr, i, j, unfm_ptr, &ih->ih_key); /* 1. zero slots pointing to a leaf */ if (is_used_leaf (unfm_ptr)) { dirty ++; d32_put (ind_item, j, 0); pass_1_stat (fs)->pointed_leaves ++; continue; } /* 2. zero pointers to blocks which are pointed already */ if (is_bad_unformatted (unfm_ptr)) { /* this unformatted pointed more than once. Did we see it already? */ if (!is_bad_unfm_in_tree_once (unfm_ptr)) /* keep first reference to it and mark about that in special bitmap */ mark_bad_unfm_in_tree_once (unfm_ptr); else { /* Yes, we have seen this pointer already, zero other pointers to it. */ dirty ++; d32_put (ind_item, j, 0); pass_1_stat (fs)->non_unique_pointers ++; continue; } } else pass_1_stat (fs)->correct_pointers ++; } } if (dirty) mark_buffer_dirty (bh);}struct si * remove_saved_item (struct si * si){ struct si * tmp = si->si_next; freemem (si->si_dnm_data); freemem (si); return tmp;}/* fsck starts creating of this bitmap on pass 1. It will then become on-disk bitmap */static void init_new_bitmap (reiserfs_filsys_t * fs){ unsigned int i; unsigned long block; unsigned long reserved; fsck_new_bitmap (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); /* mark_block_used skips 0, set the bit explicitly */ reiserfs_bitmap_set_bit (fsck_new_bitmap (fs), 0); /* mark other skipped blocks and super block used */ for (i = 1; i <= fs->fs_super_bh->b_blocknr; i ++) mark_block_used (i, 1); /* mark bitmap blocks as used */ block = fs->fs_super_bh->b_blocknr + 1; for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) { mark_block_used (block, 1); if (spread_bitmaps (fs)) block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); else block ++; } 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_new_bitmap: Wrong super block location, you must run --rebuild-sb."); block = get_journal_start_must (fs); for (i = block; i < reserved + block; i ++) mark_block_used (i, 1); 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)) { if (reiserfs_bitmap_test_bit (fsck_new_bitmap (fs), i)) reiserfs_panic ("%s: The block pointer to not data area, must be fixed on the pass0.\n", __FUNCTION__); reiserfs_bitmap_set_bit (fsck_new_bitmap (fs), i); } }#if 0 /* mark journal area as used if journal is standard or it is non standard and initialy has been created on a main device */ reserved = 0; if (!is_reiserfs_jr_magic_string (fs->fs_ondisk_sb)) reserved = get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)); if (get_sb_reserved_for_journal (fs->fs_ondisk_sb)) reserved = get_sb_reserved_for_journal (fs->fs_ondisk_sb); if (reserved) { for (i = 0; i <= reserved; i ++) mark_block_used (i + get_jp_journal_1st_block (sb_jp (fs->fs_ondisk_sb))); }#endif}/* this makes a map of blocks which can be allocated when fsck will continue */static void find_allocable_blocks (reiserfs_filsys_t * fs){ unsigned long i; fsck_progress ("Looking for allocable blocks .. "); fsck_allocable_bitmap (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); reiserfs_bitmap_fill (fsck_allocable_bitmap (fs)); /* find how many leaves are not pointed by any indirect items */ for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { if (not_data_block (fs, i)) /* journal (or reserved for it area), bitmaps, super block and blocks before it */ continue; if (is_good_unformatted (i) && is_bad_unformatted (i)) die ("find_allocable_blocks: The block (%lu) is masr as good and as bad at once.", i); if (is_good_unformatted (i) || is_bad_unformatted (i)) { /* blocks which were pointed once or more thn onec from indirect items - they will not be allocated */ continue; } /* make allocable not leaves, not bad blocks */ if (!is_used_leaf (i) && (!fs->fs_badblocks_bm || !reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i))) { /* this is not leaf and it is not pointed by found indirect items, so it does not contains anything valuable */ make_allocable (i); pass_1_stat (fs)->allocable_blocks ++; } } fsck_progress ("finished\n"); fs->block_allocator = reiserfsck_reiserfs_new_blocknrs; fs->block_deallocator = reiserfsck_reiserfs_free_block;}static void before_pass_1 (reiserfs_filsys_t * fs){ /* this will become an on-disk bitmap */ init_new_bitmap (fs); /* bitmap of leaves which could not be inserted on pass 1. FIXME: no need to have 1 bit per block */ fsck_uninsertables (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); reiserfs_bitmap_fill (fsck_uninsertables (fs)); /* find blocks which can be allocated */ find_allocable_blocks (fs); /* bitmap of bad unformatted nodes which are in the tree already */ bad_unfm_in_tree_once_bitmap = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); /* pass 1 does not deal with objectid */}static void save_pass_1_result (reiserfs_filsys_t * fs){ FILE * file; int retval; file = open_file("temp_fsck_file.deleteme", "w+"); if (!file) return; /* to be able to get a new bitmap on pass2 we should flush it on disk new_bitmap should not be flushed on disk if run without -d option, as if fsck fails on pass1 we get wrong bitmap on the next fsck start */ reiserfs_flush_to_ondisk_bitmap (fsck_new_bitmap (fs), fs); /* to be able to restart with pass 2 we need bitmap of uninsertable blocks and bitmap of alocable blocks */ reiserfs_begin_stage_info_save(file, PASS_1_DONE); reiserfs_bitmap_save (file, fsck_uninsertables (fs)); reiserfs_bitmap_save (file, fsck_allocable_bitmap(fs)); reiserfs_end_stage_info_save (file); close_file (file); retval = rename ("temp_fsck_file.deleteme", state_dump_file (fs)); if (retval != 0) fsck_progress ("pass 1: Could not rename the temporary file temp_fsck_file.deleteme to %s", state_dump_file (fs));}void load_pass_1_result (FILE * fp, reiserfs_filsys_t * fs){ fsck_new_bitmap (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); reiserfs_bitmap_copy (fsck_new_bitmap (fs), fs->fs_bitmap2); fsck_uninsertables (fs) = reiserfs_bitmap_load (fp); fsck_allocable_bitmap (fs) = reiserfs_bitmap_load (fp); fs->block_allocator = reiserfsck_reiserfs_new_blocknrs; fs->block_deallocator = reiserfsck_reiserfs_free_block; if (!fsck_new_bitmap (fs) || !fsck_allocable_bitmap (fs) || !fsck_allocable_bitmap (fs)) fsck_exit ("State dump file seems corrupted. Run without -d"); /* we need objectid map on pass 2 to be able to relocate files */ proper_id_map (fs) = id_map_init(); /* Not implemented yet. fetch_objectid_map (proper_id_map (fs), fs); */ fsck_progress ("Pass 1 result loaded. %d blocks used, %d allocable, " "still to be inserted %d\n", reiserfs_bitmap_ones (fsck_new_bitmap (fs)), reiserfs_bitmap_zeros (fsck_allocable_bitmap (fs)), reiserfs_bitmap_zeros (fsck_uninsertables (fs)));}extern reiserfs_bitmap_t * leaves_bitmap;/* reads blocks marked in leaves_bitmap and tries to insert them into tree */static void do_pass_1 (reiserfs_filsys_t * fs){ struct buffer_head * bh; unsigned long i; int what_node; unsigned long done = 0, total; /* on pass0 we have found that amount of leaves */ total = reiserfs_bitmap_ones (leaves_bitmap); /* read all leaves found on the pass 0 */ for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { if (!is_used_leaf (i)) continue; print_how_far (fsck_progress_file (fs), &done, total, 1, fsck_quiet (fs)); /* at least one of nr_to_read blocks is to be checked */ bh = bread (fs->fs_dev, i, fs->fs_blocksize); if (!bh) { /* we were reading one block at time, and failed, so mark block bad */ fsck_progress ("pass1: Reading of the block %lu failed\n", i); continue; } what_node = who_is_this (bh->b_data, bh->b_size); if ( what_node != THE_LEAF ) { check_memory_msg(); die ("build_the_tree: Nothing but leaves are expected. Block %lu - %s\n", i, which_block(what_node)); } if (is_block_used (i) && !(block_of_journal (fs, i) && fsck_data(fs)->rebuild.use_journal_area)) /* block is in new tree already */ die ("build_the_tree: The leaf (%lu) is in the tree already\n", i); /* fprintf (block_list, "leaf %d\n", i + j);*/ pass_1_stat (fs)->leaves ++; /* the leaf may still contain indirect items with wrong slots. Fix that */ pass1_correct_leaf (fs, bh); if (get_blkh_nr_items (B_BLK_HEAD (bh)) == 0) { /* all items were deleted on pass 0 or pass 1 */ mark_buffer_clean (bh); brelse (bh); continue; } if (is_leaf_bad (bh)) { /* FIXME: will die */ fsck_log ("is_leaf_bad: WARNING: The leaf (%lu) is formatted badly. Will be handled on the the pass2.\n", bh->b_blocknr); mark_block_uninsertable (bh->b_blocknr); brelse (bh); continue; } if (block_of_journal (fs, i) && fsck_data(fs)->rebuild.use_journal_area) { /* FIXME: temporary thing */ if (tree_is_empty ()) { /* we insert inot tree only first leaf of journal */ unsigned long block; struct buffer_head * new_bh; block = alloc_block (); if (!block) die ("could not allocate block"); new_bh = getblk (bh->b_dev, block, bh->b_size); memcpy (new_bh->b_data, bh->b_data, bh->b_size); mark_buffer_uptodate (new_bh, 1); mark_buffer_dirty (new_bh); make_single_leaf_tree (new_bh); brelse (new_bh); brelse (bh); continue; } /* other blocks of journal will be inserted in pass 2 */ mark_block_uninsertable (bh->b_blocknr); brelse (bh); continue; } try_to_insert_pointer_to_leaf (bh); brelse (bh); } fsck_progress ("\n");}static void after_pass_1 (reiserfs_filsys_t * fs){ time_t t; /* update fsck_state */ /* we should not flush bitmaps on disk after pass1, because new_bitmap contains only those blocks which are good leaves or just allocated internal blocks. */ set_sb_fs_state (fs->fs_ondisk_sb, PASS_1_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 (1, fs); /* we do not need this anymore */ delete_aux_bitmaps (); reiserfs_delete_bitmap (bad_unfm_in_tree_once_bitmap); if (!fsck_run_one_step (fs)) { if (fsck_user_confirmed (fs, "Continue? (Yes):", "Yes\n", 1)) /* reiserfsck continues */ return; } else save_pass_1_result (fs); if (proper_id_map (fs)) { /* when we run pass 1 only - we do not have proper_id_map */ id_map_free(proper_id_map (fs)); proper_id_map (fs) = 0; } time (&t); fsck_progress ("###########\n" "reiserfsck finished pass 1 at %s" "###########\n", ctime (&t)); fs->fs_dirt = 1; reiserfs_close (fs); exit(0);}void pass_1 (reiserfs_filsys_t * fs){ fsck_progress ("\nPass 1 (will try to insert %lu leaves):\n", reiserfs_bitmap_ones (fsck_source_bitmap (fs))); if (fsck_log_file (fs) != stderr) fsck_log ("####### Pass 1 #######\n"); before_pass_1 (fs); /* try to insert leaves found during pass 0 */ do_pass_1 (fs); after_pass_1 (fs);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -