📄 reiserfs_fs.h
字号:
#define deh_offset(deh) (le32_to_cpu ((deh)->deh_offset))#define deh_dir_id(deh) (le32_to_cpu ((deh)->deh_dir_id))#define deh_objectid(deh) (le32_to_cpu ((deh)->deh_objectid))#define deh_location(deh) (le16_to_cpu ((deh)->deh_location))#define deh_state(deh) (le16_to_cpu ((deh)->deh_state))/* empty directory contains two entries "." and ".." and their headers */#define EMPTY_DIR_SIZE \(DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen ("..")))/* old format directories have this size when empty */#define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)#define DEH_Statdata 0 /* not used now */#define DEH_Visible2 2#define DEH_Bad_offset 4 /* fsck marks entries to be deleted with this flag */#define DEH_Bad_location 5#define test_deh_state_le_bit(deh,bit) (get_deh_state (deh) & (1 << bit))#define set_deh_state_le_bit(deh,bit) \{\ __u16 state;\ state = get_deh_state (deh);\ state |= (1 << bit);\ set_deh_state(deh, state);\}#define clear_deh_state_le_bit(deh,bit) \{\ __u16 state;\ state = get_deh_state (deh);\ state &= ~(1 << bit);\ set_deh_state(deh, state);\}#define mark_de_without_sd(deh) clear_deh_state_le_bit (deh, DEH_Statdata)#define mark_de_visible(deh) set_deh_state_le_bit (deh, DEH_Visible2)#define mark_de_hidden(deh) clear_deh_state_le_bit (deh, DEH_Visible)#define de_with_sd(deh) test_deh_state_le_bit (deh, DEH_Statdata)#define de_visible(deh) test_deh_state_le_bit (deh, DEH_Visible2)#define de_hidden(deh) !test_deh_state_le_bit (deh, DEH_Visible2)/* Bad means "hashed unproperly or/and invalid location" */#define de_bad_location(deh) test_deh_state_le_bit (deh, DEH_Bad_location)#define mark_de_bad_location(deh) set_deh_state_le_bit (deh, DEH_Bad_location)#define mark_de_good_location(deh) clear_deh_state_le_bit (deh, DEH_Bad_location)#define de_bad_offset(deh) test_deh_state_le_bit (deh, DEH_Bad_offset)#define mark_de_bad_offset(deh) set_deh_state_le_bit (deh, DEH_Bad_offset)#define de_bad(deh) (de_bad_location(deh) || de_bad_offset(deh))/* for directories st_blocks is number of 512 byte units which fit into dir size round up to blocksize */#define dir_size2st_blocks(size) ((size + 511) / 512)/* array of the entry headers */#define B_I_DEH(bh,ih) ((struct reiserfs_de_head *)(B_I_PITEM(bh,ih)))#define REISERFS_MAX_NAME_LEN(block_size) (block_size - BLKH_SIZE - IH_SIZE - DEH_SIZE) /* -SD_SIZE when entry will contain stat data *//* hash value occupies 24 bits starting from 7 up to 30 */#define GET_HASH_VALUE(offset) ((offset) & 0x7fffff80)/* generation number occupies 7 bits starting from 0 up to 6 */#define GET_GENERATION_NUMBER(offset) ((offset) & 0x0000007f)/* * Picture represents an internal node of the reiserfs tree * ______________________________________________________ * | | Array of | Array of | Free | * |block | keys | pointers | space | * | head | N | N+1 | | * |______|_______________|___________________|___________| *//***************************************************************************//* DISK CHILD *//***************************************************************************//* Disk child pointer: The pointer from an internal node of the tree to a node that is on disk. */struct disk_child { __u32 dc2_block_number; /* Disk child's block number. */ __u16 dc2_size; /* Disk child's used space. */ __u16 dc2_reserved;} __attribute__ ((__packed__));#define DC_SIZE (sizeof(struct disk_child))/* set/get fields of disk_child with these defines */#define get_dc_child_blocknr(dc) get_le32 (dc, dc2_block_number)#define set_dc_child_blocknr(dc,val) set_le32 (dc, dc2_block_number, val)#define get_dc_child_size(dc) get_le16 (dc, dc2_size)#define set_dc_child_size(dc,val) set_le16 (dc, dc2_size, val)#define set_dc(dc, size, blocknr) \({ \ set_dc_child_blocknr(dc, blocknr); \ set_dc_child_size(dc, size); \ set_le16(dc, dc2_reserved, 0); \})/* Get disk child by buffer header and position in the tree node. */#define B_N_CHILD(p_s_bh,n_pos) ((struct disk_child *)\ ((p_s_bh)->b_data + BLKH_SIZE + B_NR_ITEMS(p_s_bh) \ * KEY_SIZE + DC_SIZE * (n_pos))) /* maximal value of field child_size in structure disk_child */ /* child size is the combined size of all items and their headers */#define MAX_CHILD_SIZE(blocksize) ((blocksize) - BLKH_SIZE)#define MAX_FREE_SPACE(blocksize) MAX_CHILD_SIZE(blocksize)/* amount of used space in buffer (not including block head) */#define B_CHILD_SIZE(cur) (MAX_CHILD_SIZE(cur->b_size)-(B_FREE_SPACE(cur)))/* max and min number of keys in internal node */#define MAX_NR_KEY(bh) ( (MAX_CHILD_SIZE(bh->b_size)-DC_SIZE)/(KEY_SIZE+DC_SIZE) )#define MIN_NR_KEY(bh) (MAX_NR_KEY(bh)/2)/***************************************************************************//* PATH STRUCTURES AND DEFINES *//***************************************************************************//* Search_by_key fills up the path from the root to the leaf as it descends the tree looking for the key. It uses reiserfs_bread to try to find buffers in the cache given their block number. If it does not find them in the cache it reads them from disk. For each node search_by_key finds using reiserfs_bread it then uses bin_search to look through that node. bin_search will find the position of the block_number of the next node if it is looking through an internal node. If it is looking through a leaf node bin_search will find the position of the item which has key either equal to given key, or which is the maximal key less than the given key. */struct path_element { struct buffer_head * pe_buffer; /* Pointer to the buffer at the path in the tree. */ int pe_position; /* Position in the tree node which is placed in the buffer above. */};#define MAX_HEIGHT 6#define FIRST_PATH_ELEMENT_OFFSET 2#define EXTENDED_MAX_HEIGHT (MAX_HEIGHT + FIRST_PATH_ELEMENT_OFFSET)#define ILLEGAL_PATH_ELEMENT_OFFSET 1#define MAX_FEB_SIZE (MAX_HEIGHT + 1)/* We need to keep track of who the ancestors of nodes are. When we perform a search we record which nodes were visited while descending the tree looking for the node we searched for. This list of nodes is called the path. This information is used while performing balancing. Note that this path information may become invalid, and this means we must check it when using it to see if it is still valid. You'll need to read search_by_key and the comments in it, especially about decrement_counters_in_path(), to understand this structure. */struct path { unsigned int path_length; /* Length of the array above. */ struct path_element path_elements[EXTENDED_MAX_HEIGHT]; /* Array of the path elements. */ unsigned int pos_in_item;};#define INITIALIZE_PATH(var) \struct path var = {ILLEGAL_PATH_ELEMENT_OFFSET, }/* Get path element by path and path position. */#define PATH_OFFSET_PELEMENT(p_s_path,n_offset) ((p_s_path)->path_elements +(n_offset))/* Get buffer header at the path by path and path position. */#define PATH_OFFSET_PBUFFER(p_s_path,n_offset) (PATH_OFFSET_PELEMENT(p_s_path,n_offset)->pe_buffer)/* Get position in the element at the path by path and path position. */#define PATH_OFFSET_POSITION(p_s_path,n_offset) (PATH_OFFSET_PELEMENT(p_s_path,n_offset)->pe_position)#define PATH_PLAST_BUFFER(p_s_path) (PATH_OFFSET_PBUFFER((p_s_path), (p_s_path)->path_length))#define PATH_LAST_POSITION(p_s_path) (PATH_OFFSET_POSITION((p_s_path), (p_s_path)->path_length))#define PATH_PITEM_HEAD(p_s_path) B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_path),PATH_LAST_POSITION(p_s_path))/* in do_balance leaf has h == 0 in contrast with path structure, where root has level == 0. That is why we need these defines */#define PATH_H_PBUFFER(p_s_path, h) PATH_OFFSET_PBUFFER (p_s_path, p_s_path->path_length - (h)) /* tb->S[h] */#define PATH_H_PPARENT(path, h) PATH_H_PBUFFER (path, (h) + 1) /* tb->F[h] or tb->S[0]->b_parent */#define PATH_H_POSITION(path, h) PATH_OFFSET_POSITION (path, path->path_length - (h)) #define PATH_H_B_ITEM_ORDER(path, h) PATH_H_POSITION(path, h + 1) /* tb->S[h]->b_item_order */#define PATH_H_PATH_OFFSET(p_s_path, n_h) ((p_s_path)->path_length - (n_h))#define get_bh(path) PATH_PLAST_BUFFER(path)#define get_ih(path) PATH_PITEM_HEAD(path)#define get_item_pos(path) PATH_LAST_POSITION(path)#define get_item(path) ((void *)B_N_PITEM(PATH_PLAST_BUFFER(path), PATH_LAST_POSITION (path)))#define item_moved(ih,path) comp_items(ih, path)#define path_changed(ih,path) comp_items (ih, path)/***************************************************************************//* MISC *//***************************************************************************//* n must be power of 2 */#define _ROUND_UP(x,n) (((x)+(n)-1u) & ~((n)-1u))// to be ok for alpha and others we have to align structures to 8 byte// boundary.// FIXME: do not change 4 by anything else: there is code which relies on that#define ROUND_UP(x) _ROUND_UP(x,8LL)// search_by_key (and clones) and fix_nodes error code#define CARRY_ON 0#define NO_DISK_SPACE 3/* #define IO_ERROR 0x4 - defined above as 0x4 */#define NO_BALANCING_NEEDED 5#define ITEM_FOUND 6#define ITEM_NOT_FOUND 7#define GOTO_PREVIOUS_ITEM 10#define POSITION_FOUND_INVISIBLE 11#define FILE_NOT_FOUND 12// used by fsck#define DIRECTORY_NOT_FOUND 13 #define REGULAR_FILE_FOUND 14#define DIRECTORY_FOUND 15struct unfm_nodeinfo { __u32 unfm_nodenum; __u16 unfm_freespace;};/* Size of pointer to the unformatted node. */#define UNFM_P_SIZE (sizeof(__u32))#define MAX_KEY1_OFFSET 0xffffffff#define MAX_KEY2_OFFSET 0xfffffffffffffffLL/* this is aggressive tail suppression policy taken from the kernel *//* It should be MAX_DIRECT_ITEM_LEN used here, but sometimes it is not enough, * and items got deleted. */#define STORE_TAIL_IN_UNFM(n_file_size,n_tail_size,n_block_size) \(\ (!(n_tail_size)) || \ (((n_tail_size) > MAX_ITEM_LEN(n_block_size)) || \ ( (n_file_size) >= (n_block_size) * 4 ) || \ ( ( (n_file_size) >= (n_block_size) * 3 ) && \ ( (n_tail_size) >= (MAX_ITEM_LEN(n_block_size))/4) ) || \ ( ( (n_file_size) >= (n_block_size) * 2 ) && \ ( (n_tail_size) >= (MAX_ITEM_LEN(n_block_size))/2) ) || \ ( ( (n_file_size) >= (n_block_size) ) && \ ( (n_tail_size) >= (MAX_ITEM_LEN(n_block_size) * 3)/4) ) ) \)/***************************************************************************//* FIXATE NODES *//***************************************************************************/#define VI_TYPE_STAT_DATA 1#define VI_TYPE_DIRECT 2#define VI_TYPE_INDIRECT 4#define VI_TYPE_DIRECTORY 8#define VI_TYPE_FIRST_DIRECTORY_ITEM 16#define VI_TYPE_INSERTED_DIRECTORY_ITEM 32#define VI_TYPE_LEFT_MERGEABLE 64#define VI_TYPE_RIGHT_MERGEABLE 128/* To make any changes in the tree we always first find node, that contains item to be changed/deleted or place to insert a new item. We call this node S. To do balancing we need to decide what we will shift to left/right neighbor, or to a new node, where new item will be etc. To make this analysis simpler we build virtual node. Virtual node is an array of items, that will replace items of node S. (For instance if we are going to delete an item, virtual node does not contain it). Virtual node keeps information about item sizes and types, mergeability of first and last items, sizes of all entries in directory item. We use this array of items when calculating what we can shift to neighbors and how many nodes we have to have if we do not any shiftings, if we shift to left/right neighbor or to both. */struct virtual_item{ unsigned short vi_type; /* item type, mergeability */ unsigned short vi_item_len; /* length of item that it will have after balancing */ __u64 vi_item_offset; /* offset of item that it have before balancing */ short vi_entry_count; /* number of entries in directory item (including the new one if any, or excluding entry if it must be cut) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -