📄 semantic_rebuild.c
字号:
ih = get_ih (path); bh = get_bh (path); mark_item_reachable (ih, bh); sd = get_item (path); } id_map_mark(semantic_id_map(fs), get_key_objectid (&ih->ih_key)); /* check and set nlink first */ get_sd_nlink (ih, sd, &nlink); nlink ++; set_sd_nlink (ih, sd, &nlink); mark_buffer_dirty (bh); if (nlink > 1) return retval; /* firts name of a file found */ if (get_ih_item_len (ih) == SD_SIZE) is_new_file = 1; else is_new_file = 0; get_sd_mode (ih, sd, &mode); get_sd_size (ih, sd, &saved_size); get_sd_blocks (ih, sd, &saved_blocks); if (!is_new_file) get_sd_first_direct_byte (ih, sd, &saved_first_direct_byte); /* we met this file first time */ if (S_ISREG (mode)) { sem_pass_stat(fs)->regular_files ++; } else if (S_ISLNK (mode)) { symlnk = 1; sem_pass_stat (fs)->symlinks ++; } else { sem_pass_stat (fs)->others ++; } sd_ih = *ih;// sd_key = sd_ih.ih_key; pathrelse (path); if (are_file_items_correct (&sd_ih, sd, &real_size, &blocks, 1/*mark items reachable*/, &symlnk) != 1) { /* unpassed items will be deleted in pass 4 as they left unaccessed */ sem_pass_stat (fs)->broken_files ++; } fix_sd = 0; fix_sd += wrong_mode (/*&sd_key, */ &sd_ih.ih_key, &mode, real_size, symlnk); if (!is_new_file) fix_sd += wrong_first_direct_byte (&sd_ih.ih_key, fs->fs_blocksize, &first_direct_byte, saved_first_direct_byte, real_size); fix_sd += wrong_st_size (/*&sd_key,*/ &sd_ih.ih_key, is_new_file ? MAX_FILE_SIZE_V2 : MAX_FILE_SIZE_V1, fs->fs_blocksize, &real_size, saved_size, symlnk ? TYPE_SYMLINK : 0); fix_sd += wrong_st_blocks (&sd_ih.ih_key, &blocks, saved_blocks, mode, is_new_file); if (fix_sd) { /* find stat data and correct it */ set_type_and_offset (KEY_FORMAT_1, &sd_ih.ih_key, SD_OFFSET, TYPE_STAT_DATA); if (reiserfs_search_by_key_4 (fs, &sd_ih.ih_key, path) != ITEM_FOUND) reiserfs_panic ("%s: The StatData of the file %k could not be found", __FUNCTION__, &sd_ih.ih_key); bh = get_bh (path); ih = get_ih (path); sd = get_item (path); set_sd_size (ih, sd, &real_size); set_sd_blocks (ih, sd, &blocks); set_sd_mode (ih, sd, &mode); if (!is_new_file) set_sd_first_direct_byte (ih, sd, &first_direct_byte); mark_buffer_dirty (bh); } return retval;}static int is_rootdir_key (struct key * key){ if (comp_keys (key, &root_dir_key)) return 0; return 1;}/* returns buffer, containing found directory item.*/static char * get_next_directory_item (struct key * key, /* on return this will contain key of next item in the tree */ struct key * parent, struct item_head * ih,/*not in tree*/ __u32 * pos_in_item){ INITIALIZE_PATH (path); char * dir_item; struct key * rdkey; struct buffer_head * bh; struct reiserfs_de_head * deh; int i; int retval; if ((retval = reiserfs_search_by_entry_key (fs, key, &path)) != POSITION_FOUND) reiserfs_panic ("get_next_directory_item: The current directory %k cannot be " "found", key); /* leaf containing directory item */ bh = PATH_PLAST_BUFFER (&path); *pos_in_item = path.pos_in_item; *ih = *get_ih (&path); deh = B_I_DEH (bh, ih); /* make sure, that ".." exists as well */ if (get_offset (key) == DOT_OFFSET) { if (get_ih_entry_count (ih) < 2 || name_in_entry_length (ih, deh + 1, 1) != 2 || strncmp (name_in_entry (deh + 1, 1), "..", 2)) { fsck_log ("get_next_directory_item: The entry \"..\" cannot be found in %k\n", &ih->ih_key); pathrelse (&path); return 0; } } /* mark hidden entries as visible, set "." and ".." correctly */ deh += *pos_in_item; for (i = *pos_in_item; i < get_ih_entry_count (ih); i ++, deh ++) { int namelen; char * name; name = name_in_entry (deh, i); namelen = name_in_entry_length (ih, deh, i); if (de_hidden (deh)) reiserfs_panic ("get_next_directory_item: item %k: hidden entry %d \'%.*s\'\n", key, i, namelen, name); if (get_deh_offset (deh) == DOT_OFFSET) { if (not_of_one_file (&(deh->deh2_dir_id), key)) { /* "." must point to the directory it is in */ //deh->deh_objectid != REISERFS_ROOT_PARENT_OBJECTID)/*????*/ { fsck_log ("get_next_directory_item: The entry \".\" of the directory %K pointes to %K, instead of %K", key, (struct key *)(&(deh->deh2_dir_id)), key); set_deh_dirid (deh, get_key_dirid (key)); set_deh_objectid (deh, get_key_objectid (key)); mark_buffer_dirty (bh); fsck_log (" - corrected\n"); } } if (get_deh_offset (deh) == DOT_DOT_OFFSET) { /* set ".." so that it points to the correct parent directory */ if (comp_short_keys (&(deh->deh2_dir_id), parent)) { fsck_log ("get_next_directory_item: The entry \"..\" of the directory %K pointes to %K, instead of %K", key, (struct key *)(&(deh->deh2_dir_id)), parent); set_deh_dirid (deh, get_key_dirid (parent)); set_deh_objectid (deh, get_key_objectid (parent)); mark_buffer_dirty (bh); fsck_log (" - corrected\n"); } } } /* copy directory item to the temporary buffer */ dir_item = getmem (get_ih_item_len (ih)); memcpy (dir_item, B_I_PITEM (bh, ih), get_ih_item_len (ih)); /* next item key */ if (PATH_LAST_POSITION (&path) == (B_NR_ITEMS (bh) - 1) && (rdkey = uget_rkey (&path))) copy_key (key, rdkey); else { set_key_dirid (key, 0); set_key_objectid (key, 0); } if (fsck_mode (fs) == FSCK_REBUILD) mark_item_reachable (get_ih (&path), bh); pathrelse (&path); return dir_item;}// get key of an object pointed by direntry and the key of the entry itselfvoid get_object_key (struct reiserfs_de_head * deh, struct key * key, struct key * entry_key, struct item_head * ih){ /* entry points to this key */ set_key_dirid (key, get_deh_dirid (deh)); set_key_objectid (key, get_deh_objectid (deh)); set_key_offset_v1 (key, SD_OFFSET); set_key_uniqueness (key, 0); /* key of entry */ set_key_dirid (entry_key, get_key_dirid (&ih->ih_key)); set_key_objectid (entry_key, get_key_objectid (&ih->ih_key)); set_key_offset_v1 (entry_key, get_deh_offset (deh)); set_key_uniqueness (entry_key, DIRENTRY_UNIQUENESS);}int fix_obviously_wrong_sd_mode (struct path * path) { struct key * next_key = NULL; __u16 mode; int retval = 0; next_key = reiserfs_next_key (path); if (!next_key || not_of_one_file (next_key, &get_ih(path)->ih_key)) return 0; /* next item exists and of the same file. Fix the SD mode */ if (not_a_directory (get_item (path)) && is_direntry_key (next_key)) { /* make SD mode SD of dir */ get_sd_mode (get_ih (path), get_item (path), &mode); fsck_log ("The directory %K had wrong mode %M", &get_ih(path)->ih_key, mode); if (fsck_mode(fs) != FSCK_CHECK) { mode &= ~S_IFMT; mode |= S_IFDIR; fsck_log (" - corrected to %M\n", mode); set_sd_mode (get_ih (path), get_item (path), &mode); mark_buffer_dirty (get_bh(path)); } else { fsck_log ("\n"); retval = 1; } } else if (!not_a_directory (get_item (path)) && !is_direntry_key (next_key)) { /* make SD mode SD of regular file */ get_sd_mode (get_ih (path), get_item (path), &mode); fsck_log ("The file %K had wrong mode %M", &get_ih(path)->ih_key, mode); if (fsck_mode(fs) != FSCK_CHECK) { mode &= ~S_IFMT; mode |= S_IFREG; fsck_log (" - corrected to %M\n", mode); set_sd_mode (get_ih (path), get_item (path), &mode); mark_buffer_dirty (get_bh(path)); } else { fsck_log ("\n"); retval = 1; } } return retval;}/* check recursively the semantic tree. Returns OK if entry points to good object, STAT_DATA_NOT_FOUND if stat data was not found or RELOCATED when file was relocated because its objectid was already marked as used by another file */int rebuild_semantic_pass (struct key * key, struct key * parent, int dot_dot, struct item_head * new_ih){ struct path path; void * sd; int is_new_dir; __u32 nlink; struct buffer_head * bh; struct item_head * ih; int retval, retval1; char * dir_item; __u32 pos_in_item; struct item_head tmp_ih; struct key item_key, entry_key, object_key; __u64 dir_size; __u32 blocks; __u64 saved_size; __u32 saved_blocks; int fix_sd; int relocate; int dir_format = 0; __u16 mode; retval = OK; start_again: /* when directory was relocated */ if (!KEY_IS_STAT_DATA_KEY (key)) reiserfs_panic ("rebuild_semantic_pass: The key %k must be key of a StatData", key); /* look for stat data of an object */ if (reiserfs_search_by_key_4 (fs, key, &path) == ITEM_NOT_FOUND) { pathrelse (&path); if (is_rootdir_key (key)) /* root directory has to exist at this point */ reiserfs_panic ("rebuild_semantic_pass: The root directory StatData was not found"); return STAT_DATA_NOT_FOUND; } /* stat data has been found */ bh = get_bh (&path); ih = get_ih (&path); sd = get_item(&path); /* */ get_sd_nlink (ih, sd, &nlink); relocate = 0; if (!nlink) { /* we reached the stat data for the first time */ if (id_map_mark(semantic_id_map(fs), get_key_objectid (&ih->ih_key))) { /* calculate number of found files/dirs who are using objectid which is used by another file */ sem_pass_stat (fs)->oid_sharing ++; if (1/*fsck_adjust_file_size (fs)*/) /* this works for files only */ relocate = 1; } mark_item_reachable (ih, bh); } fix_obviously_wrong_sd_mode (&path); if (not_a_directory (sd)) { retval = rebuild_check_regular_file (&path, sd, relocate ? new_ih : 0); pathrelse (&path); return retval; } if (relocate) { if (!new_ih) reiserfs_panic ("rebuild_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); *key = new_ih->ih_key; retval = RELOCATED; goto start_again; } /* 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 (bh); pathrelse (&path); return OK; } } /* we see the directory first time */ sem_pass_stat (fs)->directories ++; nlink = 2; if (get_key_objectid (key) == REISERFS_ROOT_OBJECTID) nlink ++; set_sd_nlink (ih, sd, &nlink); mark_buffer_dirty (bh); if (get_ih_item_len (ih) == SD_SIZE) is_new_dir = 1; else is_new_dir = 0;/* { struct key * tmp; // check next item: if it is not a directory item of the same file // therefore sd_mode is corrupted so we just reset it to regular file // mode tmp = reiserfs_next_key (&path); if (tmp && !not_of_one_file (tmp, key) && !is_direntry_key (tmp)) { __u16 mode; get_sd_mode (ih, sd, &mode); fsck_log ("file %K had broken mode %M, ", key, mode); mode &= ~S_IFMT; mode |= S_IFREG; fsck_log ("fixed to %M\n", mode); set_sd_mode (ih, sd, &mode); nlink = 0; set_sd_nlink (ih, sd, &nlink); retval = rebuild_check_regular_file (&path, sd, 0); //no relocate pathrelse (&path); return retval; } }*/ dir_format = (get_ih_item_len (get_ih (&path)) == SD_SIZE) ? KEY_FORMAT_2 : KEY_FORMAT_1; /* save stat data's size and st_blocks */ get_sd_size (ih, sd, &saved_size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -