📄 check_tree.c
字号:
} if (!((is_stat_data_ih (ih - 1) && get_offset (&ih->ih_key) == 1) || (is_indirect_ih (ih - 1) && get_offset (&(ih - 1)->ih_key) + get_bytes_number (ih-1, bh->b_size) == get_offset (&ih->ih_key)))) { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); return 1; } } if (is_indirect_ih (ih) || is_direntry_ih (ih)) { /* left item must be stat data of the same object */ if (not_of_one_file (&((ih - 1)->ih_key), &ih->ih_key) || !is_stat_data_ih (ih - 1)) { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); return 1; } } return 0;}/* 1 if block head or any of items is bad */static int bad_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh){ int i; if (leaf_structure_check(fs, bh)) return 1; for (i = 0; i < B_NR_ITEMS (bh); i ++) { if (bad_item (fs, bh, i)) { fsck_log ("bad_leaf: block %lu, item %d: The corrupted item found " "(%H)\n", bh->b_blocknr, i, B_N_PITEM_HEAD (bh, i)); } if (i && bad_pair (fs, bh, i)) { fsck_log ("bad_leaf: block %lu, items %d and %d: The wrong order " "of items: %k, %k\n", bh->b_blocknr, i - 1, i, &B_N_PITEM_HEAD (bh, i-1)->ih_key, &B_N_PITEM_HEAD (bh, i)->ih_key); } } return 0;}/* 1 if bh does not look like internal node */static int bad_internal (reiserfs_filsys_t * fs, struct buffer_head * bh){ int i; for (i = 0; i <= B_NR_ITEMS (bh); i ++) { if (i != B_NR_ITEMS (bh) && i != B_NR_ITEMS (bh) - 1) /* make sure that keys are in increasing order */ if (comp_keys (B_N_PDELIM_KEY (bh, i), B_N_PDELIM_KEY (bh, i + 1)) != -1) { fsck_log ("%s: vpf-10320: block %lu, items %d and %d: The " "wrong order of items: %k, %k\n", __FUNCTION__, bh->b_blocknr, i, i + 1, B_N_PDELIM_KEY (bh, i), B_N_PDELIM_KEY (bh, i + 1)); one_more_corruption (fs, FATAL); return 1; } /* make sure that the child is correct */ if (bad_block_number (fs, get_dc_child_blocknr (B_N_CHILD (bh,i)))) { fsck_log ("%s: vpf-10330: block %lu, item %d: The internal item " "points to the not legal block (%lu)\n", __FUNCTION__, bh->b_blocknr, i, get_dc_child_blocknr (B_N_CHILD (bh,i))); one_more_corruption (fs, FATAL); return 1; } } return 0;}/* h == 0 for root level. block head's level == 1 for leaf level */static inline int h_to_level (reiserfs_filsys_t * fs, int h){ return get_sb_tree_height (fs->fs_ondisk_sb) - h - 1;}#if 0int dc_fix(struct buffer_head *bh, int pos, __u32 block) { if (!bh || !bh->b_data) return -1; if (B_NR_ITEMS(bh) < pos) return -1; set_dc_child_blocknr(B_N_CHILD(bh,pos), block); mark_buffer_dirty(bh); bwrite(bh); return 0;}/* Removes @N-th key and @(N+1) pointer. */int internal_remove(struct buffer_head *bh, int pos) { char *delete; __u32 nr; if (!bh || !bh->b_data) return -1; if (B_NR_ITEMS(bh) < pos) return -1; delete = (char *)B_N_CHILD(bh, pos + 2); memmove(delete - DC_SIZE, delete, bh->b_size - (delete - bh->b_data)); delete = (char *)B_N_PDELIM_KEY(bh, pos + 1); memmove(delete - KEY_SIZE, delete, bh->b_size - (delete - bh->b_data)); nr = B_NR_ITEMS(bh) - 1; set_blkh_nr_items(B_BLK_HEAD(bh), nr); set_blkh_free_space(B_BLK_HEAD(bh), bh->b_size - (BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1))); mark_buffer_dirty(bh); bwrite(bh); return 0;}int leaf_fix_key_oid(struct buffer_head *bh, int pos, __u32 oid) { struct item_head * ih; if (!bh || !bh->b_data) return -1; if (B_NR_ITEMS(bh) < pos) return -1; ih = B_N_PITEM_HEAD (bh, pos); set_key_objectid(&ih->ih_key, oid); mark_buffer_dirty(bh); bwrite(bh); return 0;}#endif/* bh must be formatted node. blk_level must be tree_height - h + 1 */static int bad_node (reiserfs_filsys_t * fs, struct buffer_head ** path, int h){ struct buffer_head ** pbh = &path[h]; if (B_LEVEL (*pbh) != h_to_level (fs, h)) { fsck_log ("block %lu: The level of the node (%d) is not correct, " "(%d) expected\n", (*pbh)->b_blocknr, B_LEVEL (*pbh), h_to_level (fs, h)); one_more_corruption (fs, FATAL); return 1; } if (bad_block_number (fs, (*pbh)->b_blocknr)) { one_more_corruption (fs, FATAL); fsck_log ("%s: vpf-10340: The node in the wrong block number (%lu) " "found in the tree\n", __FUNCTION__, (*pbh)->b_blocknr); return 1; } if (got_already (fs, (*pbh)->b_blocknr)) { fsck_log ("%s: vpf-10350: The block (%lu) is used more than once " "in the tree.\n", __FUNCTION__, (*pbh)->b_blocknr); one_more_corruption (fs, FATAL); return 1; } if (is_leaf_node (*pbh)) { fsck_check_stat (fs)->leaves ++; return bad_leaf (fs, *pbh); } fsck_check_stat (fs)->internals ++; return bad_internal (fs, *pbh);}/* internal node bh must point to block */static int get_pos (struct buffer_head * bh, unsigned long block){ int i; for (i = 0; i <= B_NR_ITEMS (bh); i ++) { if (get_dc_child_blocknr (B_N_CHILD (bh, i)) == block) return i; } die ("An internal pointer to the block (%lu) cannot be found in the node (%lu)", block, bh->b_blocknr); return 0;}/* path[h] - leaf node */static struct key * lkey (struct buffer_head ** path, int h){ int pos; while (h > 0) { pos = get_pos (path[h - 1], path[h]->b_blocknr); if (pos) return B_N_PDELIM_KEY(path[h - 1], pos - 1); h --; } return 0;}/* path[h] - leaf node */static struct key * rkey (struct buffer_head ** path, int h){ int pos; while (h > 0) { pos = get_pos (path[h - 1], path[h]->b_blocknr); if (pos != B_NR_ITEMS (path[h - 1])) return B_N_PDELIM_KEY (path[h - 1], pos); h --; } return 0;}/* are all delimiting keys correct */static int bad_path (reiserfs_filsys_t * fs, struct buffer_head ** path, int h1){ int h = 0; struct key * dk; int pos = 0; while (path[h]) h ++; h--; // path[h] is leaf if (h != h1) die ("bad_path: The leaf is expected as the last element in the path"); if (h) pos = get_pos (path[h - 1], path[h]->b_blocknr); dk = lkey (path, h); if (dk && comp_keys (dk, B_N_PKEY (path[h], 0))) { /* left delimiting key must be equal to the key of 0-th item in the node */ fsck_log ("bad_path: The left delimiting key %k of the node (%lu) must " "be equal to the first element's key %k within the node.\n", dk, path[h]->b_blocknr, B_N_PKEY (path[h], 0)); one_more_corruption (fs, FATAL); return 1; } dk = rkey (path, h); if (dk && comp_keys (dk, B_N_PKEY (path[h], get_blkh_nr_items (B_BLK_HEAD (path[h])) - 1)) != 1) { /* right delimiting key must be gt the key of the last item in the node */ fsck_log ("bad_path: The right delimiting key %k of the node (%lu) must " "be greater than the last (%d) element's key %k within the node.\n", dk, path[h]->b_blocknr, get_blkh_nr_items (B_BLK_HEAD (path[h])) - 1, B_N_PKEY (path[h], get_blkh_nr_items (B_BLK_HEAD (path[h])) - 1)); one_more_corruption (fs, FATAL); return 1; } if (h && (get_dc_child_size (B_N_CHILD(path[h-1],pos)) + get_blkh_free_space ((struct block_head *)path[h]->b_data) + BLKH_SIZE != path[h]->b_size)) { /* wrong dc_size */ fsck_log ("bad_path: block %lu, pointer %d: The used space (%d) of the " "child block (%lu)", path[h-1]->b_blocknr, pos, get_dc_child_size(B_N_CHILD(path[h-1],pos)), path[h]->b_blocknr); fsck_log (" is not equal to the (blocksize (4096) - free space (%d) - " "header size (%u))", get_blkh_free_space((struct block_head *)path[h]->b_data), BLKH_SIZE); if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { set_dc_child_size (B_N_CHILD(path[h-1],pos), path[h]->b_size - get_blkh_free_space ((struct block_head *)path[h]->b_data) - BLKH_SIZE); fsck_log (" - corrected to (%lu)\n", get_dc_child_size (B_N_CHILD(path[h-1], pos))); mark_buffer_dirty (path[h-1]); } else { one_more_corruption (fs, FIXABLE); fsck_log ("\n"); return 1; } } return 0;}static void before_check_fs_tree (reiserfs_filsys_t * fs) { init_control_bitmap (fs); source_bitmap = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); reiserfs_bitmap_copy (source_bitmap, fs->fs_bitmap2); proper_id_map (fs) = id_map_init();}static void after_check_fs_tree (reiserfs_filsys_t * fs) { if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { reiserfs_flush_to_ondisk_bitmap (fs->fs_bitmap2, fs); reiserfs_flush (fs); fs->fs_dirt = 1; reiserfs_bitmap_delta (source_bitmap, control_bitmap); fsck_deallocate_bitmap(fs) = source_bitmap; } else reiserfs_delete_bitmap (source_bitmap); reiserfs_delete_bitmap (control_bitmap); flush_buffers (fs->fs_dev);}/* pass internal tree of filesystem */void check_fs_tree (reiserfs_filsys_t * fs){ before_check_fs_tree (fs); fsck_progress ("Checking internal tree.."); pass_through_tree (fs, bad_node, bad_path, fsck_mode(fs) == FSCK_AUTO ? 2 : -1); /* internal tree is correct (including all objects have correct sequences of items) */ fsck_progress ("finished\n"); /* compare created bitmap with the original */ if (fsck_mode(fs) == FSCK_AUTO) { if (auto_handle_bitmaps(fs)) { fprintf(stderr, "The on-disk bitmap looks corrupted."); one_more_corruption(fs, FIXABLE); } id_map_free(proper_id_map(fs)); } else handle_bitmaps (fs); after_check_fs_tree (fs);}static int clean_attributes_handler (reiserfs_filsys_t * fs, struct buffer_head ** path, int h) { struct buffer_head * bh = path[h]; int i; if (B_LEVEL (bh) != h_to_level (fs, h)) { reiserfs_panic ("The node (%lu) with wrong level (%d) found in the " "tree, (%d) expected\n", bh->b_blocknr, B_LEVEL (bh), h_to_level (fs, h)); } if (!is_leaf_node (bh)) return 0; for (i = 0; i < B_NR_ITEMS (bh); i ++) { if (is_stat_data_ih (B_N_PITEM_HEAD (bh, i)) && get_ih_item_len (B_N_PITEM_HEAD (bh, i)) == SD_SIZE) { set_sd_v2_sd_attrs((struct stat_data *)B_N_PITEM(bh, i), 0); mark_buffer_dirty (bh); } } return 0;}void do_clean_attributes (reiserfs_filsys_t * fs) { pass_through_tree (fs, clean_attributes_handler, NULL, -1); set_sb_v2_flag (fs->fs_ondisk_sb, reiserfs_attrs_cleared); mark_buffer_dirty (fs->fs_super_bh);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -