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

📄 node_formats.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
    switch (get_type (&ih->ih_key)) {    case TYPE_DIRECT:	return get_ih_item_len (ih);    case TYPE_INDIRECT:	return I_UNFM_NUM(ih) * blocksize;// - get_ih_free_space (ih);    case TYPE_STAT_DATA:    case TYPE_DIRENTRY:	return 0;    }    reiserfs_warning (stderr, "get_bytes_number: called for wrong type of item %h", ih);    return 0;}int check_item_f (reiserfs_filsys_t * fs, struct item_head * ih, char * item);/* ih_key, ih_location and ih_item_len seem correct, check other fields */static int does_ih_look_correct (struct item_head * ih){    int ih_key_format;    int key_key_format;    /* key format from item_head */    ih_key_format = get_ih_key_format (ih);    if (ih_key_format != KEY_FORMAT_1 && ih_key_format != KEY_FORMAT_2)	return 0;    /* key format calculated on key */    key_key_format = key_format (&ih->ih_key);    if (is_stat_data_ih (ih)) {	/* for stat data we can not find key format from a key itself, so look at           the item length */	if (get_ih_item_len (ih) == SD_SIZE)	    key_key_format = KEY_FORMAT_2;	else if (get_ih_item_len (ih) == SD_V1_SIZE)	    key_key_format = KEY_FORMAT_1;	else	    return 0;    }    if (key_key_format != ih_key_format)	return 0;    /* we do not check ih_format.fsck_need as fsck might change it. So,       debugreiserfs -p will have to dump it */    return 1;}/* check item length, ih_free_space for pure 3.5 format, unformatted node   pointers */static int is_bad_indirect (reiserfs_filsys_t * fs, struct item_head * ih, char * item,			    check_unfm_func_t check_unfm_func){    unsigned int i;    __u32 * ind = (__u32 *)item;    if (get_ih_item_len (ih) % UNFM_P_SIZE)	return 1;    for (i = 0; i < I_UNFM_NUM (ih); i ++) {	if (!ind [i])	    continue;	if (check_unfm_func && check_unfm_func (fs, d32_get (ind, i)))	    return 1;    }    if (fs->fs_format == REISERFS_FORMAT_3_5) {	/* check ih_free_space for 3.5 format only */	if (get_ih_free_space (ih) > fs->fs_blocksize - 1)	    return 1;    }        return 0;}static const struct {    hashf_t func;    char * name;} hashes[] = {{0, "not set"},	      {keyed_hash, "\"tea\""},	      {yura_hash, "\"rupasov\""},	      {r5_hash, "\"r5\""}};        #define HASH_AMOUNT (sizeof (hashes) / sizeof (hashes [0]))int known_hashes (void){    return HASH_AMOUNT;}#define good_name(hashfn,name,namelen,deh_offset) \(hash_value (hashfn, name, namelen) == GET_HASH_VALUE (deh_offset))/* this also sets hash function */int is_properly_hashed (reiserfs_filsys_t * fs,			char * name, int namelen, __u32 offset){    unsigned int i;    if (namelen == 1 && name[0] == '.') {	if (offset == DOT_OFFSET)	    return 1;	return 0;    }    if (namelen == 2 && name[0] == '.' && name[1] == '.') {	if (offset == DOT_DOT_OFFSET)	    return 1;	return 0;    }    if (hash_func_is_unknown (fs)) {	/* try to find what hash function the name is sorted with */	for (i = 1; i < HASH_AMOUNT; i ++) {	    if (good_name (hashes [i].func, name, namelen, offset)) {		if (!hash_func_is_unknown (fs)) {		    /* two or more hash functions give the same value for this                       name */		    fprintf (stderr, "Detecting hash code: could not detect hash with name \"%.*s\"\n",			     namelen, name);		    reiserfs_hash (fs) = 0;		    return 1;		}		/* set hash function */ 		reiserfs_hash(fs) = hashes [i].func; 	    } 	}        if (hash_func_is_unknown (fs)) {            return 0;        }    }    if (good_name (reiserfs_hash(fs), name, namelen, offset))	return 1;    return 0;}int find_hash_in_use (char * name, int namelen, __u32 offset, unsigned int code_to_try_first){    unsigned int i;    if (!namelen || !name[0])	return UNSET_HASH;    if (code_to_try_first) {	if (good_name (hashes [code_to_try_first].func, name, namelen, offset))	    return code_to_try_first;    }        for (i = 1; i < HASH_AMOUNT; i ++) {	if (i == code_to_try_first)	    continue;	if (good_name (hashes [i].func, name, namelen, offset))	    return i;    }    /* not matching hash found */    return UNSET_HASH;}char * code2name(unsigned int code) {    if (code >= HASH_AMOUNT || code < 0)        return 0;    return hashes [code].name;}int func2code (hashf_t func){    unsigned int i;        for (i = 0; i < HASH_AMOUNT; i ++)	if (func == hashes [i].func)	    return i;    reiserfs_panic ("func2code: no hashes matches this function\n");    return 0;}hashf_t code2func(unsigned int code) {    if (code >= HASH_AMOUNT) {	reiserfs_warning (stderr, "code2func: wrong hash code %d.\n"			  "Using default %s hash function\n", code,			  code2name (DEFAULT_HASH));	code = DEFAULT_HASH;    }    return hashes [code].func;}hashf_t name2func (char * hash) {    unsigned int i;     for (i = 0; i < HASH_AMOUNT; i ++)	if (!strcmp (hash, hashes [i].name))	    return hashes [i].func;    return 0;}int dir_entry_bad_location (struct reiserfs_de_head * deh, struct item_head * ih, int first){    if (get_deh_location (deh) < DEH_SIZE * get_ih_entry_count (ih))	return 1;        if (get_deh_location (deh) >= get_ih_item_len (ih))	return 1;    if (!first && get_deh_location (deh) >= get_deh_location (deh - 1))	return 1;    return 0;}/* the only corruption which is not considered fatal - is hash mismatching. If   bad_dir is set - directory item having such names is considered bad */static int is_bad_directory (reiserfs_filsys_t * fs, struct item_head * ih, char * item,			     int bad_dir){    int i;    int namelen;    struct reiserfs_de_head * deh = (struct reiserfs_de_head *)item;    __u32 prev_offset = 0;    __u16 prev_location = get_ih_item_len (ih);        for (i = 0; i < get_ih_entry_count (ih); i ++, deh ++) {	if (get_deh_location (deh) >= prev_location)	    return 1;	prev_location = get_deh_location (deh);	    	namelen = name_in_entry_length (ih, deh, i);	if (namelen > (int)REISERFS_MAX_NAME_LEN(fs->fs_blocksize))	    return 1;		if (get_deh_offset (deh) <= prev_offset)	    return 1;	prev_offset = get_deh_offset (deh);		/* check hash value */	if (!is_properly_hashed (fs, item + prev_location, namelen, prev_offset)) {	    if (bad_dir)		/* make is_bad_leaf to not insert whole leaf. Node will be		   marked not-insertable and put into tree item by item in		   pass 2 */		return 1;	}    }    return 0;}/* used by debugreisrefs -p only yet */int is_it_bad_item (reiserfs_filsys_t * fs, struct item_head * ih, char * item,		    check_unfm_func_t check_unfm, int bad_dir){    int retval;/*    if (!does_key_look_correct (fs, &ih->ih_key))	return 1;    if (!does_ih_look_correct (ih))	return 1;*/    if (!does_ih_look_correct (ih))	return 1;        if (is_stat_data_ih (ih) || is_direct_ih (ih))	return 0;    if (is_direntry_ih (ih)) {	retval =  is_bad_directory (fs, ih, item, bad_dir);	/*	if (retval)	reiserfs_warning (stderr, "is_bad_directory %H\n", ih);*/	return retval;    }    if (is_indirect_ih (ih)) {	retval = is_bad_indirect (fs, ih, item, check_unfm);	/*	if (retval)	reiserfs_warning (stderr, "is_bad_indirect %H\n", ih);*/	return retval;    }    return 1;}/* prepare new or old stat data for the new directory */void make_dir_stat_data (int blocksize, int key_format, 			 __u32 dirid, __u32 objectid, 			 struct item_head * ih, void * sd){    memset (ih, 0, IH_SIZE);    set_key_dirid (&ih->ih_key, dirid);    set_key_objectid (&ih->ih_key, objectid);    set_key_offset_v1 (&ih->ih_key, SD_OFFSET);    set_key_uniqueness (&ih->ih_key, 0);    set_ih_key_format (ih, key_format);    set_ih_free_space (ih, MAX_US_INT);    if (key_format == KEY_FORMAT_2) {        struct stat_data *sd_v2 = (struct stat_data *)sd;	set_ih_item_len (ih, SD_SIZE);        set_sd_v2_mode (sd_v2, S_IFDIR + 0755);        set_sd_v2_nlink (sd_v2, 2);        set_sd_v2_uid (sd_v2, 0);        set_sd_v2_gid (sd_v2, 0);        set_sd_v2_size (sd_v2, EMPTY_DIR_SIZE);        set_sd_v2_atime (sd_v2, time(NULL));        sd_v2->sd_ctime = sd_v2->sd_mtime = sd_v2->sd_atime; /* all le */        set_sd_v2_rdev (sd_v2, 0);        set_sd_v2_blocks (sd_v2, dir_size2st_blocks (EMPTY_DIR_SIZE));    }else{        struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd;	set_ih_item_len (ih, SD_V1_SIZE);        set_sd_v1_mode(sd_v1, S_IFDIR + 0755);        set_sd_v1_nlink(sd_v1, 2);        set_sd_v1_uid (sd_v1, 0);        set_sd_v1_gid (sd_v1, 0);        set_sd_v1_size(sd_v1, EMPTY_DIR_SIZE_V1);        set_sd_v1_atime(sd_v1, time(NULL));        sd_v1->sd_ctime = sd_v1->sd_mtime = sd_v1->sd_atime; /* all le */        set_sd_v1_blocks(sd_v1, dir_size2st_blocks(EMPTY_DIR_SIZE_V1));        set_sd_v1_first_direct_byte(sd_v1, NO_BYTES_IN_DIRECT_ITEM);    }}static void _empty_dir_item (int format, char * body, __u32 dirid, __u32 objid,			     __u32 par_dirid, __u32 par_objid){    struct reiserfs_de_head * deh;    __u16 state;    memset (body, 0, (format == KEY_FORMAT_2 ? EMPTY_DIR_SIZE : EMPTY_DIR_SIZE_V1));    deh = (struct reiserfs_de_head *)body;        /* direntry header of "." */    set_deh_offset (deh, DOT_OFFSET);    set_deh_dirid (deh, dirid);    set_deh_objectid (deh, objid);    state = (1 << DEH_Visible2);    set_deh_state (deh, state);    /* direntry header of ".." */    set_deh_offset (deh + 1, DOT_DOT_OFFSET);    /* key of ".." for the root directory */    set_deh_dirid (deh + 1, par_dirid);    set_deh_objectid (deh + 1, par_objid);    set_deh_state (deh + 1, state);    if (format == KEY_FORMAT_2) {	set_deh_location (deh, EMPTY_DIR_SIZE - ROUND_UP (strlen (".")));	set_deh_location (deh + 1, get_deh_location (deh) - ROUND_UP (strlen ("..")));    } else {	set_deh_location (deh, EMPTY_DIR_SIZE_V1 - strlen ("."));	set_deh_location (deh + 1, get_deh_location (deh) - strlen (".."));    }    /* copy ".." and "." */    memcpy (body + get_deh_location (deh), ".", 1);    memcpy (body + get_deh_location (deh + 1), "..", 2);    }void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid,			     __u32 par_dirid, __u32 par_objid){    _empty_dir_item (KEY_FORMAT_1, body, dirid, objid, par_dirid, par_objid);}void make_empty_dir_item (char * body, __u32 dirid, __u32 objid,			  __u32 par_dirid, __u32 par_objid){    _empty_dir_item (KEY_FORMAT_2, body, dirid, objid, par_dirid, par_objid);}/* for every item call common action and an action corresponding to   item type */void for_every_item (struct buffer_head * bh, item_head_action_t action,		     item_action_t * actions){    int i;    struct item_head * ih;    item_action_t iaction;    ih = B_N_PITEM_HEAD (bh, 0);    for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) {	if (action)	    action (ih);	iaction = actions[get_type (&ih->ih_key)];	if (iaction)	    iaction (bh, ih);    }}#if __BYTE_ORDER == __LITTLE_ENDIAN# define get_key_offset_v2(key)     (__u64)((key->u.k2_offset_v2.k_offset))# define set_key_offset_v2(key,val) (void)(key->u.k2_offset_v2.k_offset = (val))# define get_key_type_v2(key)       (__u16)((key->u.k2_offset_v2.k_type))# define set_key_type_v2(key,val)   (void)(key->u.k2_offset_v2.k_type = (val))#elif __BYTE_ORDER == __BIG_ENDIANtypedef union {    struct offset_v2 offset_v2;    __u64 linear;} __attribute__ ((__packed__)) offset_v2_esafe_overlay;static inline __u64 get_key_offset_v2 (const struct key *key){    offset_v2_esafe_overlay tmp =                        *(offset_v2_esafe_overlay *) (&(key->u.k2_offset_v2));    tmp.linear = le64_to_cpu( tmp.linear );

⌨️ 快捷键说明

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