📄 node_formats.c
字号:
return tmp.offset_v2.k_offset;}static inline __u32 get_key_type_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 ); return tmp.offset_v2.k_type;}static inline void set_key_offset_v2 (struct key *key, __u64 offset){ offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)(&(key->u.k2_offset_v2)); tmp->linear = le64_to_cpu(tmp->linear); tmp->offset_v2.k_offset = offset; tmp->linear = cpu_to_le64(tmp->linear);}static inline void set_key_type_v2 (struct key *key, __u32 type){ offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)(&(key->u.k2_offset_v2)); if (type > 15) reiserfs_panic ("set_key_type_v2: type is too big %d", type); tmp->linear = le64_to_cpu(tmp->linear); tmp->offset_v2.k_type = type; tmp->linear = cpu_to_le64(tmp->linear);}#else# error "nuxi/pdp-endian archs are not supported"#endifstatic inline int is_key_format_1 (int type) { return ( (type == 0 || type == 15) ? 1 : 0);}/* old keys (on i386) have k_offset_v2.k_type == 15 (direct and indirect) or == 0 (dir items and stat data) *//* */int key_format (const struct key * key){ int type; type = get_key_type_v2 (key); if (is_key_format_1 (type)) return KEY_FORMAT_1; return KEY_FORMAT_2;}unsigned long long get_offset (const struct key * key) { if (key_format (key) == KEY_FORMAT_1) return get_key_offset_v1 (key); return get_key_offset_v2 (key);}int uniqueness2type (__u32 uniqueness){ switch (uniqueness) { case V1_SD_UNIQUENESS: return TYPE_STAT_DATA; case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT; case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT; case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY; } return TYPE_UNKNOWN;}__u32 type2uniqueness (int type){ switch (type) { case TYPE_STAT_DATA: return V1_SD_UNIQUENESS; case TYPE_INDIRECT: return V1_INDIRECT_UNIQUENESS; case TYPE_DIRECT: return V1_DIRECT_UNIQUENESS; case TYPE_DIRENTRY: return V1_DIRENTRY_UNIQUENESS; } return V1_UNKNOWN_UNIQUENESS;}int get_type (const struct key * key){ int type_v2 = get_key_type_v2 (key); if (is_key_format_1 (type_v2)) return uniqueness2type (get_key_uniqueness (key)); return type_v2;}char * key_of_what (const struct key * key){ switch (get_type (key)) { case TYPE_STAT_DATA: return "SD"; case TYPE_INDIRECT: return "IND"; case TYPE_DIRECT: return "DRCT"; case TYPE_DIRENTRY: return "DIR"; default: return "???"; }}int type_unknown (struct key * key){ int type = get_type (key); switch (type) { case TYPE_STAT_DATA: case TYPE_INDIRECT: case TYPE_DIRECT: case TYPE_DIRENTRY: return 0; default: break; } return 1;}// this sets key format as well as type of item key belongs to//void set_type (int format, struct key * key, int type){ if (format == KEY_FORMAT_1) set_key_uniqueness (key, type2uniqueness (type)); else set_key_type_v2 (key, type);}// void set_offset (int format, struct key * key, loff_t offset){ if (format == KEY_FORMAT_1) set_key_offset_v1 (key, offset); else set_key_offset_v2 (key, offset); }void set_type_and_offset (int format, struct key * key, loff_t offset, int type){ set_type (format, key, type); set_offset (format, key, offset);}/* length of the directory entry in directory item. This define calculates length of i-th directory entry using directory entry locations from dir entry head. When it calculates length of 0-th directory entry, it uses length of whole item in place of entry location of the non-existent following entry in the calculation. See picture above.*/// NOTE: this is not name length. This is length of whole entryint entry_length (struct item_head * ih, struct reiserfs_de_head * deh, int pos_in_item){ if (pos_in_item) return (get_deh_location (deh - 1) - get_deh_location (deh)); return (get_ih_item_len (ih) - get_deh_location (deh));}char * name_in_entry (struct reiserfs_de_head * deh, int pos_in_item){ return ((char *)(deh - pos_in_item) + get_deh_location(deh));}int name_in_entry_length (struct item_head * ih, struct reiserfs_de_head * deh, int pos_in_item){ int len, i; char * name; len = entry_length (ih, deh, pos_in_item); name = name_in_entry (deh, pos_in_item); // name might be padded with 0s i = 0; while (name[i] && i < len) i++; return i;}int name_length (char * name, int key_format){ if (key_format == KEY_FORMAT_2) return ROUND_UP (strlen(name)); else if (key_format == KEY_FORMAT_1) return strlen(name); return -1;}/* key format is stored in 12 bits starting from 0-th of item_head's ih2_format*/__u16 get_ih_key_format (const struct item_head * ih){ get_bit_field_XX (16, &ih->ih_format, 0, 12);}__u16 get_ih_flags (const struct item_head * ih){ get_bit_field_XX (16, &ih->ih_format, 12, 4);}void set_ih_key_format (struct item_head * ih, __u16 val){ set_bit_field_XX (16, &ih->ih_format, val, 0, 12);}void set_ih_flags (struct item_head * ih, __u16 val){ set_bit_field_XX (16, &ih->ih_format, val, 12, 4);}/* access to fields of stat data (both v1 and v2) */void get_set_sd_field (int field, struct item_head * ih, void * sd, void * value, int set){ if (get_ih_key_format (ih) == KEY_FORMAT_1) { struct stat_data_v1 * sd_v1 = sd; switch (field) { case GET_SD_MODE: if (set) sd_v1->sd_mode = cpu_to_le16 (*(__u16 *)value); else *(__u16 *)value = le16_to_cpu (sd_v1->sd_mode); break; case GET_SD_SIZE: /* value must point to 64 bit int */ if (set) sd_v1->sd_size = cpu_to_le32 (*(__u64 *)value); else *(__u64 *)value = le32_to_cpu (sd_v1->sd_size); break; case GET_SD_BLOCKS: if (set) sd_v1->u.sd_blocks = cpu_to_le32 (*(__u32 *)value); else *(__u32 *)value = le32_to_cpu (sd_v1->u.sd_blocks); break; case GET_SD_NLINK: /* value must point to 32 bit int */ if (set) sd_v1->sd_nlink = cpu_to_le16 (*(__u32 *)value); else *(__u32 *)value = le16_to_cpu (sd_v1->sd_nlink); break; case GET_SD_FIRST_DIRECT_BYTE: if (set) sd_v1->sd_first_direct_byte = cpu_to_le32 (*(__u32 *)value); else *(__u32 *)value = le32_to_cpu (sd_v1->sd_first_direct_byte); break; default: reiserfs_panic ("get_set_sd_field: unknown field of old stat data"); } } else { struct stat_data * sd_v2 = sd; switch (field) { case GET_SD_MODE: if (set) sd_v2->sd_mode = cpu_to_le16 (*(__u16 *)value); else *(__u16 *)value = le16_to_cpu (sd_v2->sd_mode); break; case GET_SD_SIZE: if (set) sd_v2->sd_size = cpu_to_le64 (*(__u64 *)value); else *(__u64 *)value = le64_to_cpu (sd_v2->sd_size); break; case GET_SD_BLOCKS: if (set) sd_v2->sd_blocks = cpu_to_le32 (*(__u32 *)value); else *(__u32 *)value = le32_to_cpu (sd_v2->sd_blocks); break; case GET_SD_NLINK: if (set) sd_v2->sd_nlink = cpu_to_le32 (*(__u32 *)value); else *(__u32 *)value = le32_to_cpu (sd_v2->sd_nlink); break; case GET_SD_FIRST_DIRECT_BYTE: default: reiserfs_panic ("get_set_sd_field: unknown field of new stat data"); } }}int comp_ids (const void * p1, const void * p2){ __u32 id1 = le32_to_cpu(*(__u32 *)p1) ; __u32 id2 = le32_to_cpu(*(__u32 *)p2) ; if (id1 < id2) return -1; if (id1 > id2) return 1 ; return 0 ;}/* functions to manipulate with super block's objectid map */int is_objectid_used (reiserfs_filsys_t * fs, __u32 objectid){ __u32 * objectid_map; __u32 count = get_sb_oid_cursize(fs->fs_ondisk_sb); int ret; __u32 pos; __u32 le_id = cpu_to_le32(objectid); objectid_map = (__u32 *)((char *)fs->fs_ondisk_sb + reiserfs_super_block_size (fs->fs_ondisk_sb)); ret = reiserfs_bin_search(&le_id, objectid_map, count, sizeof(__u32), &pos, comp_ids); /* if the position returned is odd, the oid is in use */ if (ret == POSITION_NOT_FOUND) return (pos & 1) ; /* if the position returned is even, the oid is in use */ return !(pos & 1) ;}void mark_objectid_used (reiserfs_filsys_t * fs, __u32 objectid){ int i; __u32 * objectid_map; int cursize; if (is_objectid_used (fs, objectid)) { return; } objectid_map = (__u32 *)((char *)fs->fs_ondisk_sb + reiserfs_super_block_size (fs->fs_ondisk_sb)); cursize = get_sb_oid_cursize (fs->fs_ondisk_sb); for (i = 0; i < cursize; i += 2) { if (objectid >= le32_to_cpu (objectid_map [i]) && objectid < le32_to_cpu (objectid_map [i + 1])) /* it is used */ return; if (objectid + 1 == le32_to_cpu (objectid_map[i])) { /* size of objectid map does not change */ objectid_map[i] = cpu_to_le32 (objectid); return; } if (objectid == le32_to_cpu (objectid_map[i + 1])) { /* size of objectid map is decreased */ objectid_map [i + 1] = cpu_to_le32 (le32_to_cpu (objectid_map [i + 1]) + 1); if (i + 2 < cursize) { if (objectid_map[i + 1] == objectid_map[i + 2]) { memmove (objectid_map + i + 1, objectid_map + i + 1 + 2, (cursize - (i + 2 + 2 - 1)) * sizeof (__u32)); set_sb_oid_cursize (fs->fs_ondisk_sb, cursize - 2); } } return; } if (objectid < le32_to_cpu (objectid_map[i])) { /* size of objectid map must be increased */ if (cursize == get_sb_oid_maxsize (fs->fs_ondisk_sb)) { /* here all objectids between objectid and objectid_map[i] get used */ objectid_map[i] = cpu_to_le32 (objectid); return; } else { memmove (objectid_map + i + 2, objectid_map + i, (cursize - i) * sizeof (__u32)); set_sb_oid_cursize (fs->fs_ondisk_sb, cursize + 2); } objectid_map[i] = cpu_to_le32 (objectid); objectid_map[i+1] = cpu_to_le32 (objectid + 1); return; } } /* append to current objectid map, if we have space */ if (i < get_sb_oid_maxsize (fs->fs_ondisk_sb)) { objectid_map[i] = cpu_to_le32 (objectid); objectid_map[i + 1] = cpu_to_le32 (objectid + 1); set_sb_oid_cursize (fs->fs_ondisk_sb, cursize + 2); } else if (i == get_sb_oid_maxsize (fs->fs_ondisk_sb)) { objectid_map[i - 1] = cpu_to_le32 (objectid + 1); } else die ("mark_objectid_as_used: objectid map corrupted"); return;}int is_blocksize_correct (unsigned int blocksize){ return ((((blocksize & -blocksize) == blocksize) && (blocksize >= 512) && (blocksize <= 8192)));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -