📄 pass0.c
字号:
} add_hash_hit (fs, hash_code); if (j == max_length + 1) { /* deh_offset does not match to anything. it will be deleted for now, but maybe we could just fix a deh_offset if it is in ordeer */ mark_de_bad_offset (deh + i); } } } /* for */#ifdef DEBUG_VERIFY_DENTRY printf ("Entries with mismatching hash: "); for (i = 0; i < ih_entry_count (ih); i ++) { if (de_bad_offset (deh + i)) printf ("%d ", i); } printf ("\n");#endif /* DEBUG_VERIFY_DENTRY */ /* correct deh_locations such that code cutting entries will not get screwed up */ { int prev_loc; int loc_fixed; prev_loc = get_ih_item_len (ih); for (i = 0; i < get_ih_entry_count (ih); i ++) { loc_fixed = 0; if (de_bad_location (deh + i)) { set_deh_location (deh + i, prev_loc/* - 1*/); mark_buffer_dirty (bh); loc_fixed = 1; } else { if (get_deh_location (deh + i) >= prev_loc) { set_deh_location (deh + i, prev_loc/* - 1*/); mark_buffer_dirty (bh); loc_fixed = 1; } } prev_loc = get_deh_location (deh + i); if (i == get_ih_entry_count (ih) - 1) { /* last entry starts right after an array of dir entry headers */ if (!de_bad (deh + i) && get_deh_location (deh + i) != (DEH_SIZE * get_ih_entry_count (ih))) { /* free space in the directory item */ fsck_log ("%s: block %lu, item %H: Directory item has a free space - deleting\n", __FUNCTION__, bh->b_blocknr, ih); cut_entry (fs, bh, item_num, get_ih_entry_count (ih), 0); } if (get_deh_location (deh + i) != (DEH_SIZE * get_ih_entry_count (ih))) { set_deh_location (&deh[i], (DEH_SIZE * get_ih_entry_count (ih))); loc_fixed = 1; mark_buffer_dirty (bh); } }#ifdef DEBUG_VERIFY_DENTRY if (loc_fixed) direntries [i] = 1;#endif } /* for */#ifdef DEBUG_VERIFY_DENTRY printf ("Entries with fixed deh_locations: "); for (i = 0; i < ih_entry_count (ih); i ++) { if (direntries [i]) printf ("%d ", i); } printf ("\n");#endif /* DEBUG_VERIFY_DENTRY */ }#ifdef DEBUG_VERIFY_DENTRY printf (" N location name\n"); for (i = 0; i < ih_entry_count (ih); i ++) { if (de_bad (deh + i) || (i && de_bad (deh + i - 1)) || /* previous entry marked bad */ (i < ih_entry_count (ih) - 1 && de_bad (deh + i + 1))) { /* next entry is marked bad */ /* print only entries to be deleted and their nearest neighbors */ printf ("%3d: %8d ", i, deh_location (deh + i)); if (de_bad (deh + i)) printf ("will be deleted\n"); else printf ("\"%.*s\"\n", name_in_entry_length (ih, deh + i, i), name_in_entry (deh + i, i)); } }#endif bad = lost_found = 0; tmp = *ih; /* mark enries of /lost+found as bad */ deh = B_I_DEH (bh, ih); for (i = 0; i < get_ih_entry_count (ih); i ++, deh ++) { unsigned int dirid, objectid; if (de_bad (deh)) continue; sprintf (buf, "%.*s", name_in_entry_length (ih, deh, i), name_in_entry (deh, i)); if (sscanf (buf, "%d_%d", &dirid, &objectid) != 2) continue; if (get_deh_dirid (deh) != dirid || get_deh_objectid (deh) != objectid) continue; /* entry in lost+found */// printf ("%s - will be deleted\n", buf); lost_found++; mark_de_bad_offset (deh); } /* delete entries which are marked bad */ for (i = 0; i < get_ih_entry_count (ih); i ++) { deh = B_I_DEH (bh, ih) + i; if (de_bad (deh)) { bad ++; if (get_ih_entry_count (ih) == 1) { delete_item (fs, bh, item_num); break; } else { cut_entry (fs, bh, item_num, i, 1); } i --; } } if (bad == get_ih_entry_count (&tmp)) { if (lost_found != bad) { fsck_log ("%s: block %lu, item %H: All entries were deleted from the directory\n", __FUNCTION__, bh->b_blocknr, &tmp); } return -1; } deh = B_I_DEH (bh, ih); if (get_offset (&ih->ih_key) != get_deh_offset (deh)) { fsck_log ("verify_direntry: block %lu, item %H: Key's offset %k must match the directory's hash (%u) - changed.\n", bh->b_blocknr, ih, &ih->ih_key, get_deh_offset (deh)); set_offset (key_format (&ih->ih_key), &ih->ih_key, get_deh_offset (deh)); mark_buffer_dirty (bh); } if (bad > lost_found) fsck_log ("pass0: block %lu, item %H: %d entries were deleted\n", bh->b_blocknr, &tmp, bad - lost_found); return 0;}static __inline__ int does_it_fit_into_dev (__u64 offset, __u64 fs_size) {/* Count of unformatted pointers - offset / blocksize Count of blocks to store them - UNFM_P_SIZE * offset / blocksize / MAX_ITEM_LEN Size to store it - blocksize * UNFM_P_SIZE * offset / blocksize / MAX_ITEM_LEN*/ return ( UNFM_P_SIZE * offset / MAX_ITEM_LEN(fs->fs_blocksize) < fs_size) ? 1 : 0;}static int is_wrong_short_key (struct key * key) { if (get_key_dirid (key) == 0 || get_key_objectid (key) == 0 || get_key_objectid (key) == 1 || get_key_dirid (key) == ~(__u32)0 || get_key_objectid (key) == ~(__u32)0 || get_key_dirid (key) == get_key_objectid (key) || /* the alloc=packing_groups used to allow dirid = 1 (get_key_dirid (key) == 1 && get_key_objectid (key) != 2) || */ (get_key_dirid (key) != 1 && get_key_objectid (key) == 2) ) return 1; return 0;}/* 1 if some of fields in the block head of bh look bad */int leaf_structure_check (reiserfs_filsys_t * fs, struct buffer_head * bh) { struct block_head * blkh; int free_space, counted; blkh = B_BLK_HEAD (bh); if (!is_leaf_block_head(bh->b_data)) { /* We should not get here on rebuild. */ fsck_log ("block %lu: The block does not look like a leaf.\n", bh->b_blocknr); one_more_corruption (fs, FATAL); return 1; } if (get_blkh_nr_items (blkh) == 0) return 0; counted = leaf_count_ih(bh->b_data, bh->b_size); if (counted < get_blkh_nr_items (blkh)) { fsck_log ("block %lu: The number of items (%lu) is incorrect, should be (%lu)", bh->b_blocknr, get_blkh_nr_items(blkh), counted); if (fsck_mode(fs) == FSCK_REBUILD) { set_blkh_nr_items(blkh, counted); fsck_log (" - corrected\n"); mark_buffer_dirty (bh); } else { fsck_log ("\n"); one_more_corruption (fs, FATAL); return 1; } } free_space = leaf_free_space_estimate(bh->b_data, bh->b_size); if (get_blkh_free_space (blkh) != free_space) { fsck_log ("block %lu: The free space (%lu) is incorrect, should be (%lu)", bh->b_blocknr, get_blkh_free_space (blkh), free_space); if (fsck_mode(fs) != FSCK_CHECK && fsck_mode(fs) != FSCK_AUTO) { set_blkh_free_space (blkh, free_space); fsck_log (" - corrected\n"); mark_buffer_dirty (bh); } else { fsck_log ("\n"); one_more_corruption (fs, FIXABLE); return 1; } } return 0;}/* do this on pass 0 with every leaf marked used *//* FIXME: we can improve fixing of broken keys: we can ssfe direct items which go after stat data and have broken keys */static void pass0_correct_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh){ int file_format = KEY_FORMAT_UNDEFINED; struct item_head * ih; __u32 * ind_item; __u64 fs_size; __u64 offset; int symlnk = 0; int bad_order; unsigned long unfm_ptr;// unsigned int nr_items; int i, j, nr_items; int dirty = 0; leaf_structure_check(fs, bh); /* Delete all safe links. */ for (i = get_blkh_nr_items (B_BLK_HEAD (bh)) - 1; i >= 0; i--) { if (get_key_dirid (&B_N_PITEM_HEAD (bh, i)->ih_key) == ~(__u32)0) { delete_item (fs, bh, i); } if (get_key_dirid (&B_N_PITEM_HEAD (bh, i)->ih_key) == BADBLOCK_DIRID && get_key_objectid (&B_N_PITEM_HEAD (bh, i)->ih_key) == BADBLOCK_OBJID) { delete_item (fs, bh, i); } } fs_size = (__u64)fs->fs_blocksize * get_sb_block_count (fs->fs_ondisk_sb); start_again: ih = B_N_PITEM_HEAD (bh, 0); bad_order = 0; for (i = 0; i < (nr_items = get_blkh_nr_items (B_BLK_HEAD (bh))); i ++, ih ++) { if (is_indirect_ih(ih) && (get_ih_item_len (ih) % 4 != 0)) { set_type(get_ih_key_format(ih), &ih->ih_key, TYPE_UNKNOWN); dirty = 1; } if (type_unknown (&ih->ih_key)) { if ((get_ih_item_len (ih) == SD_SIZE) || (get_ih_item_len (ih) == SD_V1_SIZE)) { set_type_and_offset (KEY_FORMAT_1, &ih->ih_key, SD_OFFSET, TYPE_STAT_DATA); dirty = 1; fsck_log("pass0: vpf-10100: block %lu, item (%d): Unknown item type of StatData size," " type set to StatData %k\n", bh->b_blocknr, i, &ih->ih_key); } else { fsck_log("pass0: vpf-10110: block %lu, item (%d): Unknown item type found %k - deleted\n", bh->b_blocknr, i, &ih->ih_key); delete_item (fs, bh, i); goto start_again; } } if (is_wrong_short_key (&ih->ih_key)) { /* sometimes stat datas get k_objectid==0 or k_dir_id==0 */ /* if (i == (nr_items - 1)) { if (i == 0) { fsck_log ("block %lu: item %d: (%H) id equals 0\n", bh->b_blocknr, i, ih); return; } // delete last item fsck_log ("block %lu: item %d: (%H) id equals 0\n", bh->b_blocknr, i, ih); delete_item (fs, bh, i - 1); return; }*/ /* FIXME: 18842 19034 0x1 IND (2) 19035 19035 0x0 SD (0) 18842 1 0x1 IND (1) 18842 1 0x1001 DRCT (2) */ /* there is next item: if it is not stat data - take its k_dir_id and k_objectid. if key order will be still wrong - the changed item will be deleted */ if (i && !is_stat_data_ih (ih)) { /* previous item has a wrong short_key */ fsck_log ("pass0: vpf-10120: block %lu: item %d: Wrong key %k, corrected to ", bh->b_blocknr, i, &ih->ih_key); set_key_dirid (&ih->ih_key, get_key_dirid (&(ih - 1)->ih_key)); set_key_objectid (&ih->ih_key, get_key_objectid (&(ih - 1)->ih_key)); fsck_log ("%k\n", &ih->ih_key); dirty = 1; } else if ((i < nr_items - 1) && !is_stat_data_ih (ih + 1)) { if (!is_wrong_short_key(&(ih + 1)->ih_key)) { fsck_log ("pass0: vpf-10130: block %lu: item %d: Wrong key %k, corrected to ", bh->b_blocknr, i, &ih->ih_key); set_key_dirid (&ih->ih_key, get_key_dirid (&(ih + 1)->ih_key)); set_key_objectid (&ih->ih_key, get_key_objectid (&(ih + 1)->ih_key));/* set_offset (KEY_FORMAT_1, &ih->ih_key, 0); set_type (KEY_FORMAT_1, &ih->ih_key, TYPE_STAT_DATA);*/ fsck_log ("%k\n", &ih->ih_key); dirty = 1; goto start_again; } else { fsck_log ("pass0: vpf-10140: block %lu: items %d and %d have bad short keys %k, %k, both deleted\n", bh->b_blocknr, i, i+1, &ih->ih_key, &(ih + 1)->ih_key); delete_item (fs, bh, i); delete_item (fs, bh, i); goto start_again; } } else { fsck_log ("pass0: vpf-10150: block %lu: item %d: Wrong key %k, deleted\n", bh->b_blocknr, i, &ih->ih_key); delete_item (fs, bh, i); goto start_again; } } if (i && i + 1 < nr_items) { if (is_stat_data_ih (ih - 1) && !is_stat_data_ih (ih) && !is_direct_ih (ih + 1) && !is_stat_data_ih (ih + 1)) { /* i or i+1 item should be SD or i+1 should be direct item */ if ((get_ih_item_len (ih) == SD_SIZE) || (get_ih_item_len (ih) == SD_V1_SIZE)) { /* make i as SD */ fsck_log("pass0: vpf-10400: block %lu, item %d: Wrong order of items - " "change the type of the key %k to StatData\n", bh->b_blocknr, i, &ih->ih_key); set_type_and_offset (KEY_FORMAT_1, &ih->ih_key, SD_OFFSET, TYPE_STAT_DATA); dirty = 1; } else if ((get_ih_item_len (ih+1) == SD_SIZE) || (get_ih_item_len (ih+1) == SD_V1_SIZE)) { /* make i+1 as SD */ fsck_log("pass0: vpf-10410: block %lu, item %d: Wrong order of items - " "change the type of the key %k to StatData\n", bh->b_blocknr, i + 1, &(ih + 1)->ih_key); set_type_and_offset (KEY_FORMAT_1, &(ih + 1)->ih_key, SD_OFFSET, TYPE_STAT_DATA); dirty = 1; } else if (is_indirect_ih(ih)) { fsck_log("pass0: vpf-10420: block %lu, item %d: Wrong order of items - " "change the type of the key %k to Direct\n", bh->b_blocknr, i+1, &(ih + 1)->ih_key); set_type (get_ih_key_format(ih+1), &(ih + 1)->ih_key, TYPE_DIRECT); dirty = 1; } } } if (i && ((is_stat_data_ih (ih - 1) && !is_stat_data_ih (ih) && (get_key_dirid (&(ih - 1)->ih_key) != get_key_dirid (&ih->ih_key))) || (is_stat_data_ih (ih) && (get_key_dirid (&(ih - 1)->ih_key) > get_key_dirid (&ih->ih_key))))) { /* not the same dir_id of the same file or not increasing dir_id of different files */ if ((i > 1) && get_key_dirid (&(ih - 2)->ih_key) == get_key_dirid (&(ih - 1)->ih_key)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -