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

📄 semantic_check.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by reiserfsprogs/README */#include "fsck.h"static struct key *trunc_links = NULL;static __u32 links_num = 0;int wrong_mode (struct key * key, __u16 * mode, __u64 real_size, int symlink);int wrong_st_blocks(struct key * key, __u32 * blocks, __u32 sd_blocks, __u16 mode, 		    int new_format);int wrong_st_size (struct key * key, unsigned long long max_file_size, int blocksize,		   __u64 * size, __u64 sd_size, int type);int wrong_first_direct_byte (struct key * key, int blocksize, __u32 * first_direct_byte,			     __u32 sd_first_direct_byte, __u32 size);void get_object_key (struct reiserfs_de_head * deh, struct key * key, 		     struct key * entry_key, struct item_head * ih);void print_name (char * name, int len);void erase_name (int len);struct path_key{    struct short_key    {        __u32 k_dir_id;        __u32 k_objectid;    } key;    struct path_key * next, * prev;};struct path_key * head_key = NULL;struct path_key * tail_key = NULL;static int check_path_key(struct key * key){    struct path_key * cur = head_key;    while(cur != NULL)    {        if (!comp_short_keys(&cur->key, key)) {            fsck_log("\nsemantic check: The directory %k has 2 names.", key);            return LOOP_FOUND;        }        cur = cur->next;    }    return 0;}static int add_path_key(struct key * key){    if (check_path_key(key))    	return LOOP_FOUND;    if (tail_key == NULL)    {        tail_key = getmem(sizeof(struct path_key));        head_key = tail_key;        tail_key->prev = NULL;    }else{        tail_key->next = getmem(sizeof(struct path_key));        tail_key->next->prev = tail_key;        tail_key = tail_key->next;    }    copy_short_key (&tail_key->key, key);    tail_key->next = NULL;    return 0;}void del_path_key(){    if (tail_key == NULL)        die("Wrong path_key structure");    if (tail_key->prev == NULL)    {        freemem(tail_key);        tail_key = head_key = NULL;    }else{        tail_key = tail_key->prev;        freemem(tail_key->next);        tail_key->next = NULL;    }}/* path is path to stat data. If file will be relocated - new_ih will contain   a key file was relocated with */static int check_check_regular_file (struct path * path, void * sd,                                     struct item_head * new_ih){    int is_new_file;//    struct key key, sd_key;    __u16 mode;    __u32 nlink;    __u64 real_size, sd_size;    __u32 blocks, sd_blocks;	/* proper values and value in stat data */    __u32 first_direct_byte, sd_first_direct_byte;    struct item_head * ih, sd_ih;    int fix_sd;    int symlnk = 0;    int retval = OK;    __u32 tmp_position;    ih = get_ih (path);    if (new_ih) {	/* this objectid is used already */	*new_ih = *ih;	pathrelse (path);	rewrite_file (new_ih, 1, 1);	linked_already(&new_ih->ih_key);	one_less_corruption (fs, FIXABLE);	sem_pass_stat (fs)->oid_sharing_files_relocated ++;	retval = RELOCATED;	if (reiserfs_search_by_key_4 (fs, &(new_ih->ih_key), path) == ITEM_NOT_FOUND)	    reiserfs_panic ("check_check_regular_file: Could not find a StatData of "		"the relocated file %K", &new_ih->ih_key);	/* stat data is marked unreachable again due to relocation, fix that */	ih = get_ih (path);	sd = get_item (path);    }        if (get_ih_item_len (ih) == SD_SIZE)	is_new_file = 1;    else	is_new_file = 0;    get_sd_nlink (ih, sd, &nlink);    get_sd_mode (ih, sd, &mode);    get_sd_size (ih, sd, &sd_size);    get_sd_blocks (ih, sd, &sd_blocks);/*	    if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {    	// check and set nlink first     	nlink ++;    	set_sd_nlink (ih, sd, &nlink);    	mark_buffer_dirty (bh);    	if (nlink > 1)	    return OK;    }*/    if (!is_new_file)	get_sd_first_direct_byte (ih, sd, &sd_first_direct_byte);    if (S_ISLNK (mode)) 		symlnk = 1;        sd_ih = *ih;//    sd_key = sd_ih.ih_key;    pathrelse (path);    if (are_file_items_correct (&sd_ih, sd, &real_size, &blocks, 0/* do not mark reachable */,	&symlnk) != 1)     {	one_more_corruption (fs, FATAL);	fsck_log ("check_regular_file: The file %K with the corrupted structure found\n", 	    &sd_ih.ih_key);    } else {	fix_sd = 0;    	fix_sd += wrong_mode (&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, sd_first_direct_byte, real_size);		if (reiserfs_bin_search(&sd_ih.ih_key, trunc_links, links_num, sizeof(sd_ih.ih_key), 	    &tmp_position, comp_short_keys) != POSITION_FOUND) 	{	    fix_sd += wrong_st_size (&sd_ih.ih_key, is_new_file ? MAX_FILE_SIZE_V2 : 		MAX_FILE_SIZE_V1, fs->fs_blocksize, &real_size, sd_size, 		symlnk ? TYPE_SYMLINK : 0);	} else {	    real_size = sd_size;	}		fix_sd += wrong_st_blocks (&sd_ih.ih_key, &blocks, sd_blocks, mode, is_new_file);	if (fix_sd) {	    if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {    		struct buffer_head * bh;  	        /* 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) {		    fsck_log ("check_regular_file: A StatData of the file %K cannot be "			"found\n", &sd_ih.ih_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, &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);	    } else {		fsck_check_stat (fs)->fixable_corruptions += fix_sd;	    }	}    }        return retval;}/* 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, __u32 * pos_in_item, int dir_format){    INITIALIZE_PATH (path);    char * dir_item;    struct key * rdkey;    struct buffer_head * bh;    struct reiserfs_de_head * deh;    int i;    int retval;start_again:    retval = reiserfs_search_by_entry_key (fs, key, &path);    if (retval != POSITION_FOUND && get_offset (key) != DOT_OFFSET)	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);    /* position was not found for '.' or there is no '..' */    if (retval != POSITION_FOUND || ((get_offset (key) == DOT_OFFSET) &&	(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 %s %k cannot be found in %k", 	    (retval == POSITION_NOT_FOUND) ? "entry" : "directory", key, &ih->ih_key);		if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {	    /* add "." and ".." exist */	    pathrelse (&path);	    reiserfs_add_entry (fs, key, ".",  name_length (".", dir_format), key, 0);	    reiserfs_add_entry (fs, key, "..", name_length ("..", dir_format), parent, 0);	    fsck_log (" - entry was added\n");	    goto start_again;	} else {	    one_more_corruption (fs, FIXABLE);	    fsck_log ("\n");	    if (retval == DIRECTORY_NOT_FOUND)	        return 0;	}    }    /* 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: \"..\" not found in %H\n", ih);	    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)) // handled in check_tree	    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);		if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {		    set_deh_dirid (deh, get_key_dirid (key));		    set_deh_objectid (deh, get_key_objectid (key));		    mark_buffer_dirty (bh);		    fsck_log (" - corrected\n");		} else {		    one_more_corruption (fs, FIXABLE);		    fsck_log ("\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)));		if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {		    set_deh_dirid (deh, get_key_dirid (parent));		    set_deh_objectid (deh, get_key_objectid (parent));		    mark_buffer_dirty (bh);		    fsck_log (" - corrected\n");		} else {		    one_more_corruption (fs, FIXABLE);		    fsck_log ("\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;}/* semantic pass of --check */static int check_semantic_pass (struct key * key, struct key * parent, int dot_dot,     struct item_head * new_ih){    struct path path;    void * sd;    __u32 nlink;    int is_new_dir;    struct buffer_head * bh;    struct item_head * ih;    int retval;    char * dir_item;    __u32 pos_in_item;    struct item_head tmp_ih;    struct key next_item_key, entry_key, object_key;    __u64 dir_size = 0;    __u32 blocks;    __u64 sd_size;    __u32 sd_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)) {	fsck_log ("check_semantic_pass: The key %k must be key of a StatData\n", key);	one_more_corruption (fs, FATAL);        return STAT_DATA_NOT_FOUND;    }    /* look for stat data of an object */    if (reiserfs_search_by_key_4 (fs, key, &path) == ITEM_NOT_FOUND) {	pathrelse (&path);	return STAT_DATA_NOT_FOUND;    }    /* stat data has been found */    ih = get_ih (&path);    sd = get_item(&path);    get_sd_nlink (ih, sd, &nlink);    /* It seems quite difficult to relocate objects on fix-fixable -      * rewrite_file calls reiserfs_file_write which can convert tails      * to unfm, plus unreachable, was_tail flags, etc. */#if 0    if ((/* relocate = */ should_be_relocated(&ih->ih_key))) {	/*	if (fsck_mode(fs) == FSCK_CHECK)	    relocate = 0;	*/	one_more_corruption(fs, FATAL);    }#endif

⌨️ 快捷键说明

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