📄 pass0.c
字号:
} dirty += correct_key_format (ih, symlnk); if (is_stat_data_ih (ih)) { __u16 mode; file_format = get_ih_key_format (ih); get_sd_mode (ih, B_N_PITEM(bh,i), &mode); symlnk = ( S_ISLNK(mode) ? 1 : 0); ;/*correct_stat_data (fs, bh, i);*/ } else if ( !is_direntry_ih(ih) && !(symlnk && is_direct_ih(ih)) && (file_format != KEY_FORMAT_UNDEFINED) && (file_format != get_ih_key_format (ih))) { fsck_log("pass0: vpf-10240: block %lu, item (%d): Item %k, which format (%d) is not equal to StatData " "format (%d), is deleted\n", bh->b_blocknr, i, &ih->ih_key, get_ih_key_format(ih), file_format); delete_item (fs, bh, i); goto start_again; } else { file_format = KEY_FORMAT_UNDEFINED; symlnk = 0; } if (i && is_stat_data_ih (ih - 1) && !not_of_one_file (&ih->ih_key, &(ih - 1)->ih_key)) { __u16 mode; get_sd_mode (ih - 1, B_I_PITEM (bh, ih - 1), &mode); if (not_a_directory (B_I_PITEM (bh, ih - 1)) && is_direntry_ih (ih)) { /* make SD mode SD of dir */ fsck_log ("pass0: block %lu, item %d: The directory %K has the wrong mode (%M), corrected to ", bh->b_blocknr, i, &ih->ih_key, mode); mode &= ~S_IFMT; mode |= S_IFDIR; fsck_log ("(%M)\n", mode); set_sd_mode (ih - 1, B_I_PITEM (bh, ih - 1), &mode); dirty = 1; } else if (!not_a_directory (B_I_PITEM (bh, ih - 1)) && !is_direntry_ih (ih)) { /* make SD mode SD of regular file */ fsck_log ("pass0: block %lu, item %d: Not the directory %K has the wrong mode (%M), corrected to ", bh->b_blocknr, i, &ih->ih_key, mode); mode &= ~S_IFMT; mode |= S_IFREG; fsck_log ("(%M)\n", mode); set_sd_mode (ih - 1, B_I_PITEM (bh, ih - 1), &mode); dirty = 1; } if (not_a_regfile (B_I_PITEM (bh, ih - 1)) && is_indirect_ih (ih)) { fsck_log ("pass0: block %lu, item %d: The file %K has the wrong mode (%M), corrected to ", bh->b_blocknr, i, &ih->ih_key, mode); mode &= ~S_IFMT; mode |= S_IFREG; fsck_log ("(%M)\n", mode); set_sd_mode (ih - 1, B_I_PITEM (bh, ih - 1), &mode); dirty = 1; } } if (is_direntry_ih (ih)) { j = verify_directory_item (fs, bh, i); if (j == 1) { /* wrong hash, skip the leaf */ pass_0_stat (fs)->too_old_leaves ++; mark_buffer_clean (bh); return; } else if (j == -1) { /* item was deleted */ goto start_again; } continue; } /*DEBUG*/ if (!is_stat_data_ih (ih) && get_offset (&ih->ih_key) == 0) reiserfs_panic ("block %lu, item %d: Zero offset can have StatData items only, but found %k\n", bh->b_blocknr, i, &ih->ih_key); if (!is_indirect_ih (ih)) continue; /* Darko Palic's filesystem had item: [20079 17328 0xfffb1001 IND, len 4048], format old */ { struct key tmp_key; tmp_key = ih->ih_key; set_offset (key_format (&tmp_key), &tmp_key, get_offset (&tmp_key) + get_bytes_number (ih, bh->b_size) - 1); if (get_offset (&tmp_key) < get_offset (&ih->ih_key)) { fsck_log ("pass0: block %lu, item %d: The item, which has wrong offset %k, is deleted\n", bh->b_blocknr, i, &ih->ih_key); delete_item (fs, bh, i); goto start_again; } } /* temporary ugly fix *//* if (i && is_stat_data_ih (ih - 1) && !not_of_one_file (&ih->ih_key, &(ih - 1)->ih_key)) { __u16 mode; get_sd_mode (ih - 1, B_I_PITEM (bh, ih - 1), &mode); if (!S_ISREG (mode)) { fsck_log ("pass0: block %lu: mode (%M) of file %K having indirect item is fixed to ", bh->b_blocknr, mode, &ih->ih_key); mode &= ~S_IFMT; mode |= S_IFREG; set_sd_mode (ih - 1, B_I_PITEM (bh, ih - 1), &mode); fsck_log ("(%M)\n", mode); dirty = 1; } }*/ ind_item = (__u32 *)B_I_PITEM (bh, ih); for (j = 0; j < (int)I_UNFM_NUM (ih); j ++) { unfm_ptr = d32_get (ind_item, j); if (!unfm_ptr) continue;#if 0 if (fsck_mode (fs) == FSCK_ZERO_FILES) { /* FIXME: this is temporary mode of fsck */ ind_item [j] = 0; reiserfs_bitmap_clear_bit (fsck_new_bitmap(fs), unfm_ptr); tmp_zeroed ++; dirty = 1; continue; }#endif if (not_data_block (fs, unfm_ptr) || /* journal area or bitmap or super block */ unfm_ptr >= get_sb_block_count (fs->fs_ondisk_sb) || /* garbage in pointer */ (fs->fs_badblocks_bm && /* bad block */ reiserfs_bitmap_test_bit(fs->fs_badblocks_bm, unfm_ptr))) { pass_0_stat (fs)->wrong_pointers ++; /* fsck_log ("pass0: %d-th pointer (%lu) in item %k (leaf block %lu) is wrong\n", j, unfm_ptr, &ih->ih_key, bh->b_blocknr); */ d32_put(ind_item, j, 0); dirty = 1; continue; } /* mark block in bitmaps of unformatted nodes */ register_unfm (unfm_ptr); } } /* mark all objectids in use */ ih = B_N_PITEM_HEAD (bh, 0); for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) { struct reiserfs_de_head * deh; id_map_mark(proper_id_map (fs), get_key_dirid (&ih->ih_key)); id_map_mark(proper_id_map (fs), get_key_objectid (&ih->ih_key)); if (is_direntry_ih(ih)) { for (j = 0, deh = B_I_DEH (bh, ih); j < get_ih_entry_count (ih); j ++, deh++) id_map_mark(proper_id_map(fs), get_deh_objectid(deh)); } } if (get_blkh_nr_items (B_BLK_HEAD (bh)) < 1) { /* pass 1 will skip this */ pass_0_stat (fs)->all_contents_removed ++;// fsck_log ("pass0: block %lu: All items were deleted.\n", bh->b_blocknr); dirty = 0; mark_buffer_clean (bh); } else { /* pass1 will use this bitmap */ pass0_mark_leaf (bh->b_blocknr); /*fsck_data (fs)->rebuild.leaves ++;*/ } if (dirty) { pass_0_stat (fs)->leaves_corrected ++; mark_buffer_dirty (bh); }}static int is_bad_sd (struct item_head * ih, char * item){ struct stat_data * sd = (struct stat_data *)item; if (get_key_offset_v1 (&ih->ih_key) || get_key_uniqueness (&ih->ih_key)) { fsck_log ("vpf-10610: StatData item %k has non zero offset found.\n", &ih->ih_key); return 1; } if (get_ih_item_len (ih) == SD_V1_SIZE) { /* looks like old stat data */ if (get_ih_key_format (ih) != KEY_FORMAT_1) fsck_log ("vpf-10620: StatData item %k has wrong format.\n", &ih->ih_key); return 0; } if (!S_ISDIR (sd_v2_mode(sd)) && !S_ISREG(sd_v2_mode(sd)) && !S_ISCHR (sd_v2_mode(sd)) && !S_ISBLK(sd_v2_mode(sd)) && !S_ISLNK (sd_v2_mode(sd)) && !S_ISFIFO(sd_v2_mode(sd)) && !S_ISSOCK(sd_v2_mode(sd))) { /*fsck_log ("file %k unexpected mode encountered 0%o\n", &ih->ih_key, sd_v2_mode(sd))*/; } return 0;}int is_bad_directory (struct item_head * ih, char * item, int dev, int blocksize){ int i; char * name; int namelen, entrylen; struct reiserfs_de_head * deh = (struct reiserfs_de_head *)item; __u32 prev_offset = 0; __u16 prev_location = get_ih_item_len (ih); int min_entry_size = 1;/* we have no way to understand whether the filesystem wes created in 3.6 format or converted to it. So, we assume that minimal name length is 1 */ if (get_ih_item_len (ih) / (DEH_SIZE + min_entry_size) < get_ih_entry_count (ih)) /* entry count is too big */ return 1; for (i = 0; i < get_ih_entry_count (ih); i ++, deh ++) { entrylen = entry_length(ih, deh, i); if (entrylen > (int)REISERFS_MAX_NAME_LEN (blocksize)) return 1; if (get_deh_offset (deh) <= prev_offset) return 1; prev_offset = get_deh_offset (deh); if (get_deh_location(deh) + entrylen != prev_location) return 1; prev_location = get_deh_location (deh); namelen = name_in_entry_length (ih, deh, i); name = name_in_entry (deh, i); if (!is_properly_hashed (fs, name, namelen, get_deh_offset (deh))) return 1; } return 0;}/* change incorrect block adresses by 0. Do not consider such item as incorrect */static int is_bad_indirect (struct item_head * ih, char * item, int dev, int blocksize){ unsigned long blocks; unsigned int i; int bad = 0; if (get_ih_item_len(ih) % UNFM_P_SIZE) { fsck_log ("is_bad_indirect: indirect item of %H of invalid length\n", ih); return 1; } blocks = get_sb_block_count (fs->fs_ondisk_sb); for (i = 0; i < I_UNFM_NUM (ih); i ++) { __u32 * ind = (__u32 *)item; if (d32_get (ind, i) >= blocks) { bad ++; fsck_log ("is_bad_indirect: %d-th pointer of item %H looks bad (%lu)\n", i, ih, d32_get (ind, i)); continue; } } return bad;}/* this is used by pass1.c:save_item and check.c:is_leaf_bad */int is_bad_item (struct buffer_head * bh, struct item_head * ih, char * item){ int blocksize, dev; blocksize = bh->b_size; dev = bh->b_dev; // FIXME: refuse transparently bad items if (get_key_dirid (&ih->ih_key) == get_key_objectid (&ih->ih_key)) return 1; if (!get_key_dirid (&ih->ih_key) || !get_key_objectid (&ih->ih_key)) return 1; if (is_stat_data_ih(ih)) return is_bad_sd (ih, item); if (is_direntry_ih (ih)) return is_bad_directory (ih, item, dev, blocksize); if (is_indirect_ih (ih)) return is_bad_indirect (ih, item, dev, blocksize); if (is_direct_ih (ih)) return 0; return 1;}int is_leaf_bad (struct buffer_head * bh){ int i; struct item_head * ih; int bad = 0; assert (is_leaf_node (bh)); for (i = 0, ih = B_N_PITEM_HEAD (bh, 0); i < B_NR_ITEMS (bh); i ++, ih ++) { if (is_bad_item (bh, ih, B_I_PITEM (bh, ih))) { fsck_log ("is_leaf_bad: block %lu, item %d: The corrupted item found (%H)\n", bh->b_blocknr, i, ih); bad = 1; continue; } if (i && bad_pair (fs, bh, i)) { fsck_log ("is_leaf_bad: block %lu items %d and %d: Wrong order of items:" "\n\t%H\n\t%H\n", bh->b_blocknr, i - 1, i, ih - 1, ih); bad = 1; } } return bad;}static int is_to_be_read (reiserfs_filsys_t * fs, unsigned long block){ return reiserfs_bitmap_test_bit (fsck_source_bitmap (fs), block);}static void do_pass_0 (reiserfs_filsys_t * fs){ struct buffer_head * bh; unsigned long i; int what_node; unsigned long done = 0, total; if (fsck_mode (fs) == DO_TEST) { /* just to test pass0_correct_leaf */ bh = bread (fs->fs_dev, fsck_data (fs)->rebuild.test, fs->fs_blocksize); if (!bh) { /* we were reading one block at time, and failed, so mark block bad */ fsck_progress ("%s: Reading of the block %lu failed\n", __FUNCTION__, fsck_data (fs)->rebuild.test); reiserfs_free (fs); exit(0); } if (is_leaf_bad (bh)) { fsck_progress ("############### bad #################\n"); } pass0_correct_leaf (fs, bh); print_block (stdout, fs, bh, 3, -1, -1); if (is_leaf_bad (bh)) { fsck_progress ("############### still bad #################\n"); } brelse (bh); reiserfs_free (fs); exit(0); } total = reiserfs_bitmap_ones (fsck_source_bitmap (fs)); for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { if (!is_to_be_read (fs, i)) continue; print_how_far (fsck_progress_file (fs), &done, total, 1, fsck_quiet (fs)); bh = bread (fs->fs_dev, i, fs->fs_blocksize); if (!bh) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -