📄 semantic_check.c
字号:
if (fix_obviously_wrong_sd_mode (&path)) { one_more_corruption (fs, FIXABLE); pathrelse (&path); return OK; } if (nlink == 0) { fsck_log ("%s: block %lu: The StatData %k has bad nlink number (%u)\n", __FUNCTION__, get_bh(&path)->b_blocknr, &ih->ih_key, nlink); one_more_corruption (fs, FATAL); } if (not_a_directory (sd)) { fsck_check_stat (fs)->files ++; retval = check_check_regular_file (&path, sd, /* relocate ? new_ih : */ 0); pathrelse (&path); return retval; }/* if (relocate) { if (!new_ih) reiserfs_panic ("check_semantic_pass: Memory is not prepared for relocation of " "%K", &ih->ih_key); *new_ih = *ih; pathrelse (&path); sem_pass_stat (fs)->oid_sharing_dirs_relocated ++; relocate_dir (new_ih, 1); linked_already(&new_ih->ih_key); one_less_corruption (fs, FIXABLE); *key = new_ih->ih_key; retval = RELOCATED; goto start_again; }*//* if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { // it looks like stat data of a directory found if (nlink) { // we saw this directory already if (!dot_dot) { // this name is not ".." - and hard links are not allowed on directories pathrelse (&path); return STAT_DATA_NOT_FOUND; } else { // ".." found nlink ++; set_sd_nlink (ih, sd, &nlink); mark_buffer_dirty (get_bh (&path)); pathrelse (&path); return OK; } } // do not run it for dot_dot on check at all nlink = 2; if (get_key_objectid (key) == REISERFS_ROOT_OBJECTID) nlink ++; set_sd_nlink (ih, sd, &nlink); mark_buffer_dirty (get_bh (&path)); }*/ /* directory stat data found */ if (get_ih_item_len (ih) == SD_SIZE) is_new_dir = 1; else is_new_dir = 0; /* save stat data's size and st_blocks */ get_sd_size (ih, sd, &sd_size); get_sd_blocks (ih, sd, &sd_blocks); get_sd_mode (ih, sd, &mode); dir_format = (get_ih_item_len (get_ih (&path)) == SD_SIZE) ? KEY_FORMAT_2 : KEY_FORMAT_1; /* release path pointing to stat data */ pathrelse (&path); fsck_check_stat (fs)->dirs ++; set_key_dirid (&next_item_key, get_key_dirid (key)); set_key_objectid (&next_item_key, get_key_objectid (key)); set_key_offset_v1 (&next_item_key, DOT_OFFSET); set_key_uniqueness (&next_item_key, DIRENTRY_UNIQUENESS); dir_size = 0; while ((dir_item = get_next_directory_item (&next_item_key, parent, &tmp_ih, &pos_in_item, dir_format)) != 0) { /* dir_item is copy of the item in separately allocated memory, item_key is a key of next item in the tree */ int i; char * name = 0; int namelen, entry_len; struct reiserfs_de_head * deh = (struct reiserfs_de_head *)dir_item + pos_in_item; for (i = pos_in_item; i < get_ih_entry_count (&tmp_ih); i ++, deh ++) { struct item_head relocated_ih; int ret = OK; if (name) { free (name); name = 0; } namelen = name_in_entry_length (&tmp_ih, deh, i); asprintf (&name, "%.*s", namelen, name_in_entry (deh, i)); entry_len = entry_length (&tmp_ih, deh, i); get_object_key (deh, &object_key, &entry_key, &tmp_ih); if ((dir_format == KEY_FORMAT_2) && (entry_len % 8 != 0)) { /* not alighed directory of new format - delete it */ if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { fsck_log ("Entry %K (\"%.*s\") in the directory %K is not formated " "properly - deleted\n", (struct key *)&(deh->deh2_dir_id), namelen, name, &tmp_ih.ih_key); reiserfs_remove_entry (fs, &entry_key); entry_len = name_length (name, dir_format); reiserfs_add_entry (fs, key, name, entry_len, (struct key *)&(deh->deh2_dir_id), 0); } else { fsck_log ("Entry %K (\"%.*s\") in the directory %K is not formated " "properly.\n", (struct key *)&(deh->deh2_dir_id), namelen, name, &tmp_ih.ih_key); one_more_corruption (fs, FIXABLE); } } print_name (name, namelen); if (!is_properly_hashed (fs, name, namelen, get_deh_offset (deh))) { one_more_corruption (fs, FATAL); fsck_log ("check_semantic_pass: Hash mismatch detected for (%.*s) in " "directory %K\n", namelen, name, &tmp_ih.ih_key); } if (is_dot (name, namelen) || (is_dot_dot (name, namelen))) { /* do not go through "." and ".." */ ret = OK; } else { if ((ret = add_path_key (&object_key)) == 0) { ret = check_semantic_pass (&object_key, key, is_dot_dot(name, namelen), &relocated_ih); del_path_key (); } } erase_name (namelen); /* check what check_semantic_tree returned */ switch (ret) { case OK: dir_size += DEH_SIZE + entry_len; break; case STAT_DATA_NOT_FOUND: fsck_log ("check_semantic_pass: Name \"%.*s\" in directory %K points to " "nowhere\n", namelen, name, &tmp_ih.ih_key); case LOOP_FOUND: if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { reiserfs_remove_entry (fs, &entry_key); fsck_log (" - removed"); } else { one_more_corruption (fs, FIXABLE); } fsck_log ("\n"); break; case DIRECTORY_HAS_NO_ITEMS: fsck_log ("check_semantic_pass: Name \"%.*s\" in directory %K points a " "directory without body\n", namelen, name, &tmp_ih.ih_key); /* fixme: stat data should be deleted as well */ /* if (fsck_fix_fixable (fs)) { reiserfs_remove_entry (fs, &entry_key); fsck_data(fs)->deleted_entries ++; fsck_log (" - removed"); } fsck_log ("\n");*/ break; case RELOCATED: /* file was relocated, update key in corresponding directory entry */ if (reiserfs_search_by_entry_key (fs, &entry_key, &path) != POSITION_FOUND) { fsck_log("Cannot find a name of the relocated file %K in the directory " "%K\n", &entry_key, &tmp_ih.ih_key); } else { /* update key dir entry points to */ struct reiserfs_de_head * tmp_deh; tmp_deh = B_I_DEH (get_bh (&path), get_ih (&path)) + path.pos_in_item; fsck_log ("The directory %K pointing to %K (\"%.*s\") updated to point " "to ", &tmp_ih.ih_key, &tmp_deh->deh2_dir_id, namelen, name); set_deh_dirid (tmp_deh, get_key_dirid (&relocated_ih.ih_key)); set_deh_objectid (tmp_deh, get_key_objectid (&relocated_ih.ih_key)); fsck_log ("%K (\"%.*s\")\n", &tmp_deh->deh2_dir_id, namelen, name); mark_buffer_dirty (get_bh (&path)); } dir_size += DEH_SIZE + entry_len; pathrelse (&path); break; } } /* for */ freemem (dir_item); free (name); name = 0; if (not_of_one_file (&next_item_key, key)) /* next key is not of this directory */ break; } /* while (dir_item) */ if (dir_size == 0) /* FIXME: is it possible? */ return DIRECTORY_HAS_NO_ITEMS; /* calc correct value of sd_blocks field of stat data */ blocks = dir_size2st_blocks (dir_size); fix_sd = 0; fix_sd += wrong_st_blocks (key, &blocks, sd_blocks, mode, is_new_dir); fix_sd += wrong_st_size (key, is_new_dir ? MAX_FILE_SIZE_V2 : MAX_FILE_SIZE_V1, fs->fs_blocksize, &dir_size, sd_size, TYPE_DIRENTRY); if (fix_sd) { if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { /* we have to fix either sd_size or sd_blocks, so look for stat data again */ if (reiserfs_search_by_key_4 (fs, key, &path) != ITEM_FOUND) { fsck_log ("check_semantic_tree: The StatData of the file %K was not found\n", key); one_more_corruption(fs, FATAL); return STAT_DATA_NOT_FOUND; } bh = get_bh (&path); ih = get_ih (&path); sd = get_item (&path); set_sd_size (ih, sd, &dir_size); set_sd_blocks (ih, sd, &blocks); mark_buffer_dirty (bh); pathrelse (&path); } else { fsck_check_stat (fs)->fixable_corruptions += fix_sd; } } return retval;}int check_safe_links (){ struct path safe_link_path, path; struct key safe_link_key = {-1, 0, {{0, 0}}}; struct key key = {0, 0, {{0, 0}}}; struct key * rkey; struct item_head * tmp_ih; while (1) { if (get_key_dirid (&safe_link_key) == 0) break; reiserfs_search_by_key_4 (fs, &safe_link_key, &safe_link_path); if (get_blkh_nr_items ( B_BLK_HEAD (get_bh(&safe_link_path))) <= PATH_LAST_POSITION (&safe_link_path)) { pathrelse (&safe_link_path); break; } tmp_ih = get_ih(&safe_link_path); if (get_key_dirid(&tmp_ih->ih_key) != (__u32)-1 || get_key_objectid(&tmp_ih->ih_key) == (__u32)-1) { pathrelse (&safe_link_path); break; } if (get_ih_item_len (tmp_ih) != 4) reiserfs_panic ("Safe Link %k cannot be of the size %d", &tmp_ih->ih_key, get_ih_item_len (tmp_ih)); set_key_dirid(&key, d32_get((__u32 *)get_item(&safe_link_path), 0)); set_key_objectid(&key, get_key_objectid(&tmp_ih->ih_key)); if ((rkey = reiserfs_next_key(&safe_link_path)) == NULL) set_key_dirid (&safe_link_key, 0); else safe_link_key = *rkey; if (reiserfs_search_by_key_4 (fs, &key, &path) == ITEM_NOT_FOUND) { /*sware on check, delete on fix-fixable*/ if (fsck_mode(fs) == FSCK_CHECK) { fsck_log ("Invalid safe link %k: cannot find the pointed object (%K)\n", &tmp_ih->ih_key, &key); one_more_corruption (fs, FIXABLE); } else if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { fsck_log ("Invalid safe link %k: cannot find the pointed object (%K) - " "safe link was deleted\n", &tmp_ih->ih_key, &key); d32_put((__u32 *)get_item(&safe_link_path), 0, 0); pathrelse (&path); reiserfsck_delete_item (&safe_link_path, 0); continue; } } else if (get_offset(&tmp_ih->ih_key) == 0x1) { /* Truncate */ if (!not_a_directory (get_item(&path))) { /*truncate on directory should not happen*/ /*sware on check, delete on fix-fixable*/ if (fsck_mode(fs) == FSCK_CHECK) { fsck_log ("Invalid 'truncate' safe link %k, cannot happen for " "directory (%K)\n", &tmp_ih->ih_key, &key); one_more_corruption (fs, FIXABLE); } else if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { fsck_log ("Invalid 'truncate' safe link %k, cannot happen for " "a directory (%K) - safe link was deleted\n", &tmp_ih->ih_key, &key); d32_put((__u32 *)get_item(&safe_link_path), 0, 0); pathrelse (&path); reiserfsck_delete_item (&safe_link_path, 0); continue; } } else { /* save 'safe truncate links' to avoid swaring on wrong sizes. */ __u32 position; if (reiserfs_bin_search (&key, trunc_links, links_num, sizeof(key), &position, comp_short_keys) != POSITION_FOUND) { blocklist__insert_in_position(&key, (void *)&trunc_links, &links_num, sizeof(key), &position); } } } pathrelse (&path); pathrelse (&safe_link_path); } return OK;}void release_safe_links () { freemem(trunc_links);}/* called when --check is given */void semantic_check (void){ if (fsck_data (fs)->check.bad_nodes) { fsck_progress ("Bad nodes were found, Semantic pass skipped\n"); goto clean; } if (fsck_data (fs)->check.fatal_corruptions) { fsck_progress ("Fatal corruptions were found, Semantic pass skipped\n"); goto clean; } fsck_progress ("Checking Semantic tree:\n"); if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { /*create new_bitmap, and initialize new_bitmap & allocable bitmap*/ fsck_new_bitmap (fs) = reiserfs_create_bitmap(get_sb_block_count(fs->fs_ondisk_sb)); reiserfs_bitmap_copy (fsck_new_bitmap (fs), fs->fs_bitmap2); fsck_allocable_bitmap (fs) = reiserfs_create_bitmap(get_sb_block_count (fs->fs_ondisk_sb)); reiserfs_bitmap_copy (fsck_allocable_bitmap (fs), fs->fs_bitmap2); fs->block_allocator = reiserfsck_reiserfs_new_blocknrs; fs->block_deallocator = reiserfsck_reiserfs_free_block; } check_safe_links (); if (check_semantic_pass (&root_dir_key, &parent_root_dir_key, 0, 0) != OK) { fsck_log ("check_semantic_tree: No root directory found"); one_more_corruption (fs, FATAL); } release_safe_links (); if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { reiserfs_delete_bitmap (fs->fs_bitmap2); reiserfs_bitmap_delta (fsck_new_bitmap (fs), fsck_deallocate_bitmap (fs)); fs->fs_bitmap2 = fsck_new_bitmap (fs); reiserfs_delete_bitmap (fsck_allocable_bitmap (fs)); fsck_allocable_bitmap (fs) = NULL; set_sb_free_blocks (fs->fs_ondisk_sb, reiserfs_bitmap_zeros (fs->fs_bitmap2)); mark_buffer_dirty (fs->fs_super_bh); add_badblock_list(fs, 1); } fsck_progress ("finished\n"); clean: if (fsck_deallocate_bitmap (fs)) reiserfs_delete_bitmap (fsck_deallocate_bitmap (fs));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -