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

📄 reiserfs_fs.h

📁 umon bootloader source code, support mips cpu.
💻 H
📖 第 1 页 / 共 5 页
字号:

#define set_inode_sd_version(inode, version)                                   \
         ({ if((version)==STAT_DATA_V2)                                        \
                REISERFS_I(inode)->i_flags |= i_stat_data_version_mask;     \
            else                                                               \
                REISERFS_I(inode)->i_flags &= ~i_stat_data_version_mask; })

/* 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
//
struct offset_v1 {
    __le32 k_offset;
    __le32 k_uniqueness;
} __attribute__ ((__packed__));

struct offset_v2 {
	__le64 v;
} __attribute__ ((__packed__));

static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 )
{
	__u8 type = le64_to_cpu(v2->v) >> 60;
	return (type <= TYPE_MAXTYPE)?type:TYPE_ANY;
}
 
static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type )
{
	v2->v = (v2->v & cpu_to_le64(~0ULL>>4)) | cpu_to_le64((__u64)type<<60);
}
 
static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 )
{
	return le64_to_cpu(v2->v) & (~0ULL>>4);
}

static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){
	offset &= (~0ULL>>4);
	v2->v = (v2->v & cpu_to_le64(15ULL<<60)) | cpu_to_le64(offset);
}

/* Key of an item determines its location in the S+tree, and
   is composed of 4 components */
struct reiserfs_key {
    __le32 k_dir_id;    /* packing locality: by default parent
			  directory object id */
    __le32 k_objectid;  /* object identifier */
    union {
	struct offset_v1 k_offset_v1;
	struct offset_v2 k_offset_v2;
    } __attribute__ ((__packed__)) u;
} __attribute__ ((__packed__));

struct in_core_key {
    __u32 k_dir_id;    /* packing locality: by default parent
			  directory object id */
    __u32 k_objectid;  /* object identifier */
    __u64 k_offset;
    __u8 k_type;
};

struct cpu_key {
    struct in_core_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

/*  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. */
		__le16 ih_free_space_reserved;
		/* Iff this is a directory item, this field equals the
		   number of directory entries in the directory item. */
		__le16 ih_entry_count;
	} __attribute__ ((__packed__)) u;
	__le16 ih_item_len;           /* total size of the item body */
	__le16 ih_item_location;      /* an offset to the item body
				      * within the block */
	__le16 ih_version;	     /* 0 for all old items, 2 for new
					ones. Highest bit is set by fsck
					temporary, cleaned after all
					done */
} __attribute__ ((__packed__));
/* 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;
    }
}

//
// key is pointer to on disk key which is stored in le, result is cpu,
// there is no way to get version of object from key, so, provide
// version to these defines
//
static inline loff_t le_key_k_offset (int version, const struct reiserfs_key * key)
{
    return (version == KEY_FORMAT_3_5) ?
        le32_to_cpu( key->u.k_offset_v1.k_offset ) :
	offset_v2_k_offset( &(key->u.k_offset_v2) );
}

static inline loff_t le_ih_k_offset (const struct item_head * ih)
{
    return le_key_k_offset (ih_version (ih), &(ih->ih_key));
}

static inline loff_t le_key_k_type (int version, const struct reiserfs_key * key)
{
    return (version == KEY_FORMAT_3_5) ?
        uniqueness2type( le32_to_cpu( key->u.k_offset_v1.k_uniqueness)) :
	offset_v2_k_type( &(key->u.k_offset_v2) );
}

static inline loff_t le_ih_k_type (const struct item_head * ih)
{
    return le_key_k_type (ih_version (ih), &(ih->ih_key));
}


static inline void set_le_key_k_offset (int version, struct reiserfs_key * key, loff_t offset)
{
    (version == KEY_FORMAT_3_5) ?
        (void)(key->u.k_offset_v1.k_offset = cpu_to_le32 (offset)) : /* jdm check */
	(void)(set_offset_v2_k_offset( &(key->u.k_offset_v2), offset ));
}


static inline void set_le_ih_k_offset (struct item_head * ih, loff_t offset)
{
    set_le_key_k_offset (ih_version (ih), &(ih->ih_key), offset);
}


static inline void set_le_key_k_type (int version, struct reiserfs_key * key, int type)
{
    (version == KEY_FORMAT_3_5) ?

⌨️ 快捷键说明

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