📄 ustree.c
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */#include "fsck.h"struct tree_balance * cur_tb = 0;void reiserfsck_paste_into_item (struct path * path, const char * body, int size){ struct tree_balance tb; init_tb_struct (&tb, fs, path, size); if (fix_nodes (/*tb.transaction_handle,*/ M_PASTE, &tb, 0/*ih*/) != CARRY_ON) //fix_nodes(options, tree_balance, ih_to_option, body_to_option) die ("reiserfsck_paste_into_item: fix_nodes failed"); do_balance (/*tb.transaction_handle,*/ &tb, 0, body, M_PASTE, 0/*zero num*/);}void reiserfsck_insert_item (struct path * path, struct item_head * ih, const char * body){ struct tree_balance tb; init_tb_struct (&tb, fs, path, IH_SIZE + get_ih_item_len(ih)); if (fix_nodes (/*tb.transaction_handle,*/ M_INSERT, &tb, ih/*, body*/) != CARRY_ON) die ("reiserfsck_insert_item: fix_nodes failed"); do_balance (/*tb.transaction_handle,*/ &tb, ih, body, M_INSERT, 0/*zero num*/);}static void free_unformatted_nodes (struct item_head * ih, struct buffer_head * bh){ __u32 * punfm = (__u32 *)B_I_PITEM (bh, ih); unsigned int i; for (i = 0; i < I_UNFM_NUM (ih); i ++) { __u32 unfm = d32_get (punfm, i); if (unfm != 0) { struct buffer_head * to_be_forgotten; to_be_forgotten = find_buffer (fs->fs_dev, unfm, fs->fs_blocksize); if (to_be_forgotten) { //atomic_inc(&to_be_forgotten->b_count); to_be_forgotten->b_count ++; bforget (to_be_forgotten); } reiserfs_free_block (fs, unfm); } }}void reiserfsck_delete_item (struct path * path, int temporary){ struct tree_balance tb; struct item_head * ih = PATH_PITEM_HEAD (path); if (is_indirect_ih (ih) && !temporary) free_unformatted_nodes (ih, PATH_PLAST_BUFFER (path)); init_tb_struct (&tb, fs, path, -(IH_SIZE + get_ih_item_len(ih))); if (fix_nodes (/*tb.transaction_handle,*/ M_DELETE, &tb, 0/*ih*/) != CARRY_ON) die ("reiserfsck_delete_item: fix_nodes failed"); do_balance (/*tb.transaction_handle,*/ &tb, 0, 0, M_DELETE, 0/*zero num*/);}void reiserfsck_cut_from_item (struct path * path, int cut_size){ struct tree_balance tb; struct item_head * ih; if (cut_size >= 0) die ("reiserfsck_cut_from_item: cut size == %d", cut_size); if (is_indirect_ih (ih = PATH_PITEM_HEAD (path))) { struct buffer_head *bh = PATH_PLAST_BUFFER (path); __u32 unfm_ptr = d32_get ((__u32 *)B_I_PITEM(bh, ih), I_UNFM_NUM (ih) - 1); if (unfm_ptr != 0) { struct buffer_head * to_be_forgotten; to_be_forgotten = find_buffer (fs->fs_dev, unfm_ptr, fs->fs_blocksize); if (to_be_forgotten) { //atomic_inc(&to_be_forgotten->b_count); to_be_forgotten->b_count ++; bforget (to_be_forgotten); } reiserfs_free_block (fs, unfm_ptr); } } init_tb_struct (&tb, fs, path, cut_size); if (fix_nodes (/*tb.transaction_handle,*/ M_CUT, &tb, 0) != CARRY_ON) die ("reiserfsck_cut_from_item: fix_nodes failed"); do_balance (/*tb.transaction_handle,*/ &tb, 0, 0, M_CUT, 0/*zero num*/);}/* uget_rkey is utils clone of stree.c/get_rkey *//*struct key * uget_rkey (struct path * path){ int pos, offset = path->path_length; struct buffer_head * bh; if (offset < FIRST_PATH_ELEMENT_OFFSET) die ("uget_rkey: illegal offset in the path (%d)", offset); while (offset-- > FIRST_PATH_ELEMENT_OFFSET) { if (! buffer_uptodate (PATH_OFFSET_PBUFFER (path, offset))) die ("uget_rkey: parent is not uptodate"); // Parent at the path is not in the tree now. if (! B_IS_IN_TREE (bh = PATH_OFFSET_PBUFFER (path, offset))) die ("uget_rkey: buffer on the path is not in tree"); // Check whether position in the parrent is correct. if ((pos = PATH_OFFSET_POSITION (path, offset)) > B_NR_ITEMS (bh)) die ("uget_rkey: invalid position (%d) in the path", pos); // Check whether parent at the path really points to the child. if (get_dc_child_blocknr (B_N_CHILD (bh, pos)) != PATH_OFFSET_PBUFFER (path, offset + 1)->b_blocknr) die ("uget_rkey: invalid block number (%d). Must be %ld", get_dc_child_blocknr (B_N_CHILD (bh, pos)), PATH_OFFSET_PBUFFER (path, offset + 1)->b_blocknr); // Return delimiting key if position in the parent is not the last one. if (pos != B_NR_ITEMS (bh)) return B_N_PDELIM_KEY(bh, pos); } // there is no right delimiting key return 0;}*/static unsigned long first_child (struct buffer_head * bh){ return get_dc_child_blocknr (B_N_CHILD (bh, 0));}#if 0static unsigned long last_child (struct buffer_head * bh){ return child_block_number (bh, node_item_number (bh));}#endifstatic unsigned long get_child (int pos, struct buffer_head * parent){ if (pos == -1) return -1; if (pos > B_NR_ITEMS (parent)) die ("get_child: no child found, should not happen: %d of %d", pos, B_NR_ITEMS (parent)); return get_dc_child_blocknr (B_N_CHILD (parent, pos));}static void print (int cur, int total){ if (fsck_quiet (fs)) return; printf ("/%3d (of %3d)", cur, total);fflush (stdout);}/* erase /XXX(of XXX) */static void erase (void){ if (fsck_quiet (fs)) return; printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b"); printf (" "); printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b"); fflush (stdout);}void pass_through_tree (reiserfs_filsys_t * fs, do_after_read_t action1, do_on_full_path_t action2, int depth){ struct buffer_head * path[MAX_HEIGHT] = {0,}; int total[MAX_HEIGHT] = {0,}; int cur[MAX_HEIGHT] = {0,}; int h = 0; unsigned long block = get_sb_root_block (fs->fs_ondisk_sb); int problem; if (block >= get_sb_block_count (fs->fs_ondisk_sb) || not_data_block (fs, block)) { die ("\nBad root block %lu. (--rebuild-tree did not complete)\n", block); } while ( 1 ) { problem = 0; if (path[h]) die ("pass_through_tree: empty slot expected"); if (h) print (cur[h - 1], total[h - 1]); if (fs->fs_badblocks_bm && reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, block)) { fsck_log ("%s: block %lu specified in badblock list found in tree, whole subtree skipped\n", __FUNCTION__, block); fsck_data (fs)->check.bad_nodes++; one_more_corruption (fs, FATAL); if (h == 0) { brelse (path[h]); path[h] = 0; break; } problem = 1; } else { path[h] = bread (fs->fs_dev, block, fs->fs_blocksize); if (path[h] == 0) /* FIXME: handle case when read failed */ die ("pass_through_tree: unable to read %lu block on device 0x%x\n", block, fs->fs_dev); if (action1) if ((problem = action1 (fs, path, h))) { fsck_log (" the problem in the internal node occured (%lu), whole subtree is skipped\n", path[h]->b_blocknr); fsck_data (fs)->check.bad_nodes++; if (h == 0) { brelse (path[h]); path[h] = 0; break; } } } /* Time to stop. */ if (h == depth) problem ++; if (problem || is_leaf_node (path[h])) { if (!problem && action2) action2 (fs, path, h); brelse (path[h]); if (h) erase (); while (h && (cur[h-1] == total[h-1] || problem)) { problem = 0; path[h] = 0; h --; brelse (path[h]); if (h) erase (); } if (h == 0) { path[h] = 0; break; } block = get_child (cur[h - 1], path[h-1]); cur[h - 1] ++; path[h] = 0; continue; } total[h] = B_NR_ITEMS (path[h]) + 1; cur[h] = 1; block = first_child (path[h]); h ++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -