📄 check_tree.c
字号:
inline void handle_one_pointer (reiserfs_filsys_t * fs, struct buffer_head * bh, __u32 * item, int offset){ if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { fsck_log (" - zeroed"); d32_put (item, offset, 0); mark_buffer_dirty (bh); } else { one_more_corruption (fs, FIXABLE); }}static int bad_badblocks_item (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih) { __u32 i; __u32 * ind = (__u32 *)B_I_PITEM (bh, ih); if (get_ih_item_len (ih) % 4) { fsck_log ("%s: block %lu: item (%H) has bad length\n", __FUNCTION__, bh->b_blocknr, ih); one_more_corruption (fs, FATAL); return 1; } /* All valid badblocks are given in badblock bitmap. Nothing to check anymore. */ if (fs->fs_badblocks_bm) return 0; for (i = 0; i < I_UNFM_NUM (ih); i ++) { if (!d32_get (ind, i)) {/* fsck_log ("%s: block %lu: badblocks item (%H) has zero pointer.", __FUNCTION__, bh->b_blocknr, ih); if (fsck_mode(fs) != FSCK_FIX_FIXABLE) { fsck_log("Not an error, but could be deleted with --fix-fixable\n"); } else { fsck_log("Will be deleted later.\n"); }*/ continue; } /* check list of badblocks pointers */ if (d32_get (ind, i) >= get_sb_block_count (fs->fs_ondisk_sb)) { fsck_log ("%s: badblock pointer (block %lu) points out of disk spase (%lu)", __FUNCTION__, bh->b_blocknr, d32_get (ind, i)); handle_one_pointer (fs, bh, ind, i); fsck_log ("\n"); } if (did_we_meet_it (d32_get (ind, i))) { /* it can be 1. not_data_block delete pointer 2. ind [i] or internal/leaf advice to run fix-fixable if there is no fatal errors with list of badblocks, say that it could fix it. */ if (not_data_block (fs, d32_get (ind, i))) { fsck_log ("%s: badblock pointer (block %lu) points on fs metadata (%lu)", __FUNCTION__, bh->b_blocknr, d32_get (ind, i)); handle_one_pointer (fs, bh, ind, i); fsck_log ("\n"); } else { one_more_corruption(fs, FIXABLE); fsck_log ("%s: badblock pointer (block %lu) points to a block (%lu) " "which is in the tree already. Use badblock option (-B) to" " fix the problem\n", __FUNCTION__, bh->b_blocknr, d32_get (ind, i)); } continue; } we_met_it(d32_get(ind, i)); } return 0;}/* for each unformatted node pointer: make sure it points to data area and that it is not in the tree yet */static int bad_indirect_item (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih){ __u32 * ind = (__u32 *)B_I_PITEM (bh, ih); unsigned int i; if (get_ih_item_len (ih) % 4) { fsck_log ("%s: block %lu: The item (%H) has the bad length (%u)\n", __FUNCTION__, bh->b_blocknr, ih, get_ih_item_len (ih)); one_more_corruption (fs, FATAL); return 1; } for (i = 0; i < I_UNFM_NUM (ih); i ++) { fsck_check_stat (fs)->unfm_pointers ++; if (!d32_get (ind, i)) { fsck_check_stat (fs)->zero_unfm_pointers ++; continue; } /* check unformatted node pointer and mark it used in the control bitmap */ if (bad_block_number (fs, d32_get (ind, i))) { fsck_log ("%s: block %lu: The item %k has the bad pointer (%d) to " "the block (%lu)", __FUNCTION__, bh->b_blocknr, &ih->ih_key, i, d32_get (ind, i)); handle_one_pointer (fs, bh, ind, i); fsck_log ("\n"); continue; } if (got_already (fs, d32_get (ind, i))) { fsck_log ("%s: block %lu: The item (%H) has the bad pointer (%d) " "to the block (%lu), which is in tree already", __FUNCTION__, bh->b_blocknr, ih, i, d32_get (ind, i)); handle_one_pointer (fs, bh, ind, i); fsck_log ("\n"); continue; } }#if 0 /* delete this check for 3.6 */ if (get_ih_free_space (ih) > fs->fs_blocksize - 1) { if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { /*FIXME: fix it if needed*/ } else { fsck_log ("bad_indirect_item: %H has wrong ih_free_space\n", ih); one_more_corruption (fs, fixable); } }#endif return 0;}/* FIXME: this was is_bad_directory from pass0.c */static int bad_directory_item (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih){ char *name, *prev_name; __u32 off, prev_off; unsigned int count, i; struct reiserfs_de_head * deh = B_I_DEH (bh, ih); int min_entry_size = 1;/* We have no way to understand whether the filesystem was created in 3.6 format or converted to it. So, we assume that minimal name length is 1 */ __u16 state; int namelen; count = get_ih_entry_count (ih); if (count == 0) { one_more_corruption (fs, FATAL); return 1; } /* make sure item looks like a directory */ if (get_ih_item_len (ih) / (DEH_SIZE + min_entry_size) < count) { /* entry count can not be that big */ fsck_log ("%s: block %lu: The directory item %k has the exsessively " "big entry count (%u)\n", __FUNCTION__, bh->b_blocknr, &ih->ih_key, count); one_more_corruption (fs, FATAL); return 1; } if (get_deh_location (&deh[count - 1]) != DEH_SIZE * count) { /* last entry should start right after array of dir entry headers */ fsck_log ("%s: block %lu: The directory item %k has the corrupted " "entry structure\n", __FUNCTION__, bh->b_blocknr, &ih->ih_key); one_more_corruption (fs, FATAL); return 1; } /* check name hashing */ prev_name = B_I_PITEM(bh, ih) + get_ih_item_len(ih); prev_off = 0; for (i = 0; i < count; i ++, deh ++) { namelen = name_in_entry_length (ih, deh, i); name = name_in_entry (deh, i); off = get_deh_offset (deh); if (namelen > (int)REISERFS_MAX_NAME_LEN(fs->fs_blocksize) || name >= prev_name || off <= prev_off) { fsck_log ("%s: block %lu: The directory item %k has a broken entry " "(%d)\n", __FUNCTION__, bh->b_blocknr, &ih->ih_key, i); one_more_corruption (fs, FATAL); return 1; } if (!is_properly_hashed (fs, name, namelen, off)) { fsck_log ("%s: block %lu: The directory item %k has a not properly " "hashed entry (%d)\n", __FUNCTION__, bh->b_blocknr, &ih->ih_key, i); one_more_corruption (fs, FATAL); return 1; } prev_name = name; prev_off = off; } deh = B_I_DEH (bh, ih); state = (1 << DEH_Visible2); /* ok, items looks like a directory */ for (i = 0; i < count; i ++, deh ++) { if (get_deh_state (deh) != state) { fsck_log ("bad_directory_item: block %lu: The directory item %k " "has the entry (%d) \"%.*s\" with a not legal state " "(%o), (%o) expected", bh->b_blocknr, &ih->ih_key, i, name_in_entry_length (ih, deh, i), name_in_entry (deh, i), get_deh_state (deh), state); if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { set_deh_state (deh, 1 << DEH_Visible2); mark_buffer_dirty (bh); fsck_log (" - corrected\n"); } else one_more_corruption (fs, FIXABLE); fsck_log ("\n"); } } return 0;}static int bad_item (reiserfs_filsys_t * fs, struct buffer_head * bh, int num){ struct item_head * ih; int format; ih = B_N_PITEM_HEAD (bh, num); if ((get_ih_flags(ih)) != 0) { if (fsck_mode(fs) != FSCK_FIX_FIXABLE) { one_more_corruption (fs, FIXABLE); fsck_log ("%s: vpf-10570: block %lu: The item header (%d) has not " "cleaned flags.\n", __FUNCTION__, bh->b_blocknr, num); } else { fsck_log ("%s: vpf-10580: block %lu: Flags in the item header " "(%d) were cleaned\n", __FUNCTION__, bh->b_blocknr, num); clean_ih_flags(ih); mark_buffer_dirty(bh); } } if (is_stat_data_ih(ih) && get_ih_item_len(ih) == SD_SIZE) format = KEY_FORMAT_2; else if (is_stat_data_ih(ih) && get_ih_item_len(ih) == SD_V1_SIZE) format = KEY_FORMAT_1; else format = key_format(&ih->ih_key); if (format != get_ih_key_format(ih)) { if (fsck_mode(fs) != FSCK_FIX_FIXABLE) { one_more_corruption (fs, FIXABLE); fsck_log ("%s: vpf-10710: block %lu: The format (%d) specified " "in the item header (%d) differs from the key format " "(%d).\n", __FUNCTION__, bh->b_blocknr, get_ih_key_format(ih), num, format); } else { fsck_log ("%s: vpf-10720: block %lu: The format (%d) specified in " "the item header (%d) was fixed to the key format (%d).\n", __FUNCTION__, bh->b_blocknr, get_ih_key_format(ih), num, format); set_ih_key_format(ih, format); mark_buffer_dirty(bh); } } if (get_key_objectid (&ih->ih_key) == BADBLOCK_OBJID) { if (get_key_dirid (&ih->ih_key) == BADBLOCK_DIRID && is_indirect_ih (ih)) { /* Bad Block support. */ return bad_badblocks_item (fs, bh, ih); } goto error; } else { if (get_key_dirid (&ih->ih_key) == (__u32)-1) { /* Safe Link support. Allowable safe links are: -1 object_id 0x1 INDIRECT (truncate) or -1 object_id blocksize+1 DIRECT (unlink) */ if (is_direct_ih(ih) && get_offset(&ih->ih_key) == fs->fs_blocksize + 1) { if (get_ih_item_len (ih) == 4) { /*fsck_log("vpf-00010: safe link found %k\n", &ih->ih_key);*/ fsck_check_stat(fs)->safe ++; return 0; } } if (is_indirect_ih(ih) && get_offset(&ih->ih_key) == 0x1) { if (get_ih_item_len (ih) == 4) { /*fsck_log("vpf-00020: safe link found %k\n", &ih->ih_key);*/ fsck_check_stat(fs)->safe ++; return 0; } } /* it does not look like safe link */ goto error; } } if (is_stat_data_ih (ih)) return bad_stat_data (fs, bh, ih); if (is_direct_ih (ih)) return bad_direct_item (fs, bh, ih); if (is_indirect_ih(ih)) return bad_indirect_item (fs, bh, ih); return bad_directory_item (fs, bh, ih); error: one_more_corruption (fs, FATAL); fsck_log ("%s: vpf-10310: block %lu, item %d: The item has a wrong " "key %k\n", __FUNCTION__, num, bh->b_blocknr, &ih->ih_key); return 1;}/* 1 if i-th and (i-1)-th items can not be neighbors in a leaf */int bad_pair (reiserfs_filsys_t * fs, struct buffer_head * bh, int pos) { struct item_head * ih; ih = B_N_PITEM_HEAD (bh, pos); if (comp_keys (&((ih - 1)->ih_key), &ih->ih_key) != -1) { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); return 1; } if (is_stat_data_ih (ih)) /* left item must be of another object */ if (comp_short_keys (&((ih - 1)->ih_key), &ih->ih_key) != -1) { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); return 1; } if (get_key_objectid (&ih->ih_key) == BADBLOCK_OBJID) { /* BAD BLOCK LIST SUPPORT. */ if (get_key_dirid(&ih->ih_key) == BADBLOCK_DIRID && is_indirect_ih(ih) && comp_short_keys(&((ih - 1)->ih_key), &ih->ih_key)) return 0; } else { /* Safe link support. */ if (get_key_dirid (&ih->ih_key) == (__u32)-1) { if (comp_short_keys (&((ih - 1)->ih_key), &ih->ih_key) == 0) { if (is_indirect_ih (ih - 1) && is_direct_ih(ih)) return 0; /* safe link */ /* they do not look like safe links */ } else { if (is_indirect_ih (ih) || is_direct_ih(ih)) return 0; /* safe link */ /* it does not look like safe link */ } } } if (is_direct_ih(ih)) { /* left item must be indirect or stat data item of the same file */ if (not_of_one_file (&((ih - 1)->ih_key), &ih->ih_key)) { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -