⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semantic_rebuild.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
    get_sd_blocks (ih, sd, &saved_blocks);	    get_sd_mode (ih, sd, &mode);    /* release path pointing to stat data */    pathrelse (&path);    /* make sure that "." and ".." exist */    reiserfs_add_entry (fs, key, ".",  name_length (".", dir_format), key, 1 << IH_Unreachable);    reiserfs_add_entry (fs, key, "..", name_length ("..", dir_format), parent, 1 << IH_Unreachable);    set_key_dirid (&item_key, get_key_dirid (key));    set_key_objectid (&item_key, get_key_objectid (key));    set_key_offset_v1 (&item_key, DOT_OFFSET);    set_key_uniqueness (&item_key, DIRENTRY_UNIQUENESS);    dir_size = 0;    while ((dir_item = get_next_directory_item (&item_key, parent, &tmp_ih, &pos_in_item)) != 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;		    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 */		fsck_log ("Entry %K (\"%.*s\") in the directory %K is not formated properly - fixed.\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);	    }/*		    if ((dir_format == KEY_FORMAT_1) && (namelen != entry_len)) {	    	// aligned entry in directory of old format - remove and insert it back		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);	    }*/		    if (is_dot (name, namelen)) {		dir_size += DEH_SIZE + entry_len;		continue;	    }		    print_name (name, namelen);	    	    if (!is_properly_hashed (fs, name, namelen, get_deh_offset (deh)))		reiserfs_panic ("rebuild_semantic_pass: Hash mismatch detected for (\"%.*s\") in directory %K\n", 		    namelen, name, &tmp_ih.ih_key);	    		    retval1 = rebuild_semantic_pass (&object_key, key, is_dot_dot (name, namelen), &relocated_ih);    	    erase_name (namelen);	    	    switch (retval1) {	    case OK:		dir_size += DEH_SIZE + entry_len;		break;	    case STAT_DATA_NOT_FOUND:	    case DIRECTORY_HAS_NO_ITEMS:		if (get_offset (&entry_key) == DOT_DOT_OFFSET && 		    get_key_objectid (&object_key) == REISERFS_ROOT_PARENT_OBJECTID) {		    /* ".." of root directory can not be found */		    dir_size += DEH_SIZE + entry_len;		    continue;		}		fsck_log ("%s: The entry %K (\"%.*s\") in directory %K points to nowhere - is removed\n",		    __FUNCTION__, &object_key, namelen, name, &tmp_ih.ih_key);		reiserfs_remove_entry (fs, &entry_key);		sem_pass_stat (fs)->deleted_entries ++;		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 ("WARNING: Cannot find the name of the relocated file %K in the directory %K\n", 			&object_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 entry %K (\"%.*s\") in directory %K updated to point to ",			&object_key, namelen, name, &tmp_ih.ih_key);		    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\n",  &tmp_deh->deh2_dir_id);		    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 (&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, saved_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, saved_size, TYPE_DIRENTRY);    if (fix_sd) {	/* 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)	    reiserfs_panic ("rebuild_semantic_pass: The StatData of the file %K was not found", key);	    	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);    }        return retval;}int is_dot (char * name, int namelen){    return (namelen == 1 && name[0] == '.') ? 1 : 0;}int is_dot_dot (char * name, int namelen){    return (namelen == 2 && name[0] == '.' && name[1] == '.') ? 1 : 0;}int not_a_directory (void * sd){    /* mode is at the same place and of the same size in both stat       datas (v1 and v2) */    struct stat_data_v1 * sd_v1 = sd;    return !(S_ISDIR (le16_to_cpu (sd_v1->sd_mode)));}int not_a_regfile (void * sd){    /* mode is at the same place and of the same size in both stat       datas (v1 and v2) */    struct stat_data_v1 * sd_v1 = sd;    return !(S_ISREG (le16_to_cpu (sd_v1->sd_mode)));}void zero_nlink (struct item_head * ih, void * sd){    int zero = 0;    if (get_ih_item_len (ih) == SD_V1_SIZE && get_ih_key_format (ih) != KEY_FORMAT_1) {	fsck_log ("zero_nlink: The StatData %k of the wrong format version (%d) - corrected to (%d)\n",	    ih, get_ih_key_format (ih), KEY_FORMAT_1);	set_ih_key_format (ih, KEY_FORMAT_1);    }    if (get_ih_item_len (ih) == SD_SIZE && get_ih_key_format (ih) != KEY_FORMAT_2) {	fsck_log ("zero_nlink: The StatData %k of the wrong format version (%d) - corrected to (%d)\n",	    ih, get_ih_key_format (ih), KEY_FORMAT_2);	set_ih_key_format (ih, KEY_FORMAT_2);    }    set_sd_nlink (ih, sd, &zero);}void modify_item (struct item_head * ih, void * item){    zero_nlink (ih, item);    mark_item_unreachable (ih);    }/* mkreiserfs should have created this */static void make_sure_lost_found_exists (reiserfs_filsys_t * fs){    int retval;    INITIALIZE_PATH (path);    unsigned int gen_counter;    __u32 objectid;    __u64 sd_size;    __u32 sd_blocks;    struct buffer_head * bh;    struct item_head * ih;    void * sd;    int item_len;    /* look for "lost+found" in the root directory */    retval = reiserfs_find_entry (fs, &root_dir_key,				  "lost+found", &gen_counter,				  &lost_found_dir_key);    if (!retval) {	objectid = id_map_alloc(proper_id_map(fs));	if (!objectid) {	    fsck_progress ("Could not allocate an objectid for \"/lost+found\", \		lost files will not be linked\n");	    return;	}	set_key_dirid (&lost_found_dir_key, REISERFS_ROOT_OBJECTID);	set_key_objectid (&lost_found_dir_key, objectid);    }    /* look for stat data of "lost+found" */    retval = reiserfs_search_by_key_4 (fs, &lost_found_dir_key, &path);    if (retval == ITEM_NOT_FOUND)	lost_found_dir_format = create_dir_sd (fs, &path, &lost_found_dir_key, modify_item);    else {    	struct item_head * ih = get_ih (&path);	    	if (!is_stat_data_ih (ih))	    reiserfs_panic ("It must be lost+found's stat data %k\n", &ih->ih_key);		fix_obviously_wrong_sd_mode (&path);		if (not_a_directory (get_item (&path))) {	    fsck_progress ("\"/lost+found\" exists, but it is not a directory, \		lost files will not be linked\n");	    set_key_objectid (&lost_found_dir_key, 0);	    pathrelse (&path);	    return;	}    	        lost_found_dir_format = (get_ih_item_len (get_ih (&path)) == SD_SIZE) ? KEY_FORMAT_2 : KEY_FORMAT_1;        		pathrelse (&path);    }    /* add "." and ".." if any of them do not exist */    reiserfs_add_entry (fs, &lost_found_dir_key, ".", name_length (".", lost_found_dir_format),    		&lost_found_dir_key, 1 << IH_Unreachable);    		    reiserfs_add_entry (fs, &lost_found_dir_key, "..", name_length ("..", lost_found_dir_format),    		&root_dir_key, 1 << IH_Unreachable);    item_len = reiserfs_add_entry (fs, &root_dir_key, "lost+found",    		name_length ("lost+found", root_dir_format), &lost_found_dir_key, 1 << IH_Unreachable);    if (item_len) {	if (reiserfs_search_by_key_4 (fs, &root_dir_key, &path) == ITEM_NOT_FOUND)	    reiserfs_panic ("%s: StatData of the root directory must exists", __FUNCTION__);		bh = get_bh (&path);	ih = get_ih (&path);	sd = get_item(&path);		get_sd_size (ih, sd, &sd_size);	sd_size += item_len;	set_sd_size (ih, sd, &sd_size);	sd_blocks = dir_size2st_blocks (sd_size);	set_sd_blocks (ih, sd, &sd_blocks);	mark_buffer_dirty (bh);	pathrelse (&path);    }			    return;}/* Result of the rebuild pass will be saved in the state file which is needed to start  * fsck again from the next pass. */static void save_rebuild_semantic_result (reiserfs_filsys_t * fs) {    FILE * file;    int retval;    file = open_file ("temp_fsck_file.deleteme", "w+");    if (!file)	return;    reiserfs_begin_stage_info_save (file, SEMANTIC_DONE);    /*  Method not implemented yet.    reiserfs_objectid_map_save (file, semantic_id_map (fs));    */    reiserfs_end_stage_info_save (file);    close_file (file);    retval = rename ("temp_fsck_file.deleteme", state_dump_file (fs));    if (retval != 0)	fsck_progress ("%s: Could not rename the temporary file temp_fsck_file.deleteme to %s",	    __FUNCTION__, state_dump_file (fs));}/* we have nothing to load from a state file, but we have to fetch   on-disk bitmap, copy it to allocable bitmap, and fetch objectid   map */void load_semantic_result (FILE * file, reiserfs_filsys_t * fs){    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;    /* we need objectid map on semantic pass to be able to relocate files */    proper_id_map (fs) = id_map_init();    /* Not implemented yet.        fetch_objectid_map (proper_id_map (fs), fs);    semantic_id_map (fs) = reiserfs_objectid_map_load (file);    */}static void before_pass_3 (reiserfs_filsys_t * fs){    semantic_id_map (fs) = id_map_init();}static void after_pass_3 (reiserfs_filsys_t * fs){    /* update super block: objectid map, fsck state */    set_sb_fs_state (fs->fs_ondisk_sb, SEMANTIC_DONE);    mark_buffer_dirty (fs->fs_super_bh);    /* write all dirty blocks */    fsck_progress ("Flushing..");    id_map_flush(proper_id_map (fs), fs);    fs->fs_dirt = 1;    reiserfs_flush_to_ondisk_bitmap (fsck_new_bitmap(fs), fs);    reiserfs_flush (fs);    fsck_progress ("finished\n");    stage_report (3, fs);    if (!fsck_run_one_step (fs)) {	if (fsck_user_confirmed (fs, "Continue? (Yes):", "Yes\n", 1))	    /* reiserfsck continues */	    return;    }    save_rebuild_semantic_result (fs);    id_map_free(proper_id_map (fs));    proper_id_map (fs) = 0;    fs->fs_dirt = 1;    reiserfs_close (fs);    exit(0);}/* this is part of rebuild tree */void pass_3_semantic (reiserfs_filsys_t * fs){    before_pass_3 (fs);    fsck_progress ("Pass 3 (semantic):\n");    /* when warnings go not to stderr - separate them in the log */    if (fsck_log_file (fs) != stderr)	fsck_log ("####### Pass 3 #########\n");    if (!fs->fs_hash_function)	reiserfs_panic ("Hash function should be selected already");    make_sure_root_dir_exists (fs, modify_item, 1 << IH_Unreachable);    make_sure_lost_found_exists (fs);    id_map_mark(proper_id_map(fs), get_key_objectid(&root_dir_key));    id_map_mark(proper_id_map(fs), get_key_objectid(&lost_found_dir_key));        /* link all relocated files into /lost+found directory */    link_relocated_files ();    rebuild_semantic_pass (&root_dir_key, &parent_root_dir_key, 0/*!dot_dot*/, 0/*reloc_ih*/);    add_badblock_list(fs, 1);    after_pass_3 (fs);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -