📄 reiserfs_fs.h
字号:
/* This is an aggressive tail suppression policy, I am hoping it
improves our benchmarks. The principle behind it is that percentage
space saving is what matters, not absolute space saving. This is
non-intuitive, but it helps to understand it if you consider that the
cost to access 4 blocks is not much more than the cost to access 1
block, if you have to do a seek and rotate. A tail risks a
non-linear disk access that is significant as a percentage of total
time cost for a 4 block file and saves an amount of space that is
less significant as a percentage of space, or so goes the hypothesis.
-Hans */
#define STORE_TAIL_IN_UNFM_S1(n_file_size,n_tail_size,n_block_size) \
(\
(!(n_tail_size)) || \
(((n_tail_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) || \
( (n_file_size) >= (n_block_size) * 4 ) || \
( ( (n_file_size) >= (n_block_size) * 3 ) && \
( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size))/4) ) || \
( ( (n_file_size) >= (n_block_size) * 2 ) && \
( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size))/2) ) || \
( ( (n_file_size) >= (n_block_size) ) && \
( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size) * 3)/4) ) ) \
)
/* Another strategy for tails, this one means only create a tail if all the
file would fit into one DIRECT item.
Primary intention for this one is to increase performance by decreasing
seeking.
*/
#define STORE_TAIL_IN_UNFM_S2(n_file_size,n_tail_size,n_block_size) \
(\
(!(n_tail_size)) || \
(((n_file_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) ) \
)
/*
* values for s_umount_state field
*/
#define REISERFS_VALID_FS 1
#define REISERFS_ERROR_FS 2
//
// there are 5 item types currently
//
#define TYPE_STAT_DATA 0
#define TYPE_INDIRECT 1
#define TYPE_DIRECT 2
#define TYPE_DIRENTRY 3
#define TYPE_MAXTYPE 3
#define TYPE_ANY 15 // FIXME: comment is required
/***************************************************************************/
/* KEY & ITEM HEAD */
/***************************************************************************/
//
// directories use this key as well as old files
//
#ifndef __GCC__
#pragma pack(push, 1)
#endif
struct offset_v1 {
__u32 k_offset;
__u32 k_uniqueness;
} __PACKED;
#ifndef __GCC__
#pragma pack(pop)
#endif
#ifndef __GCC__
#pragma pack(push, 1)
#endif
struct offset_v2 {
#ifdef __LITTLE_ENDIAN
/* little endian version */
__u64 k_offset:60;
__u64 k_type: 4;
#else
/* big endian version */
__u64 k_type: 4;
__u64 k_offset:60;
#endif
} __PACKED;
#ifndef __GCC__
#pragma pack(pop)
#endif
#ifndef __LITTLE_ENDIAN
#ifndef __GCC__
#pragma pack(push, 1)
#endif
typedef union {
struct offset_v2 offset_v2;
__u64 linear;
} __PACKED offset_v2_esafe_overlay;
#ifndef __GCC__
#pragma pack(pop)
#endif
#else
# define offset_v2_k_type(v2) ((v2)->k_type)
# define set_offset_v2_k_type(v2,val) (offset_v2_k_type(v2) = (val))
# define offset_v2_k_offset(v2) ((v2)->k_offset)
# define set_offset_v2_k_offset(v2,val) (offset_v2_k_offset(v2) = (val))
#endif
#ifndef __GCC__
#pragma pack(push, 1)
#endif
/* Key of an item determines its location in the S+tree, and
is composed of 4 components */
struct reiserfs_key {
__u32 k_dir_id; /* packing locality: by default parent
directory object id */
__u32 k_objectid; /* object identifier */
union {
struct offset_v1 k_offset_v1;
struct offset_v2 k_offset_v2;
} __PACKED u;
} __PACKED;
#ifndef __GCC__
#pragma pack(pop)
#endif
struct cpu_key {
struct reiserfs_key on_disk_key;
int version;
int key_length; /* 3 in all cases but direct2indirect and
indirect2direct conversion */
};
/* Our function for comparing keys can compare keys of different
lengths. It takes as a parameter the length of the keys it is to
compare. These defines are used in determining what is to be passed
to it as that parameter. */
#define REISERFS_FULL_KEY_LEN 4
#define REISERFS_SHORT_KEY_LEN 2
/* The result of the key compare */
#define FIRST_GREATER 1
#define SECOND_GREATER -1
#define KEYS_IDENTICAL 0
#define KEY_FOUND 1
#define KEY_NOT_FOUND 0
#define KEY_SIZE (sizeof(struct reiserfs_key))
#define SHORT_KEY_SIZE (sizeof (__u32) + sizeof (__u32))
/* return values for search_by_key and clones */
#define ITEM_FOUND 1
#define ITEM_NOT_FOUND 0
#define ENTRY_FOUND 1
#define ENTRY_NOT_FOUND 0
#define DIRECTORY_NOT_FOUND -1
#define REGULAR_FILE_FOUND -2
#define DIRECTORY_FOUND -3
#define BYTE_FOUND 1
#define BYTE_NOT_FOUND 0
#define FILE_NOT_FOUND -1
#define POSITION_FOUND 1
#define POSITION_NOT_FOUND 0
// return values for reiserfs_find_entry and search_by_entry_key
#define NAME_FOUND 1
#define NAME_NOT_FOUND 0
#define GOTO_PREVIOUS_ITEM 2
#define NAME_FOUND_INVISIBLE 3
#ifndef __GCC__
#pragma pack(push, 1)
#endif
/* Everything in the filesystem is stored as a set of items. The
item head contains the key of the item, its free space (for
indirect items) and specifies the location of the item itself
within the block. */
struct item_head
{
/* Everything in the tree is found by searching for it based on
* its key.*/
struct reiserfs_key ih_key;
union {
/* The free space in the last unformatted node of an
indirect item if this is an indirect item. This
equals 0xFFFF iff this is a direct item or stat data
item. Note that the key, not this field, is used to
determine the item type, and thus which field this
union contains. */
__u16 ih_free_space_reserved;
/* Iff this is a directory item, this field equals the
number of directory entries in the directory item. */
__u16 ih_entry_count;
} __PACKED u;
__u16 ih_item_len; /* total size of the item body */
__u16 ih_item_location; /* an offset to the item body
* within the block */
__u16 ih_version; /* 0 for all old items, 2 for new
ones. Highest bit is set by fsck
temporary, cleaned after all
done */
} __PACKED;
#ifndef __GCC__
#pragma pack(pop)
#endif
/* size of item header */
#define IH_SIZE (sizeof(struct item_head))
#define ih_free_space(ih) le16_to_cpu((ih)->u.ih_free_space_reserved)
#define ih_version(ih) le16_to_cpu((ih)->ih_version)
#define ih_entry_count(ih) le16_to_cpu((ih)->u.ih_entry_count)
#define ih_location(ih) le16_to_cpu((ih)->ih_item_location)
#define ih_item_len(ih) le16_to_cpu((ih)->ih_item_len)
#define put_ih_free_space(ih, val) do { (ih)->u.ih_free_space_reserved = cpu_to_le16(val); } while(0)
#define put_ih_version(ih, val) do { (ih)->ih_version = cpu_to_le16(val); } while (0)
#define put_ih_entry_count(ih, val) do { (ih)->u.ih_entry_count = cpu_to_le16(val); } while (0)
#define put_ih_location(ih, val) do { (ih)->ih_item_location = cpu_to_le16(val); } while (0)
#define put_ih_item_len(ih, val) do { (ih)->ih_item_len = cpu_to_le16(val); } while (0)
#define unreachable_item(ih) (ih_version(ih) & (1 << 15))
#define get_ih_free_space(ih) (ih_version (ih) == KEY_FORMAT_3_6 ? 0 : ih_free_space (ih))
#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == KEY_FORMAT_3_6) ? 0 : (val)))
/* these operate on indirect items, where you've got an array of ints
** at a possibly unaligned location. These are a noop on ia32
**
** p is the array of __u32, i is the index into the array, v is the value
** to store there.
*/
#define get_block_num(p, i) le32_to_cpu(get_unaligned((p) + (i)))
#define put_block_num(p, i, v) put_unaligned(cpu_to_le32(v), (p) + (i))
//
// in old version uniqueness field shows key type
//
#define V1_SD_UNIQUENESS 0
#define V1_INDIRECT_UNIQUENESS 0xfffffffe
#define V1_DIRECT_UNIQUENESS 0xffffffff
#define V1_DIRENTRY_UNIQUENESS 500
#define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
//
// here are conversion routines
//
static inline int uniqueness2type (__u32 uniqueness) CONSTF;
static inline int uniqueness2type (__u32 uniqueness)
{
switch ((int)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;
default:
reiserfs_warning (NULL, "vs-500: unknown uniqueness %d",
uniqueness);
case V1_ANY_UNIQUENESS:
return TYPE_ANY;
}
}
static inline __u32 type2uniqueness (int type) CONSTF;
static inline __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;
default:
reiserfs_warning (NULL, "vs-501: unknown type %d", type);
case TYPE_ANY:
return V1_ANY_UNIQUENESS;
}
}
#define is_direntry_le_key(version,key) (le_key_k_type (version, key) == TYPE_DIRENTRY)
#define is_direct_le_key(version,key) (le_key_k_type (version, key) == TYPE_DIRECT)
#define is_indirect_le_key(version,key) (le_key_k_type (version, key) == TYPE_INDIRECT)
#define is_statdata_le_key(version,key) (le_key_k_type (version, key) == TYPE_STAT_DATA)
//
// item header has version.
//
#define is_direntry_le_ih(ih) is_direntry_le_key (ih_version (ih), &((ih)->ih_key))
#define is_direct_le_ih(ih) is_direct_le_key (ih_version (ih), &((ih)->ih_key))
#define is_indirect_le_ih(ih) is_indirect_le_key (ih_version(ih), &((ih)->ih_key))
#define is_statdata_le_ih(ih) is_statdata_le_key (ih_version (ih), &((ih)->ih_key))
#define is_direntry_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRENTRY)
#define is_direct_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRECT)
#define is_indirect_cpu_key(key) (cpu_key_k_type (key) == TYPE_INDIRECT)
#define is_statdata_cpu_key(key) (cpu_key_k_type (key) == TYPE_STAT_DATA)
/* are these used ? */
#define is_direntry_cpu_ih(ih) (is_direntry_cpu_key (&((ih)->ih_key)))
#define is_direct_cpu_ih(ih) (is_direct_cpu_key (&((ih)->ih_key)))
#define is_indirect_cpu_ih(ih) (is_indirect_cpu_key (&((ih)->ih_key)))
#define is_statdata_cpu_ih(ih) (is_statdata_cpu_key (&((ih)->ih_key)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -