1147476Sdumbbell/*- 2147476Sdumbbell * Copyright 2000 Hans Reiser 3147476Sdumbbell * See README for licensing and copyright details 4147476Sdumbbell * 5147476Sdumbbell * Ported to FreeBSD by Jean-S�bastien P�dron <jspedron@club-internet.fr> 6147476Sdumbbell * 7147476Sdumbbell * $FreeBSD$ 8147476Sdumbbell */ 9147476Sdumbbell 10147476Sdumbbell#ifndef _GNU_REISERFS_REISERFS_FS_H 11147476Sdumbbell#define _GNU_REISERFS_REISERFS_FS_H 12147476Sdumbbell 13147476Sdumbbell#include <sys/cdefs.h> 14147476Sdumbbell#include <sys/types.h> 15147476Sdumbbell#include <sys/endian.h> 16147476Sdumbbell#include <sys/param.h> 17147476Sdumbbell#include <sys/systm.h> 18147476Sdumbbell#include <sys/kernel.h> 19147476Sdumbbell#include <sys/mount.h> 20147476Sdumbbell#include <sys/namei.h> 21164033Srwatson#include <sys/priv.h> 22147476Sdumbbell#include <sys/proc.h> 23147476Sdumbbell#include <sys/vnode.h> 24147476Sdumbbell#include <sys/unistd.h> 25147476Sdumbbell 26147476Sdumbbell#include <sys/bio.h> 27147476Sdumbbell#include <sys/buf.h> 28147476Sdumbbell#include <sys/conf.h> 29147476Sdumbbell#include <sys/fcntl.h> 30147476Sdumbbell#include <sys/syslog.h> 31147476Sdumbbell 32147476Sdumbbell#include <sys/malloc.h> 33147476Sdumbbell#include <sys/dirent.h> 34147476Sdumbbell#include <sys/stat.h> 35147476Sdumbbell//#include <sys/mutex.h> 36147476Sdumbbell 37147476Sdumbbell#include <sys/ctype.h> 38147476Sdumbbell#include <sys/bitstring.h> 39147476Sdumbbell 40147476Sdumbbell#include <geom/geom.h> 41147476Sdumbbell#include <geom/geom_vfs.h> 42147476Sdumbbell 43147476Sdumbbell#include <gnu/fs/reiserfs/reiserfs_mount.h> 44147476Sdumbbell#include <gnu/fs/reiserfs/reiserfs_fs_sb.h> 45147476Sdumbbell#include <gnu/fs/reiserfs/reiserfs_fs_i.h> 46147476Sdumbbell 47147476Sdumbbell/* n must be power of 2 */ 48147476Sdumbbell#define _ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u)) 49147476Sdumbbell 50147476Sdumbbell/* To be ok for alpha and others we have to align structures to 8 byte 51147476Sdumbbell * boundary. */ 52147476Sdumbbell#define ROUND_UP(x) _ROUND_UP(x, 8LL) 53147476Sdumbbell 54147476Sdumbbell/* ------------------------------------------------------------------- 55147476Sdumbbell * Global variables 56147476Sdumbbell * -------------------------------------------------------------------*/ 57147476Sdumbbell 58147476Sdumbbellextern struct vop_vector reiserfs_vnodeops; 59147476Sdumbbellextern struct vop_vector reiserfs_specops; 60147476Sdumbbell 61147476Sdumbbell/* ------------------------------------------------------------------- 62147476Sdumbbell * Super block 63147476Sdumbbell * -------------------------------------------------------------------*/ 64147476Sdumbbell 65147476Sdumbbell#define REISERFS_BSIZE 1024 66147476Sdumbbell 67147476Sdumbbell/* ReiserFS leaves the first 64k unused, so that partition labels have 68147476Sdumbbell * enough space. If someone wants to write a fancy bootloader that needs 69147476Sdumbbell * more than 64k, let us know, and this will be increased in size. 70147476Sdumbbell * This number must be larger than than the largest block size on any 71147476Sdumbbell * platform, or code will break. -Hans */ 72147476Sdumbbell#define REISERFS_DISK_OFFSET 64 73147476Sdumbbell#define REISERFS_DISK_OFFSET_IN_BYTES \ 74147476Sdumbbell ((REISERFS_DISK_OFFSET) * (REISERFS_BSIZE)) 75147476Sdumbbell 76147476Sdumbbell/* The spot for the super in versions 3.5 - 3.5.10 (inclusive) */ 77147476Sdumbbell#define REISERFS_OLD_DISK_OFFSET 8 78147476Sdumbbell#define REISERFS_OLD_DISK_OFFSET_IN_BYTES \ 79147476Sdumbbell ((REISERFS_OLD_DISK_OFFSET) * (REISERFS_BSIZE)) 80147476Sdumbbell 81147476Sdumbbell/* 82147476Sdumbbell * Structure of a super block on disk, a version of which in RAM is 83147476Sdumbbell * often accessed as REISERFS_SB(s)->r_rs. The version in RAM is part of 84147476Sdumbbell * a larger structure containing fields never written to disk. 85147476Sdumbbell */ 86147476Sdumbbell 87147476Sdumbbell#define UNSET_HASH 0 /* read_super will guess about, what hash names 88147476Sdumbbell in directories were sorted with */ 89147476Sdumbbell#define TEA_HASH 1 90147476Sdumbbell#define YURA_HASH 2 91147476Sdumbbell#define R5_HASH 3 92147476Sdumbbell#define DEFAULT_HASH R5_HASH 93147476Sdumbbell 94147476Sdumbbellstruct journal_params { 95147476Sdumbbell uint32_t jp_journal_1st_block; /* Where does journal start 96147476Sdumbbell from on its device */ 97147476Sdumbbell uint32_t jp_journal_dev; /* Journal device st_rdev */ 98147476Sdumbbell uint32_t jp_journal_size; /* Size of the journal */ 99147476Sdumbbell uint32_t jp_journal_trans_max; /* Max number of blocks in 100147476Sdumbbell a transaction */ 101147476Sdumbbell uint32_t jp_journal_magic; /* Random value made on 102147476Sdumbbell fs creation (this was 103147476Sdumbbell sb_journal_block_count) */ 104147476Sdumbbell uint32_t jp_journal_max_batch; /* Max number of blocks to 105147476Sdumbbell batch into a 106147476Sdumbbell transaction */ 107147476Sdumbbell uint32_t jp_journal_max_commit_age; /* In seconds, how old can 108147476Sdumbbell an async commit be */ 109147476Sdumbbell uint32_t jp_journal_max_trans_age; /* In seconds, how old a 110147476Sdumbbell transaction be */ 111147476Sdumbbell}; 112147476Sdumbbell 113147476Sdumbbellstruct reiserfs_super_block_v1 { 114147476Sdumbbell uint32_t s_block_count; /* Blocks count */ 115147476Sdumbbell uint32_t s_free_blocks; /* Free blocks count */ 116147476Sdumbbell uint32_t s_root_block; /* Root block number */ 117147476Sdumbbell 118147476Sdumbbell struct journal_params s_journal; 119147476Sdumbbell 120147476Sdumbbell uint16_t s_blocksize; 121147476Sdumbbell uint16_t s_oid_maxsize; 122147476Sdumbbell uint16_t s_oid_cursize; 123147476Sdumbbell uint16_t s_umount_state; 124147476Sdumbbell 125147476Sdumbbell char s_magic[10]; 126147476Sdumbbell 127147476Sdumbbell uint16_t s_fs_state; 128147476Sdumbbell uint32_t s_hash_function_code; 129147476Sdumbbell uint16_t s_tree_height; 130147476Sdumbbell uint16_t s_bmap_nr; 131147476Sdumbbell uint16_t s_version; 132147476Sdumbbell uint16_t s_reserved_for_journal; 133147476Sdumbbell} __packed; 134147476Sdumbbell 135147476Sdumbbell#define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1)) 136147476Sdumbbell 137147476Sdumbbellstruct reiserfs_super_block { 138147476Sdumbbell struct reiserfs_super_block_v1 s_v1; 139147476Sdumbbell uint32_t s_inode_generation; 140147476Sdumbbell uint32_t s_flags; 141147476Sdumbbell unsigned char s_uuid[16]; 142147476Sdumbbell unsigned char s_label[16]; 143147476Sdumbbell char s_unused[88]; 144147476Sdumbbell} __packed; 145147476Sdumbbell 146147476Sdumbbell#define SB_SIZE (sizeof(struct reiserfs_super_block)) 147147476Sdumbbell 148147476Sdumbbell#define REISERFS_VERSION_1 0 149147476Sdumbbell#define REISERFS_VERSION_2 2 150147476Sdumbbell 151147476Sdumbbell#define REISERFS_SB(sbi) (sbi) 152147476Sdumbbell#define SB_DISK_SUPER_BLOCK(sbi) (REISERFS_SB(sbi)->s_rs) 153147476Sdumbbell#define SB_V1_DISK_SUPER_BLOCK(sbi) (&(SB_DISK_SUPER_BLOCK(sbi)->s_v1)) 154147476Sdumbbell 155147476Sdumbbell#define SB_BLOCKSIZE(sbi) \ 156147476Sdumbbell le32toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_blocksize)) 157147476Sdumbbell#define SB_BLOCK_COUNT(sbi) \ 158147476Sdumbbell le32toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_block_count)) 159147476Sdumbbell#define SB_FREE_BLOCKS(s) \ 160147476Sdumbbell le32toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_free_blocks)) 161147476Sdumbbell 162147476Sdumbbell#define SB_REISERFS_MAGIC(sbi) \ 163147476Sdumbbell (SB_V1_DISK_SUPER_BLOCK(sbi)->s_magic) 164147476Sdumbbell 165147476Sdumbbell#define SB_ROOT_BLOCK(sbi) \ 166147476Sdumbbell le32toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_root_block)) 167147476Sdumbbell 168147476Sdumbbell#define SB_TREE_HEIGHT(sbi) \ 169147476Sdumbbell le16toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_tree_height)) 170147476Sdumbbell 171147476Sdumbbell#define SB_REISERFS_STATE(sbi) \ 172147476Sdumbbell le16toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_umount_state)) 173147476Sdumbbell 174147476Sdumbbell#define SB_VERSION(sbi) le16toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_version)) 175147476Sdumbbell#define SB_BMAP_NR(sbi) le16toh((SB_V1_DISK_SUPER_BLOCK(sbi)->s_bmap_nr)) 176147476Sdumbbell 177147476Sdumbbell#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs" 178147476Sdumbbell#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" 179147476Sdumbbell#define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs" 180147476Sdumbbell 181147476Sdumbbellextern const char reiserfs_3_5_magic_string[]; 182147476Sdumbbellextern const char reiserfs_3_6_magic_string[]; 183147476Sdumbbellextern const char reiserfs_jr_magic_string[]; 184147476Sdumbbell 185147476Sdumbbellint is_reiserfs_3_5(struct reiserfs_super_block *rs); 186147476Sdumbbellint is_reiserfs_3_6(struct reiserfs_super_block *rs); 187147476Sdumbbellint is_reiserfs_jr(struct reiserfs_super_block *rs); 188147476Sdumbbell 189147476Sdumbbell/* ReiserFS internal error code (used by search_by_key and fix_nodes) */ 190147476Sdumbbell#define IO_ERROR -2 191147476Sdumbbell 192147476Sdumbbelltypedef uint32_t b_blocknr_t; 193147476Sdumbbelltypedef uint32_t unp_t; 194147476Sdumbbell 195147476Sdumbbellstruct unfm_nodeinfo { 196147476Sdumbbell unp_t unfm_nodenum; 197147476Sdumbbell unsigned short unfm_freespace; 198147476Sdumbbell}; 199147476Sdumbbell 200147476Sdumbbell/* There are two formats of keys: 3.5 and 3.6 */ 201147476Sdumbbell#define KEY_FORMAT_3_5 0 202147476Sdumbbell#define KEY_FORMAT_3_6 1 203147476Sdumbbell 204147476Sdumbbell/* There are two stat datas */ 205147476Sdumbbell#define STAT_DATA_V1 0 206147476Sdumbbell#define STAT_DATA_V2 1 207147476Sdumbbell 208147476Sdumbbell#define REISERFS_I(ip) (ip) 209147476Sdumbbell 210147476Sdumbbell#define get_inode_item_key_version(ip) \ 211147476Sdumbbell ((REISERFS_I(ip)->i_flags & i_item_key_version_mask) ? \ 212147476Sdumbbell KEY_FORMAT_3_6 : KEY_FORMAT_3_5) 213147476Sdumbbell 214147476Sdumbbell#define set_inode_item_key_version(ip, version) ({ \ 215147476Sdumbbell if ((version) == KEY_FORMAT_3_6) \ 216147476Sdumbbell REISERFS_I(ip)->i_flags |= i_item_key_version_mask; \ 217147476Sdumbbell else \ 218147476Sdumbbell REISERFS_I(ip)->i_flags &= ~i_item_key_version_mask; \ 219147476Sdumbbell}) 220147476Sdumbbell 221147476Sdumbbell#define get_inode_sd_version(ip) \ 222147476Sdumbbell ((REISERFS_I(ip)->i_flags & i_stat_data_version_mask) ? \ 223147476Sdumbbell STAT_DATA_V2 : STAT_DATA_V1) 224147476Sdumbbell 225147476Sdumbbell#define set_inode_sd_version(inode, version) ({ \ 226147476Sdumbbell if((version) == STAT_DATA_V2) \ 227147476Sdumbbell REISERFS_I(ip)->i_flags |= i_stat_data_version_mask; \ 228147476Sdumbbell else \ 229147476Sdumbbell REISERFS_I(ip)->i_flags &= ~i_stat_data_version_mask; \ 230147476Sdumbbell}) 231147476Sdumbbell 232147476Sdumbbell/* Values for s_umount_state field */ 233147476Sdumbbell#define REISERFS_VALID_FS 1 234147476Sdumbbell#define REISERFS_ERROR_FS 2 235147476Sdumbbell 236147476Sdumbbell/* There are 5 item types currently */ 237147476Sdumbbell#define TYPE_STAT_DATA 0 238147476Sdumbbell#define TYPE_INDIRECT 1 239147476Sdumbbell#define TYPE_DIRECT 2 240147476Sdumbbell#define TYPE_DIRENTRY 3 241147476Sdumbbell#define TYPE_MAXTYPE 3 242147476Sdumbbell#define TYPE_ANY 15 243147476Sdumbbell 244147476Sdumbbell/* ------------------------------------------------------------------- 245147476Sdumbbell * Key & item head 246147476Sdumbbell * -------------------------------------------------------------------*/ 247147476Sdumbbell 248147476Sdumbbellstruct offset_v1 { 249147476Sdumbbell uint32_t k_offset; 250147476Sdumbbell uint32_t k_uniqueness; 251147476Sdumbbell} __packed; 252147476Sdumbbell 253147476Sdumbbellstruct offset_v2 { 254147476Sdumbbell#if BYTE_ORDER == LITTLE_ENDIAN 255147476Sdumbbell /* little endian version */ 256147476Sdumbbell uint64_t k_offset:60; 257147476Sdumbbell uint64_t k_type:4; 258147476Sdumbbell#else 259147476Sdumbbell /* big endian version */ 260147476Sdumbbell uint64_t k_type:4; 261147476Sdumbbell uint64_t k_offset:60; 262147476Sdumbbell#endif 263147476Sdumbbell} __packed; 264147476Sdumbbell 265147476Sdumbbell#if (BYTE_ORDER == BIG_ENDIAN) 266147476Sdumbbelltypedef union { 267147476Sdumbbell struct offset_v2 offset_v2; 268147476Sdumbbell uint64_t linear; 269147476Sdumbbell} __packed offset_v2_esafe_overlay; 270147476Sdumbbell 271147476Sdumbbellstatic inline uint16_t 272147476Sdumbbelloffset_v2_k_type(const struct offset_v2 *v2) 273147476Sdumbbell{ 274147476Sdumbbell 275147476Sdumbbell offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; 276147476Sdumbbell tmp.linear = le64toh(tmp.linear); 277147476Sdumbbell return ((tmp.offset_v2.k_type <= TYPE_MAXTYPE) ? 278147476Sdumbbell tmp.offset_v2.k_type : TYPE_ANY); 279147476Sdumbbell} 280147476Sdumbbell 281147476Sdumbbellstatic inline void 282147476Sdumbbellset_offset_v2_k_type(struct offset_v2 *v2, int type) 283147476Sdumbbell{ 284147476Sdumbbell 285147476Sdumbbell offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2; 286147476Sdumbbell tmp->linear = le64toh(tmp->linear); 287147476Sdumbbell tmp->offset_v2.k_type = type; 288147476Sdumbbell tmp->linear = htole64(tmp->linear); 289147476Sdumbbell} 290147476Sdumbbell 291147476Sdumbbellstatic inline off_t 292147476Sdumbbelloffset_v2_k_offset(const struct offset_v2 *v2) 293147476Sdumbbell{ 294147476Sdumbbell 295147476Sdumbbell offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; 296147476Sdumbbell tmp.linear = le64toh(tmp.linear); 297147476Sdumbbell return (tmp.offset_v2.k_offset); 298147476Sdumbbell} 299147476Sdumbbell 300147476Sdumbbellstatic inline void 301147476Sdumbbellset_offset_v2_k_offset(struct offset_v2 *v2, off_t offset) 302147476Sdumbbell{ 303147476Sdumbbell 304147476Sdumbbell offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2; 305147476Sdumbbell tmp->linear = le64toh(tmp->linear); 306147476Sdumbbell tmp->offset_v2.k_offset = offset; 307147476Sdumbbell tmp->linear = htole64(tmp->linear); 308147476Sdumbbell} 309147476Sdumbbell#else /* BYTE_ORDER != BIG_ENDIAN */ 310147476Sdumbbell#define offset_v2_k_type(v2) ((v2)->k_type) 311147476Sdumbbell#define set_offset_v2_k_type(v2, val) (offset_v2_k_type(v2) = (val)) 312147476Sdumbbell#define offset_v2_k_offset(v2) ((v2)->k_offset) 313147476Sdumbbell#define set_offset_v2_k_offset(v2, val) (offset_v2_k_offset(v2) = (val)) 314147476Sdumbbell#endif /* BYTE_ORDER == BIG_ENDIAN */ 315147476Sdumbbell 316147476Sdumbbell/* 317147476Sdumbbell * Key of an item determines its location in the S+tree, and 318147476Sdumbbell * is composed of 4 components 319147476Sdumbbell */ 320147476Sdumbbellstruct key { 321147476Sdumbbell uint32_t k_dir_id; /* Packing locality: by default parent 322147476Sdumbbell directory object id */ 323147476Sdumbbell uint32_t k_objectid; /* Object identifier */ 324147476Sdumbbell union { 325147476Sdumbbell struct offset_v1 k_offset_v1; 326147476Sdumbbell struct offset_v2 k_offset_v2; 327147476Sdumbbell } __packed u; 328147476Sdumbbell} __packed; 329147476Sdumbbell 330147476Sdumbbellstruct cpu_key { 331147476Sdumbbell struct key on_disk_key; 332147476Sdumbbell int version; 333147476Sdumbbell int key_length; /* 3 in all cases but direct2indirect 334147476Sdumbbell and indirect2direct conversion */ 335147476Sdumbbell}; 336147476Sdumbbell 337147476Sdumbbell/* 338147476Sdumbbell * Our function for comparing keys can compare keys of different 339147476Sdumbbell * lengths. It takes as a parameter the length of the keys it is to 340147476Sdumbbell * compare. These defines are used in determining what is to be passed 341147476Sdumbbell * to it as that parameter. 342147476Sdumbbell */ 343147476Sdumbbell#define REISERFS_FULL_KEY_LEN 4 344147476Sdumbbell#define REISERFS_SHORT_KEY_LEN 2 345147476Sdumbbell 346147476Sdumbbell#define KEY_SIZE (sizeof(struct key)) 347147476Sdumbbell#define SHORT_KEY_SIZE (sizeof(uint32_t) + sizeof(uint32_t)) 348147476Sdumbbell 349147476Sdumbbell/* Return values for search_by_key and clones */ 350147476Sdumbbell#define ITEM_FOUND 1 351147476Sdumbbell#define ITEM_NOT_FOUND 0 352147476Sdumbbell#define ENTRY_FOUND 1 353147476Sdumbbell#define ENTRY_NOT_FOUND 0 354147476Sdumbbell#define DIRECTORY_NOT_FOUND -1 355147476Sdumbbell#define REGULAR_FILE_FOUND -2 356147476Sdumbbell#define DIRECTORY_FOUND -3 357147476Sdumbbell#define BYTE_FOUND 1 358147476Sdumbbell#define BYTE_NOT_FOUND 0 359147476Sdumbbell#define FILE_NOT_FOUND -1 360147476Sdumbbell 361147476Sdumbbell#define POSITION_FOUND 1 362147476Sdumbbell#define POSITION_NOT_FOUND 0 363147476Sdumbbell 364147476Sdumbbell/* Return values for reiserfs_find_entry and search_by_entry_key */ 365147476Sdumbbell#define NAME_FOUND 1 366147476Sdumbbell#define NAME_NOT_FOUND 0 367147476Sdumbbell#define GOTO_PREVIOUS_ITEM 2 368147476Sdumbbell#define NAME_FOUND_INVISIBLE 3 369147476Sdumbbell 370147476Sdumbbell/* 371147476Sdumbbell * Everything in the filesystem is stored as a set of items. The item 372147476Sdumbbell * head contains the key of the item, its free space (for indirect 373147476Sdumbbell * items) and specifies the location of the item itself within the 374147476Sdumbbell * block. 375147476Sdumbbell */ 376147476Sdumbbellstruct item_head { 377147476Sdumbbell /* 378147476Sdumbbell * Everything in the tree is found by searching for it based on 379147476Sdumbbell * its key. 380147476Sdumbbell */ 381147476Sdumbbell struct key ih_key; 382147476Sdumbbell union { 383147476Sdumbbell /* 384147476Sdumbbell * The free space in the last unformatted node of an 385147476Sdumbbell * indirect item if this is an indirect item. This 386147476Sdumbbell * equals 0xFFFF iff this is a direct item or stat data 387147476Sdumbbell * item. Note that the key, not this field, is used to 388147476Sdumbbell * determine the item type, and thus which field this 389147476Sdumbbell * union contains. 390147476Sdumbbell */ 391147476Sdumbbell uint16_t ih_free_space_reserved; 392147476Sdumbbell 393147476Sdumbbell /* 394147476Sdumbbell * If this is a directory item, this field equals the number of 395147476Sdumbbell * directory entries in the directory item. 396147476Sdumbbell */ 397147476Sdumbbell uint16_t ih_entry_count; 398147476Sdumbbell } __packed u; 399147476Sdumbbell uint16_t ih_item_len; /* Total size of the item body */ 400147476Sdumbbell uint16_t ih_item_location; /* An offset to the item body within 401147476Sdumbbell the block */ 402147476Sdumbbell uint16_t ih_version; /* 0 for all old items, 2 for new 403147476Sdumbbell ones. Highest bit is set by fsck 404147476Sdumbbell temporary, cleaned after all 405147476Sdumbbell done */ 406147476Sdumbbell} __packed; 407147476Sdumbbell 408147476Sdumbbell/* Size of item header */ 409147476Sdumbbell#define IH_SIZE (sizeof(struct item_head)) 410147476Sdumbbell 411147476Sdumbbell#define ih_free_space(ih) le16toh((ih)->u.ih_free_space_reserved) 412147476Sdumbbell#define ih_version(ih) le16toh((ih)->ih_version) 413147476Sdumbbell#define ih_entry_count(ih) le16toh((ih)->u.ih_entry_count) 414147476Sdumbbell#define ih_location(ih) le16toh((ih)->ih_item_location) 415147476Sdumbbell#define ih_item_len(ih) le16toh((ih)->ih_item_len) 416147476Sdumbbell 417147476Sdumbbell/* 418147476Sdumbbell * These operate on indirect items, where you've got an array of ints at 419147476Sdumbbell * a possibly unaligned location. These are a noop on IA32. 420147476Sdumbbell * 421147476Sdumbbell * p is the array of uint32_t, i is the index into the array, v is the 422147476Sdumbbell * value to store there. 423147476Sdumbbell */ 424147476Sdumbbell#define get_unaligned(ptr) \ 425147476Sdumbbell ({ __typeof__(*(ptr)) __tmp; \ 426147476Sdumbbell memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) 427147476Sdumbbell 428147476Sdumbbell#define put_unaligned(val, ptr) \ 429147476Sdumbbell ({ __typeof__(*(ptr)) __tmp = (val); \ 430147476Sdumbbell memcpy((ptr), &__tmp, sizeof(*(ptr))); \ 431147476Sdumbbell (void)0; }) 432147476Sdumbbell 433147476Sdumbbell#define get_block_num(p, i) le32toh(get_unaligned((p) + (i))) 434147476Sdumbbell#define put_block_num(p, i, v) put_unaligned(htole32(v), (p) + (i)) 435147476Sdumbbell 436147476Sdumbbell/* In old version uniqueness field shows key type */ 437147476Sdumbbell#define V1_SD_UNIQUENESS 0 438147476Sdumbbell#define V1_INDIRECT_UNIQUENESS 0xfffffffe 439147476Sdumbbell#define V1_DIRECT_UNIQUENESS 0xffffffff 440147476Sdumbbell#define V1_DIRENTRY_UNIQUENESS 500 441147476Sdumbbell#define V1_ANY_UNIQUENESS 555 442147476Sdumbbell 443147476Sdumbbell/* Here are conversion routines */ 444147476Sdumbbellstatic inline int uniqueness2type(uint32_t uniqueness); 445147476Sdumbbellstatic inline uint32_t type2uniqueness(int type); 446147476Sdumbbell 447147476Sdumbbellstatic inline int 448147476Sdumbbelluniqueness2type(uint32_t uniqueness) 449147476Sdumbbell{ 450147476Sdumbbell 451147476Sdumbbell switch ((int)uniqueness) { 452147476Sdumbbell case V1_SD_UNIQUENESS: 453147476Sdumbbell return (TYPE_STAT_DATA); 454147476Sdumbbell case V1_INDIRECT_UNIQUENESS: 455147476Sdumbbell return (TYPE_INDIRECT); 456147476Sdumbbell case V1_DIRECT_UNIQUENESS: 457147476Sdumbbell return (TYPE_DIRECT); 458147476Sdumbbell case V1_DIRENTRY_UNIQUENESS: 459147476Sdumbbell return (TYPE_DIRENTRY); 460147476Sdumbbell default: 461147476Sdumbbell log(LOG_NOTICE, "reiserfs: unknown uniqueness (%u)\n", 462147476Sdumbbell uniqueness); 463147476Sdumbbell case V1_ANY_UNIQUENESS: 464147476Sdumbbell return (TYPE_ANY); 465147476Sdumbbell } 466147476Sdumbbell} 467147476Sdumbbell 468147476Sdumbbellstatic inline uint32_t 469147476Sdumbbelltype2uniqueness(int type) 470147476Sdumbbell{ 471147476Sdumbbell 472147476Sdumbbell switch (type) { 473147476Sdumbbell case TYPE_STAT_DATA: 474147476Sdumbbell return (V1_SD_UNIQUENESS); 475147476Sdumbbell case TYPE_INDIRECT: 476147476Sdumbbell return (V1_INDIRECT_UNIQUENESS); 477147476Sdumbbell case TYPE_DIRECT: 478147476Sdumbbell return (V1_DIRECT_UNIQUENESS); 479147476Sdumbbell case TYPE_DIRENTRY: 480147476Sdumbbell return (V1_DIRENTRY_UNIQUENESS); 481147476Sdumbbell default: 482147476Sdumbbell log(LOG_NOTICE, "reiserfs: unknown type (%u)\n", type); 483147476Sdumbbell case TYPE_ANY: 484147476Sdumbbell return (V1_ANY_UNIQUENESS); 485147476Sdumbbell } 486147476Sdumbbell} 487147476Sdumbbell 488147476Sdumbbell/* 489147476Sdumbbell * Key is pointer to on disk key which is stored in le, result is cpu, 490147476Sdumbbell * there is no way to get version of object from key, so, provide 491147476Sdumbbell * version to these defines. 492147476Sdumbbell */ 493147476Sdumbbellstatic inline off_t 494147476Sdumbbellle_key_k_offset(int version, const struct key *key) 495147476Sdumbbell{ 496147476Sdumbbell 497147476Sdumbbell return ((version == KEY_FORMAT_3_5) ? 498147476Sdumbbell le32toh(key->u.k_offset_v1.k_offset) : 499147476Sdumbbell offset_v2_k_offset(&(key->u.k_offset_v2))); 500147476Sdumbbell} 501147476Sdumbbell 502147476Sdumbbellstatic inline off_t 503147476Sdumbbellle_ih_k_offset(const struct item_head *ih) 504147476Sdumbbell{ 505147476Sdumbbell 506147476Sdumbbell return (le_key_k_offset(ih_version(ih), &(ih->ih_key))); 507147476Sdumbbell} 508147476Sdumbbell 509147476Sdumbbellstatic inline off_t 510147476Sdumbbellle_key_k_type(int version, const struct key *key) 511147476Sdumbbell{ 512147476Sdumbbell 513147476Sdumbbell return ((version == KEY_FORMAT_3_5) ? 514147476Sdumbbell uniqueness2type(le32toh(key->u.k_offset_v1.k_uniqueness)) : 515147476Sdumbbell offset_v2_k_type(&(key->u.k_offset_v2))); 516147476Sdumbbell} 517147476Sdumbbell 518147476Sdumbbellstatic inline off_t 519147476Sdumbbellle_ih_k_type(const struct item_head *ih) 520147476Sdumbbell{ 521147476Sdumbbell return (le_key_k_type(ih_version(ih), &(ih->ih_key))); 522147476Sdumbbell} 523147476Sdumbbell 524147476Sdumbbellstatic inline void 525147476Sdumbbellset_le_key_k_offset(int version, struct key *key, off_t offset) 526147476Sdumbbell{ 527147476Sdumbbell 528147476Sdumbbell (version == KEY_FORMAT_3_5) ? 529147476Sdumbbell (key->u.k_offset_v1.k_offset = htole32(offset)) : 530147476Sdumbbell (set_offset_v2_k_offset(&(key->u.k_offset_v2), offset)); 531147476Sdumbbell} 532147476Sdumbbell 533147476Sdumbbellstatic inline void 534147476Sdumbbellset_le_ih_k_offset(struct item_head *ih, off_t offset) 535147476Sdumbbell{ 536147476Sdumbbell 537147476Sdumbbell set_le_key_k_offset(ih_version(ih), &(ih->ih_key), offset); 538147476Sdumbbell} 539147476Sdumbbell 540147476Sdumbbellstatic inline void 541147476Sdumbbellset_le_key_k_type(int version, struct key *key, int type) 542147476Sdumbbell{ 543147476Sdumbbell 544147476Sdumbbell (version == KEY_FORMAT_3_5) ? 545147476Sdumbbell (key->u.k_offset_v1.k_uniqueness = 546147476Sdumbbell htole32(type2uniqueness(type))) : 547147476Sdumbbell (set_offset_v2_k_type(&(key->u.k_offset_v2), type)); 548147476Sdumbbell} 549147476Sdumbbell 550147476Sdumbbellstatic inline void 551147476Sdumbbellset_le_ih_k_type(struct item_head *ih, int type) 552147476Sdumbbell{ 553147476Sdumbbell 554147476Sdumbbell set_le_key_k_type(ih_version(ih), &(ih->ih_key), type); 555147476Sdumbbell} 556147476Sdumbbell 557147476Sdumbbell#define is_direntry_le_key(version, key) \ 558147476Sdumbbell (le_key_k_type(version, key) == TYPE_DIRENTRY) 559147476Sdumbbell#define is_direct_le_key(version, key) \ 560147476Sdumbbell (le_key_k_type(version, key) == TYPE_DIRECT) 561147476Sdumbbell#define is_indirect_le_key(version, key) \ 562147476Sdumbbell (le_key_k_type(version, key) == TYPE_INDIRECT) 563147476Sdumbbell#define is_statdata_le_key(version, key) \ 564147476Sdumbbell (le_key_k_type(version, key) == TYPE_STAT_DATA) 565147476Sdumbbell 566147476Sdumbbell/* Item header has version. */ 567147476Sdumbbell#define is_direntry_le_ih(ih) \ 568147476Sdumbbell is_direntry_le_key(ih_version(ih), &((ih)->ih_key)) 569147476Sdumbbell#define is_direct_le_ih(ih) \ 570147476Sdumbbell is_direct_le_key(ih_version(ih), &((ih)->ih_key)) 571147476Sdumbbell#define is_indirect_le_ih(ih) \ 572147476Sdumbbell is_indirect_le_key(ih_version(ih), &((ih)->ih_key)) 573147476Sdumbbell#define is_statdata_le_ih(ih) \ 574147476Sdumbbell is_statdata_le_key(ih_version(ih), &((ih)->ih_key)) 575147476Sdumbbell 576147476Sdumbbellstatic inline void 577147476Sdumbbellset_cpu_key_k_offset(struct cpu_key *key, off_t offset) 578147476Sdumbbell{ 579147476Sdumbbell 580147476Sdumbbell (key->version == KEY_FORMAT_3_5) ? 581147476Sdumbbell (key->on_disk_key.u.k_offset_v1.k_offset = offset) : 582147476Sdumbbell (key->on_disk_key.u.k_offset_v2.k_offset = offset); 583147476Sdumbbell} 584147476Sdumbbell 585147476Sdumbbellstatic inline void 586147476Sdumbbellset_cpu_key_k_type(struct cpu_key *key, int type) 587147476Sdumbbell{ 588147476Sdumbbell 589147476Sdumbbell (key->version == KEY_FORMAT_3_5) ? 590147476Sdumbbell (key->on_disk_key.u.k_offset_v1.k_uniqueness = 591147476Sdumbbell type2uniqueness(type)): 592147476Sdumbbell (key->on_disk_key.u.k_offset_v2.k_type = type); 593147476Sdumbbell} 594147476Sdumbbell 595147476Sdumbbell#define is_direntry_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRENTRY) 596147476Sdumbbell#define is_direct_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRECT) 597147476Sdumbbell#define is_indirect_cpu_key(key) (cpu_key_k_type (key) == TYPE_INDIRECT) 598147476Sdumbbell#define is_statdata_cpu_key(key) (cpu_key_k_type (key) == TYPE_STAT_DATA) 599147476Sdumbbell 600147476Sdumbbell/* Maximal length of item */ 601147476Sdumbbell#define MAX_ITEM_LEN(block_size) (block_size - BLKH_SIZE - IH_SIZE) 602147476Sdumbbell#define MIN_ITEM_LEN 1 603147476Sdumbbell 604147476Sdumbbell/* Object identifier for root dir */ 605147476Sdumbbell#define REISERFS_ROOT_OBJECTID 2 606147476Sdumbbell#define REISERFS_ROOT_PARENT_OBJECTID 1 607147476Sdumbbell 608147476Sdumbbell/* key is pointer to cpu key, result is cpu */ 609147476Sdumbbellstatic inline off_t 610147476Sdumbbellcpu_key_k_offset(const struct cpu_key *key) 611147476Sdumbbell{ 612147476Sdumbbell 613147476Sdumbbell return ((key->version == KEY_FORMAT_3_5) ? 614147476Sdumbbell key->on_disk_key.u.k_offset_v1.k_offset : 615147476Sdumbbell key->on_disk_key.u.k_offset_v2.k_offset); 616147476Sdumbbell} 617147476Sdumbbell 618147476Sdumbbellstatic inline off_t 619147476Sdumbbellcpu_key_k_type(const struct cpu_key *key) 620147476Sdumbbell{ 621147476Sdumbbell 622147476Sdumbbell return ((key->version == KEY_FORMAT_3_5) ? 623147476Sdumbbell uniqueness2type(key->on_disk_key.u.k_offset_v1.k_uniqueness) : 624147476Sdumbbell key->on_disk_key.u.k_offset_v2.k_type); 625147476Sdumbbell} 626147476Sdumbbell 627147476Sdumbbell/* 628147476Sdumbbell * Header of a disk block. More precisely, header of a formatted leaf 629147476Sdumbbell * or internal node, and not the header of an unformatted node. 630147476Sdumbbell */ 631147476Sdumbbellstruct block_head { 632147476Sdumbbell uint16_t blk_level; /* Level of a block in the 633147476Sdumbbell tree. */ 634147476Sdumbbell uint16_t blk_nr_item; /* Number of keys/items in a 635147476Sdumbbell block. */ 636147476Sdumbbell uint16_t blk_free_space; /* Block free space in bytes. */ 637147476Sdumbbell uint16_t blk_reserved; /* Dump this in v4/planA */ 638147476Sdumbbell struct key blk_right_delim_key; /* Kept only for compatibility */ 639147476Sdumbbell}; 640147476Sdumbbell 641147476Sdumbbell#define BLKH_SIZE (sizeof(struct block_head)) 642147476Sdumbbell#define blkh_level(p_blkh) (le16toh((p_blkh)->blk_level)) 643147476Sdumbbell#define blkh_nr_item(p_blkh) (le16toh((p_blkh)->blk_nr_item)) 644147476Sdumbbell#define blkh_free_space(p_blkh) (le16toh((p_blkh)->blk_free_space)) 645147476Sdumbbell 646147476Sdumbbell#define FREE_LEVEL 0 /* When node gets removed from the tree its 647147476Sdumbbell blk_level is set to FREE_LEVEL. It is then 648147476Sdumbbell used to see whether the node is still in the 649147476Sdumbbell tree */ 650147476Sdumbbell 651147476Sdumbbell/* Values for blk_level field of the struct block_head */ 652147476Sdumbbell#define DISK_LEAF_NODE_LEVEL 1 /* Leaf node level.*/ 653147476Sdumbbell 654147476Sdumbbell/* 655147476Sdumbbell * Given the buffer head of a formatted node, resolve to the block head 656147476Sdumbbell * of that node. 657147476Sdumbbell */ 658147476Sdumbbell#define B_BLK_HEAD(p_s_bp) ((struct block_head *)((p_s_bp)->b_data)) 659147476Sdumbbell#define B_NR_ITEMS(p_s_bp) (blkh_nr_item(B_BLK_HEAD(p_s_bp))) 660147476Sdumbbell#define B_LEVEL(p_s_bp) (blkh_level(B_BLK_HEAD(p_s_bp))) 661147476Sdumbbell#define B_FREE_SPACE(p_s_bp) (blkh_free_space(B_BLK_HEAD(p_s_bp))) 662147476Sdumbbell 663147476Sdumbbell/* ------------------------------------------------------------------- 664147476Sdumbbell * Stat data 665147476Sdumbbell * -------------------------------------------------------------------*/ 666147476Sdumbbell 667147476Sdumbbell/* 668147476Sdumbbell * Old stat data is 32 bytes long. We are going to distinguish new one 669147476Sdumbbell * by different size. 670147476Sdumbbell */ 671147476Sdumbbellstruct stat_data_v1 { 672147476Sdumbbell uint16_t sd_mode; /* File type, permissions */ 673147476Sdumbbell uint16_t sd_nlink; /* Number of hard links */ 674147476Sdumbbell uint16_t sd_uid; /* Owner */ 675147476Sdumbbell uint16_t sd_gid; /* Group */ 676147476Sdumbbell uint32_t sd_size; /* File size */ 677147476Sdumbbell uint32_t sd_atime; /* Time of last access */ 678147476Sdumbbell uint32_t sd_mtime; /* Time file was last modified */ 679147476Sdumbbell uint32_t sd_ctime; /* Time inode (stat data) was last changed 680147476Sdumbbell (except changes to sd_atime and 681147476Sdumbbell sd_mtime) */ 682147476Sdumbbell union { 683147476Sdumbbell uint32_t sd_rdev; 684147476Sdumbbell uint32_t sd_blocks; /* Number of blocks file uses */ 685147476Sdumbbell } __packed u; 686147476Sdumbbell uint32_t sd_first_direct_byte; /* First byte of file which is 687147476Sdumbbell stored in a direct item: 688147476Sdumbbell except that if it equals 1 689147476Sdumbbell it is a symlink and if it 690147476Sdumbbell equals ~(uint32_t)0 there 691147476Sdumbbell is no direct item. The 692147476Sdumbbell existence of this field 693147476Sdumbbell really grates on me. Let's 694147476Sdumbbell replace it with a macro based 695147476Sdumbbell on sd_size and our tail 696147476Sdumbbell suppression policy. Someday. 697147476Sdumbbell -Hans */ 698147476Sdumbbell} __packed; 699147476Sdumbbell 700147476Sdumbbell#define SD_V1_SIZE (sizeof(struct stat_data_v1)) 701147476Sdumbbell#define stat_data_v1(ih) (ih_version (ih) == KEY_FORMAT_3_5) 702147476Sdumbbell#define sd_v1_mode(sdp) (le16toh((sdp)->sd_mode)) 703147476Sdumbbell#define set_sd_v1_mode(sdp, v) ((sdp)->sd_mode = htole16(v)) 704147476Sdumbbell#define sd_v1_nlink(sdp) (le16toh((sdp)->sd_nlink)) 705147476Sdumbbell#define set_sd_v1_nlink(sdp, v) ((sdp)->sd_nlink = htole16(v)) 706147476Sdumbbell#define sd_v1_uid(sdp) (le16toh((sdp)->sd_uid)) 707147476Sdumbbell#define set_sd_v1_uid(sdp, v) ((sdp)->sd_uid = htole16(v)) 708147476Sdumbbell#define sd_v1_gid(sdp) (le16toh((sdp)->sd_gid)) 709147476Sdumbbell#define set_sd_v1_gid(sdp, v) ((sdp)->sd_gid = htole16(v)) 710147476Sdumbbell#define sd_v1_size(sdp) (le32toh((sdp)->sd_size)) 711147476Sdumbbell#define set_sd_v1_size(sdp, v) ((sdp)->sd_size = htole32(v)) 712147476Sdumbbell#define sd_v1_atime(sdp) (le32toh((sdp)->sd_atime)) 713147476Sdumbbell#define set_sd_v1_atime(sdp, v) ((sdp)->sd_atime = htole32(v)) 714147476Sdumbbell#define sd_v1_mtime(sdp) (le32toh((sdp)->sd_mtime)) 715147476Sdumbbell#define set_sd_v1_mtime(sdp, v) ((sdp)->sd_mtime = htole32(v)) 716147476Sdumbbell#define sd_v1_ctime(sdp) (le32toh((sdp)->sd_ctime)) 717147476Sdumbbell#define set_sd_v1_ctime(sdp, v) ((sdp)->sd_ctime = htole32(v)) 718147476Sdumbbell#define sd_v1_rdev(sdp) (le32toh((sdp)->u.sd_rdev)) 719147476Sdumbbell#define set_sd_v1_rdev(sdp, v) ((sdp)->u.sd_rdev = htole32(v)) 720147476Sdumbbell#define sd_v1_blocks(sdp) (le32toh((sdp)->u.sd_blocks)) 721147476Sdumbbell#define set_sd_v1_blocks(sdp, v) ((sdp)->u.sd_blocks = htole32(v)) 722147476Sdumbbell#define sd_v1_first_direct_byte(sdp) \ 723147476Sdumbbell (le32toh((sdp)->sd_first_direct_byte)) 724147476Sdumbbell#define set_sd_v1_first_direct_byte(sdp, v) \ 725147476Sdumbbell ((sdp)->sd_first_direct_byte = htole32(v)) 726147476Sdumbbell 727147476Sdumbbell/* 728147476Sdumbbell * We want common flags to have the same values as in ext2, 729147476Sdumbbell * so chattr(1) will work without problems 730147476Sdumbbell */ 731202283Slulf#include <fs/ext2fs/ext2fs.h> 732202283Slulf#include <fs/ext2fs/ext2_dinode.h> 733202283Slulf#define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE 734202283Slulf#define REISERFS_APPEND_FL EXT2_APPEND 735202283Slulf#define REISERFS_SYNC_FL EXT2_SYNC 736202283Slulf#define REISERFS_NOATIME_FL EXT2_NOATIME 737202283Slulf#define REISERFS_NODUMP_FL EXT2_NODUMP 738202283Slulf#define REISERFS_SECRM_FL EXT2_SECRM 739202283Slulf#define REISERFS_UNRM_FL EXT2_UNRM 740202283Slulf#define REISERFS_COMPR_FL EXT2_COMPR 741147476Sdumbbell#define REISERFS_NOTAIL_FL EXT2_NOTAIL_FL 742147476Sdumbbell 743147476Sdumbbell/* 744147476Sdumbbell * Stat Data on disk (reiserfs version of UFS disk inode minus the 745147476Sdumbbell * address blocks) 746147476Sdumbbell */ 747147476Sdumbbellstruct stat_data { 748147476Sdumbbell uint16_t sd_mode; /* File type, permissions */ 749147476Sdumbbell uint16_t sd_attrs; /* Persistent inode flags */ 750147476Sdumbbell uint32_t sd_nlink; /* Number of hard links */ 751147476Sdumbbell uint64_t sd_size; /* File size */ 752147476Sdumbbell uint32_t sd_uid; /* Owner */ 753147476Sdumbbell uint32_t sd_gid; /* Group */ 754147476Sdumbbell uint32_t sd_atime; /* Time of last access */ 755147476Sdumbbell uint32_t sd_mtime; /* Time file was last modified */ 756147476Sdumbbell uint32_t sd_ctime; /* Time inode (stat data) was last changed 757147476Sdumbbell (except changes to sd_atime and 758147476Sdumbbell sd_mtime) */ 759147476Sdumbbell uint32_t sd_blocks; 760147476Sdumbbell union { 761147476Sdumbbell uint32_t sd_rdev; 762147476Sdumbbell uint32_t sd_generation; 763147476Sdumbbell //uint32_t sd_first_direct_byte; 764147476Sdumbbell /* 765147476Sdumbbell * First byte of file which is stored in a 766147476Sdumbbell * direct item: except that if it equals 1 767147476Sdumbbell * it is a symlink and if it equals 768147476Sdumbbell * ~(uint32_t)0 there is no direct item. The 769147476Sdumbbell * existence of this field really grates 770147476Sdumbbell * on me. Let's replace it with a macro 771147476Sdumbbell * based on sd_size and our tail 772147476Sdumbbell * suppression policy? 773147476Sdumbbell */ 774147476Sdumbbell } __packed u; 775147476Sdumbbell} __packed; 776147476Sdumbbell 777147476Sdumbbell/* This is 44 bytes long */ 778147476Sdumbbell#define SD_SIZE (sizeof(struct stat_data)) 779147476Sdumbbell#define SD_V2_SIZE SD_SIZE 780147476Sdumbbell#define stat_data_v2(ih) (ih_version (ih) == KEY_FORMAT_3_6) 781147476Sdumbbell#define sd_v2_mode(sdp) (le16toh((sdp)->sd_mode)) 782147476Sdumbbell#define set_sd_v2_mode(sdp, v) ((sdp)->sd_mode = htole16(v)) 783147476Sdumbbell/* sd_reserved */ 784147476Sdumbbell/* set_sd_reserved */ 785147476Sdumbbell#define sd_v2_nlink(sdp) (le32toh((sdp)->sd_nlink)) 786147476Sdumbbell#define set_sd_v2_nlink(sdp, v) ((sdp)->sd_nlink = htole32(v)) 787147476Sdumbbell#define sd_v2_size(sdp) (le64toh((sdp)->sd_size)) 788147476Sdumbbell#define set_sd_v2_size(sdp, v) ((sdp)->sd_size = cpu_to_le64(v)) 789147476Sdumbbell#define sd_v2_uid(sdp) (le32toh((sdp)->sd_uid)) 790147476Sdumbbell#define set_sd_v2_uid(sdp, v) ((sdp)->sd_uid = htole32(v)) 791147476Sdumbbell#define sd_v2_gid(sdp) (le32toh((sdp)->sd_gid)) 792147476Sdumbbell#define set_sd_v2_gid(sdp, v) ((sdp)->sd_gid = htole32(v)) 793147476Sdumbbell#define sd_v2_atime(sdp) (le32toh((sdp)->sd_atime)) 794147476Sdumbbell#define set_sd_v2_atime(sdp, v) ((sdp)->sd_atime = htole32(v)) 795147476Sdumbbell#define sd_v2_mtime(sdp) (le32toh((sdp)->sd_mtime)) 796147476Sdumbbell#define set_sd_v2_mtime(sdp, v) ((sdp)->sd_mtime = htole32(v)) 797147476Sdumbbell#define sd_v2_ctime(sdp) (le32toh((sdp)->sd_ctime)) 798147476Sdumbbell#define set_sd_v2_ctime(sdp, v) ((sdp)->sd_ctime = htole32(v)) 799147476Sdumbbell#define sd_v2_blocks(sdp) (le32toh((sdp)->sd_blocks)) 800147476Sdumbbell#define set_sd_v2_blocks(sdp, v) ((sdp)->sd_blocks = htole32(v)) 801147476Sdumbbell#define sd_v2_rdev(sdp) (le32toh((sdp)->u.sd_rdev)) 802147476Sdumbbell#define set_sd_v2_rdev(sdp, v) ((sdp)->u.sd_rdev = htole32(v)) 803147476Sdumbbell#define sd_v2_generation(sdp) (le32toh((sdp)->u.sd_generation)) 804147476Sdumbbell#define set_sd_v2_generation(sdp, v) ((sdp)->u.sd_generation = htole32(v)) 805147476Sdumbbell#define sd_v2_attrs(sdp) (le16toh((sdp)->sd_attrs)) 806147476Sdumbbell#define set_sd_v2_attrs(sdp, v) ((sdp)->sd_attrs = htole16(v)) 807147476Sdumbbell 808147476Sdumbbell/* ------------------------------------------------------------------- 809147476Sdumbbell * Directory structure 810147476Sdumbbell * -------------------------------------------------------------------*/ 811147476Sdumbbell 812147476Sdumbbell#define SD_OFFSET 0 813147476Sdumbbell#define SD_UNIQUENESS 0 814147476Sdumbbell#define DOT_OFFSET 1 815147476Sdumbbell#define DOT_DOT_OFFSET 2 816147476Sdumbbell#define DIRENTRY_UNIQUENESS 500 817147476Sdumbbell 818147476Sdumbbell#define FIRST_ITEM_OFFSET 1 819147476Sdumbbell 820147476Sdumbbellstruct reiserfs_de_head { 821147476Sdumbbell uint32_t deh_offset; /* Third component of the directory 822147476Sdumbbell entry key */ 823147476Sdumbbell uint32_t deh_dir_id; /* Objectid of the parent directory of 824147476Sdumbbell the object, that is referenced by 825147476Sdumbbell directory entry */ 826147476Sdumbbell uint32_t deh_objectid; /* Objectid of the object, that is 827147476Sdumbbell referenced by directory entry */ 828147476Sdumbbell uint16_t deh_location; /* Offset of name in the whole item */ 829147476Sdumbbell uint16_t deh_state; /* Whether 1) entry contains stat data 830147476Sdumbbell (for future), and 2) whether entry 831147476Sdumbbell is hidden (unlinked) */ 832147476Sdumbbell} __packed; 833147476Sdumbbell 834147476Sdumbbell#define DEH_SIZE sizeof(struct reiserfs_de_head) 835147476Sdumbbell#define deh_offset(p_deh) (le32toh((p_deh)->deh_offset)) 836147476Sdumbbell#define deh_dir_id(p_deh) (le32toh((p_deh)->deh_dir_id)) 837147476Sdumbbell#define deh_objectid(p_deh) (le32toh((p_deh)->deh_objectid)) 838147476Sdumbbell#define deh_location(p_deh) (le16toh((p_deh)->deh_location)) 839147476Sdumbbell#define deh_state(p_deh) (le16toh((p_deh)->deh_state)) 840147476Sdumbbell 841147476Sdumbbell#define put_deh_offset(p_deh, v) ((p_deh)->deh_offset = htole32((v))) 842147476Sdumbbell#define put_deh_dir_id(p_deh, v) ((p_deh)->deh_dir_id = htole32((v))) 843147476Sdumbbell#define put_deh_objectid(p_deh, v) ((p_deh)->deh_objectid = htole32((v))) 844147476Sdumbbell#define put_deh_location(p_deh, v) ((p_deh)->deh_location = htole16((v))) 845147476Sdumbbell#define put_deh_state(p_deh, v) ((p_deh)->deh_state = htole16((v))) 846147476Sdumbbell 847147476Sdumbbell/* Empty directory contains two entries "." and ".." and their headers */ 848147476Sdumbbell#define EMPTY_DIR_SIZE \ 849147476Sdumbbell (DEH_SIZE * 2 + ROUND_UP(strlen(".")) + ROUND_UP(strlen(".."))) 850147476Sdumbbell 851147476Sdumbbell/* Old format directories have this size when empty */ 852147476Sdumbbell#define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3) 853147476Sdumbbell 854147476Sdumbbell#define DEH_Statdata 0 /* Not used now */ 855147476Sdumbbell#define DEH_Visible 2 856147476Sdumbbell 857147512Sdumbbell/* Macro to map Linux' *_bit function to bitstring.h macros */ 858147512Sdumbbell#define set_bit(bit, name) bit_set((bitstr_t *)name, bit) 859147512Sdumbbell#define clear_bit(bit, name) bit_clear((bitstr_t *)name, bit) 860147512Sdumbbell#define test_bit(bit, name) bit_test((bitstr_t *)name, bit) 861147476Sdumbbell 862147512Sdumbbell#define set_bit_unaligned(bit, name) set_bit(bit, name) 863147512Sdumbbell#define clear_bit_unaligned(bit, name) clear_bit(bit, name) 864147512Sdumbbell#define test_bit_unaligned(bit, name) test_bit(bit, name) 865147476Sdumbbell 866147476Sdumbbell#define mark_de_with_sd(deh) \ 867147476Sdumbbell set_bit_unaligned(DEH_Statdata, &((deh)->deh_state)) 868147476Sdumbbell#define mark_de_without_sd(deh) \ 869147476Sdumbbell clear_bit_unaligned(DEH_Statdata, &((deh)->deh_state)) 870147476Sdumbbell#define mark_de_visible(deh) \ 871147476Sdumbbell set_bit_unaligned (DEH_Visible, &((deh)->deh_state)) 872147476Sdumbbell#define mark_de_hidden(deh) \ 873147476Sdumbbell clear_bit_unaligned (DEH_Visible, &((deh)->deh_state)) 874147476Sdumbbell 875147476Sdumbbell#define de_with_sd(deh) \ 876147476Sdumbbell test_bit_unaligned(DEH_Statdata, &((deh)->deh_state)) 877147476Sdumbbell#define de_visible(deh) \ 878147476Sdumbbell test_bit_unaligned(DEH_Visible, &((deh)->deh_state)) 879147476Sdumbbell#define de_hidden(deh) \ 880147476Sdumbbell !test_bit_unaligned(DEH_Visible, &((deh)->deh_state)) 881147476Sdumbbell 882147476Sdumbbell/* Two entries per block (at least) */ 883147476Sdumbbell#define REISERFS_MAX_NAME(block_size) 255 884147476Sdumbbell 885147476Sdumbbell/* 886147476Sdumbbell * This structure is used for operations on directory entries. It is not 887147476Sdumbbell * a disk structure. When reiserfs_find_entry or search_by_entry_key 888147476Sdumbbell * find directory entry, they return filled reiserfs_dir_entry structure 889147476Sdumbbell */ 890147476Sdumbbellstruct reiserfs_dir_entry { 891147476Sdumbbell struct buf *de_bp; 892147476Sdumbbell int de_item_num; 893147476Sdumbbell struct item_head *de_ih; 894147476Sdumbbell int de_entry_num; 895147476Sdumbbell struct reiserfs_de_head *de_deh; 896147476Sdumbbell int de_entrylen; 897147476Sdumbbell int de_namelen; 898147476Sdumbbell char *de_name; 899147476Sdumbbell char *de_gen_number_bit_string; 900147476Sdumbbell 901147476Sdumbbell uint32_t de_dir_id; 902147476Sdumbbell uint32_t de_objectid; 903147476Sdumbbell 904147476Sdumbbell struct cpu_key de_entry_key; 905147476Sdumbbell}; 906147476Sdumbbell 907147476Sdumbbell/* Pointer to file name, stored in entry */ 908147476Sdumbbell#define B_I_DEH_ENTRY_FILE_NAME(bp, ih, deh) \ 909147476Sdumbbell (B_I_PITEM(bp, ih) + deh_location(deh)) 910147476Sdumbbell 911147476Sdumbbell/* Length of name */ 912147476Sdumbbell#define I_DEH_N_ENTRY_FILE_NAME_LENGTH(ih, deh, entry_num) \ 913147476Sdumbbell (I_DEH_N_ENTRY_LENGTH(ih, deh, entry_num) - \ 914147476Sdumbbell (de_with_sd(deh) ? SD_SIZE : 0)) 915147476Sdumbbell 916147476Sdumbbell/* Hash value occupies bits from 7 up to 30 */ 917147476Sdumbbell#define GET_HASH_VALUE(offset) ((offset) & 0x7fffff80LL) 918147476Sdumbbell 919147476Sdumbbell/* Generation number occupies 7 bits starting from 0 up to 6 */ 920147476Sdumbbell#define GET_GENERATION_NUMBER(offset) ((offset) & 0x7fLL) 921147476Sdumbbell#define MAX_GENERATION_NUMBER 127 922147476Sdumbbell 923147476Sdumbbell/* Get item body */ 924147476Sdumbbell#define B_I_PITEM(bp, ih) ((bp)->b_data + ih_location(ih)) 925147476Sdumbbell#define B_I_DEH(bp, ih) ((struct reiserfs_de_head *)(B_I_PITEM(bp, ih))) 926147476Sdumbbell 927147476Sdumbbell/* 928147476Sdumbbell * Length of the directory entry in directory item. This define 929147476Sdumbbell * calculates length of i-th directory entry using directory entry 930147476Sdumbbell * locations from dir entry head. When it calculates length of 0-th 931147476Sdumbbell * directory entry, it uses length of whole item in place of entry 932147476Sdumbbell * location of the non-existent following entry in the calculation. See 933147476Sdumbbell * picture above. 934147476Sdumbbell */ 935147476Sdumbbellstatic inline int 936147476Sdumbbellentry_length (const struct buf *bp, const struct item_head *ih, 937147476Sdumbbell int pos_in_item) 938147476Sdumbbell{ 939147476Sdumbbell struct reiserfs_de_head *deh; 940147476Sdumbbell 941147476Sdumbbell deh = B_I_DEH(bp, ih) + pos_in_item; 942147476Sdumbbell if (pos_in_item) 943147476Sdumbbell return (deh_location(deh - 1) - deh_location(deh)); 944147476Sdumbbell 945147476Sdumbbell return (ih_item_len(ih) - deh_location(deh)); 946147476Sdumbbell} 947147476Sdumbbell 948147476Sdumbbell/* 949147476Sdumbbell * Number of entries in the directory item, depends on ENTRY_COUNT 950147476Sdumbbell * being at the start of directory dynamic data. 951147476Sdumbbell */ 952147476Sdumbbell#define I_ENTRY_COUNT(ih) (ih_entry_count((ih))) 953147476Sdumbbell 954147476Sdumbbell/* ------------------------------------------------------------------- 955147476Sdumbbell * Disk child 956147476Sdumbbell * -------------------------------------------------------------------*/ 957147476Sdumbbell 958147476Sdumbbell/* 959147476Sdumbbell * Disk child pointer: The pointer from an internal node of the tree 960147476Sdumbbell * to a node that is on disk. 961147476Sdumbbell */ 962147476Sdumbbellstruct disk_child { 963147476Sdumbbell uint32_t dc_block_number; /* Disk child's block number. */ 964147476Sdumbbell uint16_t dc_size; /* Disk child's used space. */ 965147476Sdumbbell uint16_t dc_reserved; 966147476Sdumbbell}; 967147476Sdumbbell 968147476Sdumbbell#define DC_SIZE (sizeof(struct disk_child)) 969147476Sdumbbell#define dc_block_number(dc_p) (le32toh((dc_p)->dc_block_number)) 970147476Sdumbbell#define dc_size(dc_p) (le16toh((dc_p)->dc_size)) 971147476Sdumbbell#define put_dc_block_number(dc_p, val) \ 972147476Sdumbbell do { (dc_p)->dc_block_number = htole32(val); } while (0) 973147476Sdumbbell#define put_dc_size(dc_p, val) \ 974147476Sdumbbell do { (dc_p)->dc_size = htole16(val); } while (0) 975147476Sdumbbell 976147476Sdumbbell/* Get disk child by buffer header and position in the tree node. */ 977147476Sdumbbell#define B_N_CHILD(p_s_bp, n_pos) \ 978147476Sdumbbell ((struct disk_child *)((p_s_bp)->b_data + BLKH_SIZE + \ 979147476Sdumbbell B_NR_ITEMS(p_s_bp) * KEY_SIZE + \ 980147476Sdumbbell DC_SIZE * (n_pos))) 981147476Sdumbbell 982147476Sdumbbell/* Get disk child number by buffer header and position in the tree node. */ 983147476Sdumbbell#define B_N_CHILD_NUM(p_s_bp, n_pos) \ 984147476Sdumbbell (dc_block_number(B_N_CHILD(p_s_bp, n_pos))) 985147476Sdumbbell#define PUT_B_N_CHILD_NUM(p_s_bp, n_pos, val) \ 986147476Sdumbbell (put_dc_block_number(B_N_CHILD(p_s_bp, n_pos), val)) 987147476Sdumbbell 988147476Sdumbbell/* ------------------------------------------------------------------- 989147476Sdumbbell * Path structures and defines 990147476Sdumbbell * -------------------------------------------------------------------*/ 991147476Sdumbbell 992147476Sdumbbellstruct path_element { 993147476Sdumbbell struct buf *pe_buffer; /* Pointer to the buffer at the path in 994147476Sdumbbell the tree. */ 995147476Sdumbbell int pe_position; /* Position in the tree node which is 996147476Sdumbbell placed in the buffer above. */ 997147476Sdumbbell}; 998147476Sdumbbell 999147476Sdumbbell#define MAX_HEIGHT 5 /* Maximal height of a tree. Don't 1000147476Sdumbbell change this without changing 1001147476Sdumbbell JOURNAL_PER_BALANCE_CNT */ 1002147476Sdumbbell#define EXTENDED_MAX_HEIGHT 7 /* Must be equals MAX_HEIGHT + 1003147476Sdumbbell FIRST_PATH_ELEMENT_OFFSET */ 1004147476Sdumbbell#define FIRST_PATH_ELEMENT_OFFSET 2 /* Must be equal to at least 2. */ 1005147476Sdumbbell#define ILLEGAL_PATH_ELEMENT_OFFSET 1 /* Must be equal to 1006147476Sdumbbell FIRST_PATH_ELEMENT_OFFSET - 1 */ 1007147476Sdumbbell#define MAX_FEB_SIZE 6 /* This MUST be MAX_HEIGHT + 1. 1008147476Sdumbbell See about FEB below */ 1009147476Sdumbbell 1010147476Sdumbbellstruct path { 1011147476Sdumbbell /* Length of the array below. */ 1012147476Sdumbbell int path_length; 1013147476Sdumbbell /* Array of the path element */ 1014147476Sdumbbell struct path_element path_elements[EXTENDED_MAX_HEIGHT]; 1015147476Sdumbbell int pos_in_item; 1016147476Sdumbbell}; 1017147476Sdumbbell 1018147476Sdumbbell#define pos_in_item(path) ((path)->pos_in_item) 1019147476Sdumbbell 1020153081Sru#ifdef __amd64__ 1021153081Sru/* To workaround a bug in gcc. He generates a call to memset() which 1022153081Sru * is a inline function; this causes a compile time error. */ 1023147476Sdumbbell#define INITIALIZE_PATH(var) \ 1024153081Sru struct path var; \ 1025153081Sru bzero(&var, sizeof(var)); \ 1026153081Sru var.path_length = ILLEGAL_PATH_ELEMENT_OFFSET; 1027153081Sru#else 1028153081Sru#define INITIALIZE_PATH(var) \ 1029147476Sdumbbell struct path var = { ILLEGAL_PATH_ELEMENT_OFFSET, } 1030153081Sru#endif 1031147476Sdumbbell 1032147476Sdumbbell/* Get path element by path and path position. */ 1033147476Sdumbbell#define PATH_OFFSET_PELEMENT(p_s_path, n_offset) \ 1034147476Sdumbbell ((p_s_path)->path_elements + (n_offset)) 1035147476Sdumbbell 1036147476Sdumbbell/* Get buffer header at the path by path and path position. */ 1037147476Sdumbbell#define PATH_OFFSET_PBUFFER(p_s_path, n_offset) \ 1038147476Sdumbbell (PATH_OFFSET_PELEMENT(p_s_path, n_offset)->pe_buffer) 1039147476Sdumbbell 1040147476Sdumbbell/* Get position in the element at the path by path and path position. */ 1041147476Sdumbbell#define PATH_OFFSET_POSITION(p_s_path, n_offset) \ 1042147476Sdumbbell (PATH_OFFSET_PELEMENT(p_s_path, n_offset)->pe_position) 1043147476Sdumbbell 1044147476Sdumbbell#define PATH_PLAST_BUFFER(p_s_path) \ 1045147476Sdumbbell (PATH_OFFSET_PBUFFER((p_s_path), (p_s_path)->path_length)) 1046147476Sdumbbell 1047147476Sdumbbell#define PATH_LAST_POSITION(p_s_path) \ 1048147476Sdumbbell (PATH_OFFSET_POSITION((p_s_path), (p_s_path)->path_length)) 1049147476Sdumbbell 1050147476Sdumbbell#define PATH_PITEM_HEAD(p_s_path) \ 1051147476Sdumbbell B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_path), PATH_LAST_POSITION(p_s_path)) 1052147476Sdumbbell 1053147476Sdumbbell#define get_last_bp(path) PATH_PLAST_BUFFER(path) 1054147476Sdumbbell#define get_ih(path) PATH_PITEM_HEAD(path) 1055147476Sdumbbell 1056147476Sdumbbell/* ------------------------------------------------------------------- 1057147476Sdumbbell * Misc. 1058147476Sdumbbell * -------------------------------------------------------------------*/ 1059147476Sdumbbell 1060147476Sdumbbell/* Size of pointer to the unformatted node. */ 1061147476Sdumbbell#define UNFM_P_SIZE (sizeof(unp_t)) 1062147476Sdumbbell#define UNFM_P_SHIFT 2 1063147476Sdumbbell 1064147476Sdumbbell/* In in-core inode key is stored on le form */ 1065147476Sdumbbell#define INODE_PKEY(ip) ((struct key *)(REISERFS_I(ip)->i_key)) 1066147476Sdumbbell 1067147476Sdumbbell#define MAX_UL_INT 0xffffffff 1068147476Sdumbbell#define MAX_INT 0x7ffffff 1069147476Sdumbbell#define MAX_US_INT 0xffff 1070147476Sdumbbell 1071147476Sdumbbell/* The purpose is to detect overflow of an unsigned short */ 1072147476Sdumbbell#define REISERFS_LINK_MAX (MAX_US_INT - 1000) 1073147476Sdumbbell 1074147476Sdumbbell#define fs_generation(sbi) (REISERFS_SB(sbi)->s_generation_counter) 1075147476Sdumbbell#define get_generation(sbi) (fs_generation(sbi)) 1076147476Sdumbbell 1077147476Sdumbbell#define __fs_changed(gen, sbi) (gen != get_generation (sbi)) 1078147476Sdumbbell/*#define fs_changed(gen, sbi) ({ cond_resched(); \ 1079147476Sdumbbell __fs_changed(gen, sbi); })*/ 1080147476Sdumbbell#define fs_changed(gen, sbi) (__fs_changed(gen, sbi)) 1081147476Sdumbbell 1082147476Sdumbbell/* ------------------------------------------------------------------- 1083147476Sdumbbell * Fixate node 1084147476Sdumbbell * -------------------------------------------------------------------*/ 1085147476Sdumbbell 1086147476Sdumbbell/* 1087147476Sdumbbell * To make any changes in the tree we always first find node, that 1088147476Sdumbbell * contains item to be changed/deleted or place to insert a new item. 1089147476Sdumbbell * We call this node S. To do balancing we need to decide what we will 1090147476Sdumbbell * shift to left/right neighbor, or to a new node, where new item will 1091147476Sdumbbell * be etc. To make this analysis simpler we build virtual node. Virtual 1092147476Sdumbbell * node is an array of items, that will replace items of node S. (For 1093147476Sdumbbell * instance if we are going to delete an item, virtual node does not 1094147476Sdumbbell * contain it). Virtual node keeps information about item sizes and 1095147476Sdumbbell * types, mergeability of first and last items, sizes of all entries in 1096147476Sdumbbell * directory item. We use this array of items when calculating what we 1097147476Sdumbbell * can shift to neighbors and how many nodes we have to have if we do 1098147476Sdumbbell * not any shiftings, if we shift to left/right neighbor or to both. 1099147476Sdumbbell */ 1100147476Sdumbbellstruct virtual_item { 1101147476Sdumbbell int vi_index; /* Index in the array of item 1102147476Sdumbbell operations */ 1103147476Sdumbbell unsigned short vi_type; /* Left/right mergeability */ 1104147476Sdumbbell unsigned short vi_item_len; /* Length of item that it will 1105147476Sdumbbell have after balancing */ 1106147476Sdumbbell struct item_head *vi_ih; 1107147476Sdumbbell const char *vi_item; /* Body of item (old or new) */ 1108147476Sdumbbell const void *vi_new_data; /* 0 always but paste mode */ 1109147476Sdumbbell void *vi_uarea; /* Item specific area */ 1110147476Sdumbbell}; 1111147476Sdumbbell 1112147476Sdumbbellstruct virtual_node { 1113147476Sdumbbell char *vn_free_ptr; /* This is a pointer to the free space 1114147476Sdumbbell in the buffer */ 1115147476Sdumbbell unsigned short vn_nr_item; /* Number of items in virtual node */ 1116147476Sdumbbell short vn_size; /* Size of node , that node would have 1117147476Sdumbbell if it has unlimited size and no 1118147476Sdumbbell balancing is performed */ 1119147476Sdumbbell short vn_mode; /* Mode of balancing (paste, insert, 1120147476Sdumbbell delete, cut) */ 1121147476Sdumbbell short vn_affected_item_num; 1122147476Sdumbbell short vn_pos_in_item; 1123147476Sdumbbell struct item_head *vn_ins_ih; /* Item header of inserted item, 0 for 1124147476Sdumbbell other modes */ 1125147476Sdumbbell const void *vn_data; 1126147476Sdumbbell struct virtual_item *vn_vi; /* Array of items (including a new one, 1127147476Sdumbbell excluding item to be deleted) */ 1128147476Sdumbbell}; 1129147476Sdumbbell 1130147476Sdumbbell/* Used by directory items when creating virtual nodes */ 1131147476Sdumbbellstruct direntry_uarea { 1132147476Sdumbbell int flags; 1133147476Sdumbbell uint16_t entry_count; 1134147476Sdumbbell uint16_t entry_sizes[1]; 1135147476Sdumbbell} __packed; 1136147476Sdumbbell 1137147476Sdumbbell/* ------------------------------------------------------------------- 1138147476Sdumbbell * Tree balance 1139147476Sdumbbell * -------------------------------------------------------------------*/ 1140147476Sdumbbell 1141147476Sdumbbellstruct reiserfs_iget_args { 1142147476Sdumbbell uint32_t objectid; 1143147476Sdumbbell uint32_t dirid; 1144147476Sdumbbell}; 1145147476Sdumbbell 1146147476Sdumbbellstruct item_operations { 1147147476Sdumbbell int (*bytes_number)(struct item_head * ih, int block_size); 1148147476Sdumbbell void (*decrement_key)(struct cpu_key *); 1149147476Sdumbbell int (*is_left_mergeable)(struct key * ih, unsigned long bsize); 1150147476Sdumbbell void (*print_item)(struct item_head *, char * item); 1151147476Sdumbbell void (*check_item)(struct item_head *, char * item); 1152147476Sdumbbell 1153147476Sdumbbell int (*create_vi)(struct virtual_node * vn, 1154147476Sdumbbell struct virtual_item * vi, int is_affected, int insert_size); 1155147476Sdumbbell int (*check_left)(struct virtual_item * vi, int free, 1156147476Sdumbbell int start_skip, int end_skip); 1157147476Sdumbbell int (*check_right)(struct virtual_item * vi, int free); 1158147476Sdumbbell int (*part_size)(struct virtual_item * vi, int from, int to); 1159147476Sdumbbell int (*unit_num)(struct virtual_item * vi); 1160147476Sdumbbell void (*print_vi)(struct virtual_item * vi); 1161147476Sdumbbell}; 1162147476Sdumbbell 1163147476Sdumbbellextern struct item_operations *item_ops[TYPE_ANY + 1]; 1164147476Sdumbbell 1165147476Sdumbbell#define op_bytes_number(ih, bsize) \ 1166147476Sdumbbell item_ops[le_ih_k_type(ih)]->bytes_number(ih, bsize) 1167147476Sdumbbell 1168147476Sdumbbell#define COMP_KEYS comp_keys 1169147476Sdumbbell#define COMP_SHORT_KEYS comp_short_keys 1170147476Sdumbbell 1171147476Sdumbbell/* Get the item header */ 1172147476Sdumbbell#define B_N_PITEM_HEAD(bp, item_num) \ 1173147476Sdumbbell ((struct item_head *)((bp)->b_data + BLKH_SIZE) + (item_num)) 1174147476Sdumbbell 1175147476Sdumbbell/* Get key */ 1176147476Sdumbbell#define B_N_PDELIM_KEY(bp, item_num) \ 1177147476Sdumbbell ((struct key *)((bp)->b_data + BLKH_SIZE) + (item_num)) 1178147476Sdumbbell 1179147476Sdumbbell/* ------------------------------------------------------------------- 1180147476Sdumbbell * Function declarations 1181147476Sdumbbell * -------------------------------------------------------------------*/ 1182147476Sdumbbell 1183147476Sdumbbell/* reiserfs_stree.c */ 1184147476Sdumbbellint B_IS_IN_TREE(const struct buf *p_s_bp); 1185147476Sdumbbell 1186147476Sdumbbellextern void copy_item_head(struct item_head * p_v_to, 1187147476Sdumbbell const struct item_head * p_v_from); 1188147476Sdumbbell 1189147476Sdumbbellextern int comp_keys(const struct key *le_key, 1190147476Sdumbbell const struct cpu_key *cpu_key); 1191147476Sdumbbellextern int comp_short_keys(const struct key *le_key, 1192147476Sdumbbell const struct cpu_key *cpu_key); 1193147476Sdumbbell 1194147476Sdumbbellextern int comp_le_keys(const struct key *, const struct key *); 1195147476Sdumbbell 1196147476Sdumbbellstatic inline int 1197147476Sdumbbellle_key_version(const struct key *key) 1198147476Sdumbbell{ 1199147476Sdumbbell int type; 1200147476Sdumbbell 1201147476Sdumbbell type = offset_v2_k_type(&(key->u.k_offset_v2)); 1202147476Sdumbbell if (type != TYPE_DIRECT && type != TYPE_INDIRECT && 1203147476Sdumbbell type != TYPE_DIRENTRY) 1204147476Sdumbbell return (KEY_FORMAT_3_5); 1205147476Sdumbbell 1206147476Sdumbbell return (KEY_FORMAT_3_6); 1207147476Sdumbbell} 1208147476Sdumbbell 1209147476Sdumbbellstatic inline void 1210147476Sdumbbellcopy_key(struct key *to, const struct key *from) 1211147476Sdumbbell{ 1212147476Sdumbbell 1213147476Sdumbbell memcpy(to, from, KEY_SIZE); 1214147476Sdumbbell} 1215147476Sdumbbell 1216147476Sdumbbellconst struct key *get_lkey(const struct path *p_s_chk_path, 1217147476Sdumbbell const struct reiserfs_sb_info *p_s_sbi); 1218147476Sdumbbellconst struct key *get_rkey(const struct path *p_s_chk_path, 1219147476Sdumbbell const struct reiserfs_sb_info *p_s_sbi); 1220189525Sdasint bin_search(const void * p_v_key, const void * p_v_base, 1221147476Sdumbbell int p_n_num, int p_n_width, int * p_n_pos); 1222147476Sdumbbell 1223147476Sdumbbellvoid pathrelse(struct path *p_s_search_path); 1224147476Sdumbbellint reiserfs_check_path(struct path *p); 1225147476Sdumbbell 1226147476Sdumbbellint search_by_key(struct reiserfs_sb_info *p_s_sbi, 1227147476Sdumbbell const struct cpu_key *p_s_key, 1228147476Sdumbbell struct path *p_s_search_path, 1229147476Sdumbbell int n_stop_level); 1230147476Sdumbbell#define search_item(sbi, key, path) \ 1231147476Sdumbbell search_by_key(sbi, key, path, DISK_LEAF_NODE_LEVEL) 1232147476Sdumbbellint search_for_position_by_key(struct reiserfs_sb_info *p_s_sbi, 1233147476Sdumbbell const struct cpu_key *p_s_cpu_key, 1234147476Sdumbbell struct path *p_s_search_path); 1235147476Sdumbbellvoid decrement_counters_in_path(struct path *p_s_search_path); 1236147476Sdumbbell 1237147476Sdumbbell/* reiserfs_inode.c */ 1238147476Sdumbbellvop_read_t reiserfs_read; 1239147476Sdumbbellvop_inactive_t reiserfs_inactive; 1240147476Sdumbbellvop_reclaim_t reiserfs_reclaim; 1241147476Sdumbbell 1242147476Sdumbbellint reiserfs_get_block(struct reiserfs_node *ip, long block, 1243147476Sdumbbell off_t offset, struct uio *uio); 1244147476Sdumbbell 1245147476Sdumbbellvoid make_cpu_key(struct cpu_key *cpu_key, struct reiserfs_node *ip, 1246147476Sdumbbell off_t offset, int type, int key_length); 1247147476Sdumbbell 1248147476Sdumbbellvoid reiserfs_read_locked_inode(struct reiserfs_node *ip, 1249147476Sdumbbell struct reiserfs_iget_args *args); 1250147476Sdumbbellint reiserfs_iget(struct mount *mp, const struct cpu_key *key, 1251147476Sdumbbell struct vnode **vpp, struct thread *td); 1252147476Sdumbbell 1253147476Sdumbbellvoid sd_attrs_to_i_attrs(uint16_t sd_attrs, struct reiserfs_node *ip); 1254147476Sdumbbellvoid i_attrs_to_sd_attrs(struct reiserfs_node *ip, uint16_t *sd_attrs); 1255147476Sdumbbell 1256147476Sdumbbell/* reiserfs_namei.c */ 1257147476Sdumbbellvop_readdir_t reiserfs_readdir; 1258147476Sdumbbellvop_cachedlookup_t reiserfs_lookup; 1259147476Sdumbbell 1260147476Sdumbbellvoid set_de_name_and_namelen(struct reiserfs_dir_entry * de); 1261147476Sdumbbellint search_by_entry_key(struct reiserfs_sb_info *sbi, 1262147476Sdumbbell const struct cpu_key *key, struct path *path, 1263147476Sdumbbell struct reiserfs_dir_entry *de); 1264147476Sdumbbell 1265147476Sdumbbell/* reiserfs_prints.c */ 1266147476Sdumbbellchar *reiserfs_hashname(int code); 1267147476Sdumbbellvoid reiserfs_dump_buffer(caddr_t buf, off_t len); 1268147476Sdumbbell 1269147476Sdumbbell#if defined(REISERFS_DEBUG) 1270147476Sdumbbell#define reiserfs_log(lvl, fmt, ...) \ 1271147476Sdumbbell log(lvl, "ReiserFS/%s: " fmt, __func__, ## __VA_ARGS__) 1272147476Sdumbbell#elif defined (REISERFS_DEBUG_CONS) 1273147476Sdumbbell#define reiserfs_log(lvl, fmt, ...) \ 1274147476Sdumbbell printf("%s:%d: " fmt, __func__, __LINE__, ## __VA_ARGS__) 1275147476Sdumbbell#else 1276147476Sdumbbell#define reiserfs_log(lvl, fmt, ...) 1277147476Sdumbbell#endif 1278147476Sdumbbell 1279147476Sdumbbell#define reiserfs_log_0(lvl, fmt, ...) \ 1280147476Sdumbbell printf("%s:%d: " fmt, __func__, __LINE__, ## __VA_ARGS__) 1281147476Sdumbbell 1282147476Sdumbbell/* reiserfs_hashes.c */ 1283147476Sdumbbelluint32_t keyed_hash(const signed char *msg, int len); 1284147476Sdumbbelluint32_t yura_hash(const signed char *msg, int len); 1285147476Sdumbbelluint32_t r5_hash(const signed char *msg, int len); 1286147476Sdumbbell 1287147476Sdumbbell#define reiserfs_test_le_bit test_bit 1288147476Sdumbbell 1289147476Sdumbbell#endif /* !defined _GNU_REISERFS_REISERFS_FS_H */ 1290