⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 check_tree.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	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 + -