2e27a27e3ab47866fc0f4d850e883c79057913b9
[yaboot.git] / include / reiserfs / reiserfs.h
1 #ifndef _REISERFS_H_
2 #define _REISERFS_H_
3 #include "byteorder.h"
4 #include "types.h"
5
6 /* ReiserFS Super Block */
7 /* include/linux/reiserfs_fs_sb.h */
8 #define REISERFS_MAX_SUPPORTED_VERSION  2
9 #define REISERFS_SUPER_MAGIC_STRING     "ReIsErFs"
10 #define REISER2FS_SUPER_MAGIC_STRING    "ReIsEr2Fs"
11 #define REISERFS_MAX_TREE_HEIGHT        7
12
13 struct reiserfs_super_block
14 {
15     __u32 s_block_count;
16     __u32 s_free_blocks;            /* free blocks count */
17     __u32 s_root_block;             /* root block number */
18     __u32 s_journal_block;          /* journal block number */
19     __u32 s_journal_dev;            /* journal device number */
20     __u32 s_orig_journal_size;      /* size of the journal */
21     __u32 s_journal_trans_max;      /* max number of blocks in
22                                        a transaction.  */
23     __u32 s_journal_block_count;    /* total size of the journal.
24                                        can change over time  */
25     __u32 s_journal_max_batch;      /* max number of blocks to
26                                        batch into a trans */
27     __u32 s_journal_max_commit_age; /* in seconds, how old can an
28                                        async commit be */
29     __u32 s_journal_max_trans_age;  /* in seconds, how old can a
30                                        transaction be */
31     __u16 s_blocksize;              /* block size */
32     __u16 s_oid_maxsize;            /* max size of object id array, */
33     __u16 s_oid_cursize;            /* current size of obj id array */
34     __u16 s_state;                  /* valid or error */
35     char s_magic[12];               /* reiserfs magic string indicates
36                                        that file system is reiserfs */
37     __u32 s_hash_function_code;     /* indicate, what hash function is
38                                        being use to sort names in a
39                                        directory */
40     __u16 s_tree_height;            /* height of disk tree */
41     __u16 s_bmap_nr;                /* amount of bitmap blocks needed
42                                        to address each block of file
43                                        system */
44     __u16 s_version;
45     __u16 s_marked_in_use;
46     __u16 s_inode_generation;
47     char s_unused[124];             /* zero filled by mkreiserfs */
48     char padding_to_quad[ 2 ];      /* aligned to __u32 */
49 } __attribute__ ((__packed__));
50 #define SB_SIZE         (sizeof (struct reiserfs_super_block) )
51
52 /* ReiserFS Journal */
53 /* include/linux/reiserfs_fs.h */
54 /* must be correct to keep the desc and commit structs at 4k */
55 #define JOURNAL_TRANS_HALF 1018
56
57 /* first block written in a commit */
58 struct reiserfs_journal_desc {
59     __u32 j_trans_id;                      /* id of commit */
60     __u32 j_len;                           /* length of commit. len +1 is the
61                                             commit block */
62     __u32 j_mount_id;                      /* mount id of this trans*/
63     __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for each block */
64   char j_magic[12];
65 };
66
67 /* last block written in a commit */
68 struct reiserfs_journal_commit {
69     __u32 j_trans_id;                      /* must match j_trans_id from the
70                                               desc block */
71     __u32 j_len;                           /* ditto */
72     __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for each block */
73     char j_digest[16];                     /* md5 sum of all the blocks
74                                               involved, including desc and
75                                               commit. not used, kill it */
76 };
77
78 /*
79 ** This header block gets written whenever a transaction is considered
80 ** fully flushed, and is more recent than the last fully flushed
81 ** transaction.  fully flushed means all the log blocks and all the real
82 ** blocks are on disk, and this transaction does not need to be replayed.
83 */
84 struct reiserfs_journal_header {
85     __u32 j_last_flush_trans_id;    /* id of last fully flushed transaction */
86     __u32 j_first_unflushed_offset; /* offset in the log of where to start
87                                        replay after a crash */
88     __u32 j_mount_id;
89 };
90
91 /* Magic to find journal descriptors */
92 #define JOURNAL_DESC_MAGIC "ReIsErLB"
93
94 /* ReiserFS Tree structures/accessors */
95 /* Item version determines which offset_v# struct to use */
96 #define ITEM_VERSION_1 0
97 #define ITEM_VERSION_2 1
98 #define IH_KEY_OFFSET(ih) (INFO->version < 2 \
99                            || ih_version(ih) == ITEM_VERSION_1 \
100                            ? (ih)->ih_key.u.k_offset_v1.k_offset \
101                            : offset_v2_k_offset(&(ih)->ih_key.u.k_offset_v2))
102  
103 #define IH_KEY_ISTYPE(ih, type) (INFO->version < 2 \
104                 || ih_version(ih) == ITEM_VERSION_1 \
105                 ? (ih)->ih_key.u.k_offset_v1.k_uniqueness == V1_##type \
106                 : offset_v2_k_type(&(ih)->ih_key.u.k_offset_v2) == V2_##type)
107
108 //
109 // directories use this key as well as old files
110 //
111 struct offset_v1 {
112     __u32 k_offset;
113     __u32 k_uniqueness;
114 } __attribute__ ((__packed__));
115
116 struct offset_v2 {
117 #ifdef __LITTLE_ENDIAN
118     /* little endian version */
119     __u64 k_offset:60;
120     __u64 k_type: 4;
121 #else
122     /* big endian version */
123     __u64 k_type: 4;
124     __u64 k_offset:60;
125 #endif
126 } __attribute__ ((__packed__));
127
128 #ifndef __LITTLE_ENDIAN
129 inline __u16 offset_v2_k_type( struct offset_v2 *v2 );
130 inline loff_t offset_v2_k_offset( struct offset_v2 *v2 );
131 #else
132 # define offset_v2_k_type(v2)           ((v2)->k_type)
133 # define offset_v2_k_offset(v2)         ((v2)->k_offset)
134 #endif
135
136 /* Key of an item determines its location in the S+tree, and
137    is composed of 4 components */
138 struct key {
139     __u32 k_dir_id;    /* packing locality: by default parent
140                           directory object id */
141     __u32 k_objectid;  /* object identifier */
142     union {
143         struct offset_v1 k_offset_v1;
144         struct offset_v2 k_offset_v2;
145     } __attribute__ ((__packed__)) u;
146 } __attribute__ ((__packed__));
147 #define KEY_SIZE        (sizeof (struct key))
148
149 //
150 // there are 5 item types currently
151 //
152 #define TYPE_STAT_DATA 0
153 #define TYPE_INDIRECT 1
154 #define TYPE_DIRECT 2
155 #define TYPE_DIRENTRY 3
156 #define TYPE_ANY 15 // FIXME: comment is required
157  
158 //
159 // in old version uniqueness field shows key type
160 //
161 #define V1_SD_UNIQUENESS 0
162 #define V1_INDIRECT_UNIQUENESS 0xfffffffe
163 #define V1_DIRECT_UNIQUENESS 0xffffffff
164 #define V1_DIRENTRY_UNIQUENESS 500
165 #define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
166 inline int uniqueness2type (__u32 uniqueness);
167
168 struct item_head
169 {
170   struct key ih_key;                  /* Everything in the tree is found by
171                                          searching for its key.*/
172
173   union {
174     __u16 ih_free_space_reserved;     /* The free space in the last unformatted
175                                          node of an indirect item if this is an
176                                          indirect item.  This equals 0xFFFF
177                                          iff this is a direct item or stat
178                                          data item. Note that the key, not
179                                          this field, is used to determine
180                                          the item type, and thus which field
181                                          this union contains. */
182     __u16 ih_entry_count;             /* Iff this is a directory item, this
183                                          field equals the number of directory
184                                          entries in the directory item. */
185   } __attribute__ ((__packed__)) u;
186   __u16 ih_item_len;                  /* total size of the item body */
187   __u16 ih_item_location;             /* Offset to the item within the block */
188   __u16 ih_version;                   /* ITEM_VERSION_[01] of key type */
189 } __attribute__ ((__packed__));
190 #define IH_SIZE (sizeof(struct item_head))
191
192 #define ih_version(ih)               le16_to_cpu((ih)->ih_version)
193 #define ih_entry_count(ih)           le16_to_cpu((ih)->u.ih_entry_count)
194 #define ih_location(ih)              le16_to_cpu((ih)->ih_item_location)
195 #define ih_item_len(ih)              le16_to_cpu((ih)->ih_item_len)
196
197 /* Header of a disk block.  More precisely, header of a formatted leaf
198    or internal node, and not the header of an unformatted node. */
199 struct block_head {       
200     __u16 blk_level;                  /* Level of a block in the tree */
201     __u16 blk_nr_item;                /* Number of keys/items in a block */
202     __u16 blk_free_space;             /* Block free space in bytes */
203     __u16 blk_reserved;
204     struct key blk_right_delim_key;   /* kept only for compatibility */
205 };
206 #define BLKH_SIZE                     (sizeof(struct block_head))
207
208 #define blkh_level(p_blkh)            (le16_to_cpu((p_blkh)->blk_level))
209 #define blkh_nr_item(p_blkh)          (le16_to_cpu((p_blkh)->blk_nr_item))
210
211 #define BLKH_LEVEL_FREE 0 /* Freed from the tree */
212 #define BLKH_LEVEL_LEAF 1 /* Leaf node level*/
213
214 struct disk_child {
215     __u32       dc_block_number;   /* Disk child's block number */
216     __u16       dc_size;           /* Disk child's used space */
217     __u16       dc_reserved;
218 };
219
220 #define DC_SIZE (sizeof(struct disk_child))
221 #define dc_block_number(dc_p)   (le32_to_cpu((dc_p)->dc_block_number))
222 #define dc_size(dc_p)           (le16_to_cpu((dc_p)->dc_size))
223
224 /* Stat data */
225 struct stat_data_v1
226 {
227     __u16 sd_mode;              /* file type, permissions */
228     __u16 sd_nlink;             /* number of hard links */
229     __u16 sd_uid;               /* owner */
230     __u16 sd_gid;               /* group */
231     __u32 sd_size;              /* file size */
232     __u32 sd_atime;             /* time of last access */
233     __u32 sd_mtime;             /* time file was last modified  */
234     __u32 sd_ctime;             /* time inode (stat data) was last changed
235                                    (except changes to sd_atime and sd_mtime) */
236     union {
237         __u32 sd_rdev;
238         __u32 sd_blocks;        /* number of blocks file uses */
239     } __attribute__ ((__packed__)) u;
240     __u32 sd_first_direct_byte; /* 0 = no direct item, 1 = symlink */
241 } __attribute__ ((__packed__));
242 #define SD_V1_SIZE              (sizeof(struct stat_data_v1))
243
244 #define stat_data_v1(ih)        (ih_version (ih) == ITEM_VERSION_1)
245 #define sd_v1_size(sdp)         (le32_to_cpu((sdp)->sd_size))
246
247 /* Stat Data on disk (reiserfs version of UFS disk inode minus the
248    address blocks) */
249 struct stat_data {
250     __u16 sd_mode;     /* file type, permissions */
251     __u16 sd_reserved;
252     __u32 sd_nlink;    /* number of hard links */
253     __u64 sd_size;     /* file size */
254     __u32 sd_uid;      /* owner */
255     __u32 sd_gid;      /* group */
256     __u32 sd_atime;    /* time of last access */
257     __u32 sd_mtime;    /* time file was last modified  */
258     __u32 sd_ctime;    /* time inode (stat data) was last changed
259                           (except changes to sd_atime and sd_mtime) */
260     __u32 sd_blocks;
261     __u32 sd_rdev;
262 } __attribute__ ((__packed__));
263 #define SD_V2_SIZE              (sizeof(struct stat_data))
264 #define stat_data_v2(ih)        (ih_version (ih) == ITEM_VERSION_2)
265 #define sd_v2_size(sdp)         (le64_to_cpu((sdp)->sd_size))
266
267 /* valid for any stat data */
268 #define sd_size(ih,sdp)         ((ih_version(ih) == ITEM_VERSION_2) ? \
269                                   sd_v2_size((struct stat_data *)sdp) : \
270                                   sd_v1_size((struct stat_data_v1 *)sdp))
271 #define sd_mode(sdp)            (le16_to_cpu((sdp)->sd_mode))
272
273 struct reiserfs_de_head
274 {
275     __u32 deh_offset;    /* third component of the directory entry key */
276     __u32 deh_dir_id;    /* objectid of the parent directory of the object,
277                             that is referenced by directory entry */
278     __u32 deh_objectid;  /* objectid of the object, that is referenced by
279                             directory entry */
280     __u16 deh_location;  /* offset of name in the whole item */
281     __u16 deh_state;     /* whether 1) entry contains stat data (for future),                               and 2) whether entry is hidden (unlinked) */
282 } __attribute__ ((__packed__));
283 #define DEH_SIZE                  sizeof(struct reiserfs_de_head)
284
285 #define deh_offset(p_deh)         (le32_to_cpu((p_deh)->deh_offset))
286 #define deh_dir_id(p_deh)         (le32_to_cpu((p_deh)->deh_dir_id))
287 #define deh_objectid(p_deh)       (le32_to_cpu((p_deh)->deh_objectid))
288 #define deh_location(p_deh)       (le16_to_cpu((p_deh)->deh_location))
289 #define deh_state(p_deh)          (le16_to_cpu((p_deh)->deh_state))
290
291 /* empty directory contains two entries "." and ".." and their headers */
292 #define EMPTY_DIR_SIZE \
293 (DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen ("..")))
294
295 /* old format directories have this size when empty */
296 #define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)
297
298 #define DEH_Statdata 0                  /* not used now */
299 #define DEH_Visible 2
300
301 /* 64 bit systems need to aligned explicitly -jdm */
302 #if BITS_PER_LONG == 64
303 # define ADDR_UNALIGNED_BITS  (5)
304 #endif
305
306 #define test_bit(x,y) ext2fs_test_bit(x,y)
307
308 #ifdef ADDR_UNALIGNED_BITS
309 # define aligned_address(addr)           ((void *)((long)(addr) & ~((1UL << ADDR_UNALIGNED_BITS) - 1)))
310 # define unaligned_offset(addr)          (((int)((long)(addr) & ((1 << ADDR_UNALIGNED_BITS) - 1))) << 3)
311 # define set_bit_unaligned(nr, addr)     set_bit((nr) + unaligned_offset(addr), aligned_address(addr))
312 # define clear_bit_unaligned(nr, addr)   clear_bit((nr) + unaligned_offset(addr), aligned_address(addr))
313 # define test_bit_unaligned(nr, addr)    test_bit((nr) + unaligned_offset(addr), aligned_address(addr))
314 #else
315 # define set_bit_unaligned(nr, addr)     set_bit(nr, addr)
316 # define clear_bit_unaligned(nr, addr)   clear_bit(nr, addr)
317 # define test_bit_unaligned(nr, addr)    test_bit(nr, addr)
318 #endif
319
320 #define SD_OFFSET  0
321 #define SD_UNIQUENESS 0
322 #define DOT_OFFSET 1
323 #define DOT_DOT_OFFSET 2
324 #define DIRENTRY_UNIQUENESS 500
325  
326 #define V1_TYPE_STAT_DATA 0x0
327 #define V1_TYPE_DIRECT 0xffffffff
328 #define V1_TYPE_INDIRECT 0xfffffffe
329 #define V1_TYPE_DIRECTORY_MAX 0xfffffffd
330 #define V2_TYPE_STAT_DATA 0
331 #define V2_TYPE_INDIRECT 1
332 #define V2_TYPE_DIRECT 2
333 #define V2_TYPE_DIRENTRY 3
334
335  
336 #define REISERFS_ROOT_OBJECTID 2
337 #define REISERFS_ROOT_PARENT_OBJECTID 1
338 #define REISERFS_SUPERBLOCK_BLOCK 16
339 /* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
340 #define REISERFS_OLD_SUPERBLOCK_BLOCK 2
341 #define REISERFS_OLD_BLOCKSIZE 4096
342  
343 #define S_ISREG(mode) (((mode) & 0170000) == 0100000)
344 #define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
345 #define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
346 #define PATH_MAX       1024     /* include/linux/limits.h */
347 #define MAX_LINK_COUNT    5     /* number of symbolic links to follow */
348
349 /* Cache stuff, adapted from GRUB source */
350 #define FSYSREISER_CACHE_SIZE        (REISERFS_MAX_TREE_HEIGHT*REISERFS_OLD_BLOCKSIZE)
351 #define SECTOR_SIZE                  512
352 #define FSYSREISER_MIN_BLOCKSIZE     SECTOR_SIZE
353 #define FSYSREISER_MAX_BLOCKSIZE     FSYSREISER_CACHE_SIZE / 3
354
355
356 struct reiserfs_state
357 {
358     /* Context */
359     struct key fileinfo;
360     struct boot_file_t *file;
361     struct item_head *current_ih;
362     char *current_item;
363     __u64 partition_offset;
364
365     /* Commonly used values, cpu order */
366     __u32 journal_block;       /* Start of journal */
367     __u32 journal_block_count; /* The size of the journal */
368     __u32 journal_first_desc;  /* The first valid descriptor block in journal
369                                  (relative to journal_block) */
370     
371    __u16 version;              /* The ReiserFS version. */
372    __u16 tree_depth;           /* The current depth of the reiser tree. */
373    __u8  blocksize_shift;      /* 1 << blocksize_shift == blocksize. */
374    __u16 blocksize;            /* The reiserfs block size (power of 2) */
375
376     /* Cache */
377     __u16 cached_slots;
378     __u16 journal_transactions;
379     __u32 blocks[REISERFS_MAX_TREE_HEIGHT];
380     __u32 next_key_nr[REISERFS_MAX_TREE_HEIGHT];
381 };
382
383 #define ROOT     ((char *)FSYS_BUF)
384 #define CACHE(i) (ROOT + ((i) * INFO->blocksize))
385 #define LEAF     CACHE (BLKH_LEVEL_LEAF)
386
387 #define BLOCKHEAD(cache) ((struct block_head *) cache)
388 #define ITEMHEAD         ((struct item_head *) ((int) LEAF + BLKH_SIZE))
389 #define KEY(cache)       ((struct key *) ((int) cache + BLKH_SIZE))
390 #define DC(cache)        ((struct disk_child *) \
391                                 ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
392
393 /*
394  * The journal cache.  For each transaction it contains the number of
395  * blocks followed by the real block numbers of this transaction.
396  *
397  * If the block numbers of some transaction won't fit in this space,
398  * this list is stopped with a 0xffffffff marker and the remaining
399  * uncommitted transactions aren't cached.
400  */
401 #define JOURNAL_START    ((__u32 *) (FSYS_BUF + FSYSREISER_CACHE_SIZE))
402 #define JOURNAL_END      ((__u32 *) (FSYS_BUF + sizeof(FSYS_BUF)))
403
404
405 #endif /* _REISERFS_H_ */