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

📄 semantic_rebuild.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -