xref: /rk3399_rockchip-uboot/fs/reiserfs/reiserfs_private.h (revision 326ea986ac150acdc7656d57fca647db80b50158)
1518e2e1aSwdenk /*
2518e2e1aSwdenk  *  Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
3518e2e1aSwdenk  *
4518e2e1aSwdenk  *  GRUB  --  GRand Unified Bootloader
5518e2e1aSwdenk  *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
6518e2e1aSwdenk  *
7518e2e1aSwdenk  *  (C) Copyright 2003 - 2004
8518e2e1aSwdenk  *  Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
9518e2e1aSwdenk  *
10518e2e1aSwdenk  *
11*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
12518e2e1aSwdenk  */
13518e2e1aSwdenk 
14518e2e1aSwdenk /* An implementation for the ReiserFS filesystem ported from GRUB.
15518e2e1aSwdenk  * Some parts of this code (mainly the structures and defines) are
16518e2e1aSwdenk  * from the original reiser fs code, as found in the linux kernel.
17518e2e1aSwdenk  */
18518e2e1aSwdenk 
19518e2e1aSwdenk #ifndef __BYTE_ORDER
20518e2e1aSwdenk #if defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
21518e2e1aSwdenk #define __BYTE_ORDER __LITTLE_ENDIAN
22518e2e1aSwdenk #elif defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
23518e2e1aSwdenk #define __BYTE_ORDER __BIG_ENDIAN
24518e2e1aSwdenk #else
25518e2e1aSwdenk #error "unable to define __BYTE_ORDER"
26518e2e1aSwdenk #endif
27518e2e1aSwdenk #endif /* not __BYTE_ORDER */
28518e2e1aSwdenk 
29518e2e1aSwdenk #define FSYS_BUFLEN  0x8000
30518e2e1aSwdenk #define FSYS_BUF     fsys_buf
31518e2e1aSwdenk 
32518e2e1aSwdenk /* This is the new super block of a journaling reiserfs system */
33518e2e1aSwdenk struct reiserfs_super_block
34518e2e1aSwdenk {
35518e2e1aSwdenk   __u32 s_block_count;			/* blocks count		*/
36518e2e1aSwdenk   __u32 s_free_blocks;			/* free blocks count	*/
37518e2e1aSwdenk   __u32 s_root_block;			/* root block number	*/
38518e2e1aSwdenk   __u32 s_journal_block;		/* journal block number    */
39518e2e1aSwdenk   __u32 s_journal_dev;			/* journal device number  */
40518e2e1aSwdenk   __u32 s_journal_size;			/* size of the journal on FS creation.	used to make sure they don't overflow it */
41518e2e1aSwdenk   __u32 s_journal_trans_max;		/* max number of blocks in a transaction.  */
42518e2e1aSwdenk   __u32 s_journal_magic;		/* random value made on fs creation */
43518e2e1aSwdenk   __u32 s_journal_max_batch;		/* max number of blocks to batch into a trans */
44518e2e1aSwdenk   __u32 s_journal_max_commit_age;	/* in seconds, how old can an async commit be */
45518e2e1aSwdenk   __u32 s_journal_max_trans_age;	/* in seconds, how old can a transaction be */
46518e2e1aSwdenk   __u16 s_blocksize;			/* block size		*/
47518e2e1aSwdenk   __u16 s_oid_maxsize;			/* max size of object id array	*/
48518e2e1aSwdenk   __u16 s_oid_cursize;			/* current size of object id array */
49518e2e1aSwdenk   __u16 s_state;			/* valid or error	*/
50518e2e1aSwdenk   char s_magic[16];			/* reiserfs magic string indicates that file system is reiserfs */
51518e2e1aSwdenk   __u16 s_tree_height;			/* height of disk tree */
52518e2e1aSwdenk   __u16 s_bmap_nr;			/* amount of bitmap blocks needed to address each block of file system */
53518e2e1aSwdenk   __u16 s_version;
54518e2e1aSwdenk   char s_unused[128];			/* zero filled by mkreiserfs */
55518e2e1aSwdenk };
56518e2e1aSwdenk 
57518e2e1aSwdenk 
58518e2e1aSwdenk #define sb_root_block(sbp)	      (__le32_to_cpu((sbp)->s_root_block))
59518e2e1aSwdenk #define sb_journal_block(sbp)	      (__le32_to_cpu((sbp)->s_journal_block))
60518e2e1aSwdenk #define set_sb_journal_block(sbp,v)   ((sbp)->s_journal_block = __cpu_to_le32(v))
61518e2e1aSwdenk #define sb_journal_size(sbp)	      (__le32_to_cpu((sbp)->s_journal_size))
62518e2e1aSwdenk #define sb_blocksize(sbp)	      (__le16_to_cpu((sbp)->s_blocksize))
63518e2e1aSwdenk #define set_sb_blocksize(sbp,v)       ((sbp)->s_blocksize = __cpu_to_le16(v))
64518e2e1aSwdenk #define sb_version(sbp)		      (__le16_to_cpu((sbp)->s_version))
65518e2e1aSwdenk #define set_sb_version(sbp,v)	      ((sbp)->s_version = __cpu_to_le16(v))
66518e2e1aSwdenk 
67518e2e1aSwdenk 
68518e2e1aSwdenk #define REISERFS_MAX_SUPPORTED_VERSION 2
69518e2e1aSwdenk #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
70518e2e1aSwdenk #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
71518e2e1aSwdenk #define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs"
72518e2e1aSwdenk 
73518e2e1aSwdenk #define MAX_HEIGHT 7
74518e2e1aSwdenk 
75518e2e1aSwdenk /* must be correct to keep the desc and commit structs at 4k */
76518e2e1aSwdenk #define JOURNAL_TRANS_HALF 1018
77518e2e1aSwdenk 
78518e2e1aSwdenk /* first block written in a commit.  */
79518e2e1aSwdenk struct reiserfs_journal_desc {
80518e2e1aSwdenk   __u32 j_trans_id;			/* id of commit */
81518e2e1aSwdenk   __u32 j_len;				/* length of commit. len +1 is the commit block */
82518e2e1aSwdenk   __u32 j_mount_id;			/* mount id of this trans*/
83518e2e1aSwdenk   __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */
84518e2e1aSwdenk   char j_magic[12];
85518e2e1aSwdenk };
86518e2e1aSwdenk 
87518e2e1aSwdenk /* last block written in a commit */
88518e2e1aSwdenk struct reiserfs_journal_commit {
89518e2e1aSwdenk   __u32 j_trans_id;			/* must match j_trans_id from the desc block */
90518e2e1aSwdenk   __u32 j_len;			/* ditto */
91518e2e1aSwdenk   __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */
92518e2e1aSwdenk   char j_digest[16];			/* md5 sum of all the blocks involved, including desc and commit. not used, kill it */
93518e2e1aSwdenk };
94518e2e1aSwdenk 
95518e2e1aSwdenk /* this header block gets written whenever a transaction is considered
96518e2e1aSwdenk    fully flushed, and is more recent than the last fully flushed
97518e2e1aSwdenk    transaction.
98518e2e1aSwdenk    fully flushed means all the log blocks and all the real blocks are
99518e2e1aSwdenk    on disk, and this transaction does not need to be replayed.
100518e2e1aSwdenk */
101518e2e1aSwdenk struct reiserfs_journal_header {
102518e2e1aSwdenk   /* id of last fully flushed transaction */
103518e2e1aSwdenk   __u32 j_last_flush_trans_id;
104518e2e1aSwdenk   /* offset in the log of where to start replay after a crash */
105518e2e1aSwdenk   __u32 j_first_unflushed_offset;
106518e2e1aSwdenk   /* mount id to detect very old transactions */
107518e2e1aSwdenk   __u32 j_mount_id;
108518e2e1aSwdenk };
109518e2e1aSwdenk 
110518e2e1aSwdenk /* magic string to find desc blocks in the journal */
111518e2e1aSwdenk #define JOURNAL_DESC_MAGIC "ReIsErLB"
112518e2e1aSwdenk 
113518e2e1aSwdenk 
114518e2e1aSwdenk /*
115518e2e1aSwdenk  * directories use this key as well as old files
116518e2e1aSwdenk  */
117518e2e1aSwdenk struct offset_v1
118518e2e1aSwdenk {
119518e2e1aSwdenk   /*
120518e2e1aSwdenk    * for regular files this is the offset to the first byte of the
121518e2e1aSwdenk    * body, contained in the object-item, as measured from the start of
122518e2e1aSwdenk    * the entire body of the object.
123518e2e1aSwdenk    *
124518e2e1aSwdenk    * for directory entries, k_offset consists of hash derived from
125518e2e1aSwdenk    * hashing the name and using few bits (23 or more) of the resulting
126518e2e1aSwdenk    * hash, and generation number that allows distinguishing names with
127518e2e1aSwdenk    * hash collisions. If number of collisions overflows generation
128518e2e1aSwdenk    * number, we return EEXIST.	High order bit is 0 always
129518e2e1aSwdenk    */
130518e2e1aSwdenk   __u32 k_offset;
131518e2e1aSwdenk   __u32 k_uniqueness;
132518e2e1aSwdenk };
133518e2e1aSwdenk 
134518e2e1aSwdenk struct offset_v2 {
135518e2e1aSwdenk   /*
136518e2e1aSwdenk    * for regular files this is the offset to the first byte of the
137518e2e1aSwdenk    * body, contained in the object-item, as measured from the start of
138518e2e1aSwdenk    * the entire body of the object.
139518e2e1aSwdenk    *
140518e2e1aSwdenk    * for directory entries, k_offset consists of hash derived from
141518e2e1aSwdenk    * hashing the name and using few bits (23 or more) of the resulting
142518e2e1aSwdenk    * hash, and generation number that allows distinguishing names with
143518e2e1aSwdenk    * hash collisions. If number of collisions overflows generation
144518e2e1aSwdenk    * number, we return EEXIST.	High order bit is 0 always
145518e2e1aSwdenk    */
146518e2e1aSwdenk 
147518e2e1aSwdenk #if defined(__LITTLE_ENDIAN_BITFIELD)
148518e2e1aSwdenk 	    /* little endian version */
149518e2e1aSwdenk 	    __u64 k_offset:60;
150518e2e1aSwdenk 	    __u64 k_type: 4;
151518e2e1aSwdenk #elif defined(__BIG_ENDIAN_BITFIELD)
152518e2e1aSwdenk 	    /* big endian version */
153518e2e1aSwdenk 	    __u64 k_type: 4;
154518e2e1aSwdenk 	    __u64 k_offset:60;
155518e2e1aSwdenk #else
156518e2e1aSwdenk #error "__LITTLE_ENDIAN_BITFIELD or __BIG_ENDIAN_BITFIELD must be defined"
157518e2e1aSwdenk #endif
158518e2e1aSwdenk } __attribute__ ((__packed__));
159518e2e1aSwdenk 
160518e2e1aSwdenk #define TYPE_MAXTYPE 3
161518e2e1aSwdenk #define TYPE_ANY 15
162518e2e1aSwdenk 
163518e2e1aSwdenk #if (__BYTE_ORDER == __BIG_ENDIAN)
164518e2e1aSwdenk typedef union {
165518e2e1aSwdenk     struct offset_v2 offset_v2;
166518e2e1aSwdenk     __u64 linear;
167518e2e1aSwdenk } __attribute__ ((__packed__)) offset_v2_esafe_overlay;
168518e2e1aSwdenk 
offset_v2_k_type(const struct offset_v2 * v2)169518e2e1aSwdenk static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 )
170518e2e1aSwdenk {
171518e2e1aSwdenk     offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
172518e2e1aSwdenk     tmp.linear = __le64_to_cpu( tmp.linear );
173518e2e1aSwdenk     return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY;
174518e2e1aSwdenk }
175518e2e1aSwdenk 
offset_v2_k_offset(const struct offset_v2 * v2)176518e2e1aSwdenk static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 )
177518e2e1aSwdenk {
178518e2e1aSwdenk     offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
179518e2e1aSwdenk     tmp.linear = __le64_to_cpu( tmp.linear );
180518e2e1aSwdenk     return tmp.offset_v2.k_offset;
181518e2e1aSwdenk }
182518e2e1aSwdenk #elif (__BYTE_ORDER == __LITTLE_ENDIAN)
183518e2e1aSwdenk # define offset_v2_k_type(v2)		((v2)->k_type)
184518e2e1aSwdenk # define offset_v2_k_offset(v2)		((v2)->k_offset)
185518e2e1aSwdenk #else
186518e2e1aSwdenk #error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN"
187518e2e1aSwdenk #endif
188518e2e1aSwdenk 
189518e2e1aSwdenk struct key
190518e2e1aSwdenk {
191518e2e1aSwdenk   /* packing locality: by default parent directory object id */
192518e2e1aSwdenk   __u32 k_dir_id;
193518e2e1aSwdenk   /* object identifier */
194518e2e1aSwdenk   __u32 k_objectid;
195518e2e1aSwdenk   /* the offset and node type (old and new form) */
196518e2e1aSwdenk   union
197518e2e1aSwdenk   {
198518e2e1aSwdenk     struct offset_v1 v1;
199518e2e1aSwdenk     struct offset_v2 v2;
200518e2e1aSwdenk   }
201518e2e1aSwdenk   u;
202518e2e1aSwdenk };
203518e2e1aSwdenk 
204518e2e1aSwdenk #define KEY_SIZE (sizeof (struct key))
205518e2e1aSwdenk 
206518e2e1aSwdenk /* Header of a disk block.  More precisely, header of a formatted leaf
207518e2e1aSwdenk    or internal node, and not the header of an unformatted node. */
208518e2e1aSwdenk struct block_head
209518e2e1aSwdenk {
210518e2e1aSwdenk   __u16 blk_level;	  /* Level of a block in the tree. */
211518e2e1aSwdenk   __u16 blk_nr_item;	  /* Number of keys/items in a block. */
212518e2e1aSwdenk   __u16 blk_free_space;   /* Block free space in bytes. */
213518e2e1aSwdenk   struct key  blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes
214518e2e1aSwdenk 				      only) */
215518e2e1aSwdenk };
216518e2e1aSwdenk #define BLKH_SIZE (sizeof (struct block_head))
217518e2e1aSwdenk #define DISK_LEAF_NODE_LEVEL  1 /* Leaf node level.			  */
218518e2e1aSwdenk 
219518e2e1aSwdenk struct item_head
220518e2e1aSwdenk {
221518e2e1aSwdenk 	/* Everything in the tree is found by searching for it based on
222518e2e1aSwdenk 	 * its key.*/
223518e2e1aSwdenk 	struct key ih_key;
224518e2e1aSwdenk 	union {
225518e2e1aSwdenk 		/* The free space in the last unformatted node of an
226518e2e1aSwdenk 		   indirect item if this is an indirect item.  This
227518e2e1aSwdenk 		   equals 0xFFFF iff this is a direct item or stat data
228518e2e1aSwdenk 		   item. Note that the key, not this field, is used to
229518e2e1aSwdenk 		   determine the item type, and thus which field this
230518e2e1aSwdenk 		   union contains. */
231518e2e1aSwdenk 		__u16 ih_free_space;
232518e2e1aSwdenk 		/* Iff this is a directory item, this field equals the
233518e2e1aSwdenk 		   number of directory entries in the directory item. */
234518e2e1aSwdenk 		__u16 ih_entry_count;
235518e2e1aSwdenk 	} __attribute__ ((__packed__)) u;
236518e2e1aSwdenk 	__u16 ih_item_len;	     /* total size of the item body */
237518e2e1aSwdenk 	__u16 ih_item_location;      /* an offset to the item body
238518e2e1aSwdenk 				      * within the block */
239518e2e1aSwdenk 	__u16 ih_version;	     /* 0 for all old items, 2 for new
240518e2e1aSwdenk 					ones. Highest bit is set by fsck
241518e2e1aSwdenk 					temporary, cleaned after all
242518e2e1aSwdenk 					done */
243518e2e1aSwdenk } __attribute__ ((__packed__));
244518e2e1aSwdenk 
245518e2e1aSwdenk /* size of item header	   */
246518e2e1aSwdenk #define IH_SIZE (sizeof (struct item_head))
247518e2e1aSwdenk 
248518e2e1aSwdenk #define ITEM_VERSION_1 0
249518e2e1aSwdenk #define ITEM_VERSION_2 1
250518e2e1aSwdenk 
251518e2e1aSwdenk #define ih_version(ih)	  (__le16_to_cpu((ih)->ih_version))
252518e2e1aSwdenk 
253518e2e1aSwdenk #define IH_KEY_OFFSET(ih) (ih_version(ih) == ITEM_VERSION_1 \
254518e2e1aSwdenk 			   ? __le32_to_cpu((ih)->ih_key.u.v1.k_offset) \
255518e2e1aSwdenk 			   : offset_v2_k_offset(&((ih)->ih_key.u.v2)))
256518e2e1aSwdenk 
257518e2e1aSwdenk #define IH_KEY_ISTYPE(ih, type) (ih_version(ih) == ITEM_VERSION_1 \
258518e2e1aSwdenk 				 ? __le32_to_cpu((ih)->ih_key.u.v1.k_uniqueness) == V1_##type \
259518e2e1aSwdenk 				 : offset_v2_k_type(&((ih)->ih_key.u.v2)) == V2_##type)
260518e2e1aSwdenk 
261518e2e1aSwdenk /***************************************************************************/
262518e2e1aSwdenk /*			DISK CHILD					   */
263518e2e1aSwdenk /***************************************************************************/
264518e2e1aSwdenk /* Disk child pointer: The pointer from an internal node of the tree
265518e2e1aSwdenk    to a node that is on disk. */
266518e2e1aSwdenk struct disk_child {
267518e2e1aSwdenk   __u32       dc_block_number;		    /* Disk child's block number. */
268518e2e1aSwdenk   __u16       dc_size;			    /* Disk child's used space.   */
269518e2e1aSwdenk   __u16       dc_reserved;
270518e2e1aSwdenk };
271518e2e1aSwdenk 
272518e2e1aSwdenk #define DC_SIZE (sizeof(struct disk_child))
273518e2e1aSwdenk #define dc_block_number(dc_p)	(__le32_to_cpu((dc_p)->dc_block_number))
274518e2e1aSwdenk 
275518e2e1aSwdenk 
276b79a11ccSwdenk /*
277b79a11ccSwdenk  * old stat data is 32 bytes long. We are going to distinguish new one by
278b79a11ccSwdenk  * different size
279b79a11ccSwdenk  */
280518e2e1aSwdenk struct stat_data_v1
281518e2e1aSwdenk {
282518e2e1aSwdenk     __u16 sd_mode;	/* file type, permissions */
283518e2e1aSwdenk     __u16 sd_nlink;	/* number of hard links */
284518e2e1aSwdenk     __u16 sd_uid;		/* owner */
285518e2e1aSwdenk     __u16 sd_gid;		/* group */
286518e2e1aSwdenk     __u32 sd_size;	/* file size */
287518e2e1aSwdenk     __u32 sd_atime;	/* time of last access */
288518e2e1aSwdenk     __u32 sd_mtime;	/* time file was last modified	*/
289518e2e1aSwdenk     __u32 sd_ctime;	/* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
290518e2e1aSwdenk     union {
291518e2e1aSwdenk 	__u32 sd_rdev;
292518e2e1aSwdenk 	__u32 sd_blocks;	/* number of blocks file uses */
293518e2e1aSwdenk     } __attribute__ ((__packed__)) u;
294518e2e1aSwdenk     __u32 sd_first_direct_byte; /* first byte of file which is stored
295518e2e1aSwdenk 				   in a direct item: except that if it
296518e2e1aSwdenk 				   equals 1 it is a symlink and if it
297518e2e1aSwdenk 				   equals ~(__u32)0 there is no
298518e2e1aSwdenk 				   direct item.  The existence of this
299518e2e1aSwdenk 				   field really grates on me. Let's
300518e2e1aSwdenk 				   replace it with a macro based on
301518e2e1aSwdenk 				   sd_size and our tail suppression
302518e2e1aSwdenk 				   policy.  Someday.  -Hans */
303518e2e1aSwdenk } __attribute__ ((__packed__));
304518e2e1aSwdenk 
305518e2e1aSwdenk #define stat_data_v1(ih)	(ih_version(ih) == ITEM_VERSION_1)
306518e2e1aSwdenk #define sd_v1_mode(sdp)		((sdp)->sd_mode)
307518e2e1aSwdenk #define sd_v1_nlink(sdp)	(__le16_to_cpu((sdp)->sd_nlink))
308518e2e1aSwdenk #define sd_v1_uid(sdp)		(__le16_to_cpu((sdp)->sd_uid))
309518e2e1aSwdenk #define sd_v1_gid(sdp)		(__le16_to_cpu((sdp)->sd_gid))
310518e2e1aSwdenk #define sd_v1_size(sdp)		(__le32_to_cpu((sdp)->sd_size))
311518e2e1aSwdenk #define sd_v1_mtime(sdp)	(__le32_to_cpu((sdp)->sd_mtime))
312518e2e1aSwdenk 
313518e2e1aSwdenk /* Stat Data on disk (reiserfs version of UFS disk inode minus the
314518e2e1aSwdenk    address blocks) */
315518e2e1aSwdenk struct stat_data {
316518e2e1aSwdenk     __u16 sd_mode;	/* file type, permissions */
317518e2e1aSwdenk     __u16 sd_attrs;	/* persistent inode flags */
318518e2e1aSwdenk     __u32 sd_nlink;	/* number of hard links */
319518e2e1aSwdenk     __u64 sd_size;	/* file size */
320518e2e1aSwdenk     __u32 sd_uid;		/* owner */
321518e2e1aSwdenk     __u32 sd_gid;		/* group */
322518e2e1aSwdenk     __u32 sd_atime;	/* time of last access */
323518e2e1aSwdenk     __u32 sd_mtime;	/* time file was last modified	*/
324518e2e1aSwdenk     __u32 sd_ctime;	/* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
325518e2e1aSwdenk     __u32 sd_blocks;
326518e2e1aSwdenk     union {
327518e2e1aSwdenk 	__u32 sd_rdev;
328518e2e1aSwdenk 	__u32 sd_generation;
329b79a11ccSwdenk       /*__u32 sd_first_direct_byte; */
330518e2e1aSwdenk       /* first byte of file which is stored in a
331518e2e1aSwdenk 				       direct item: except that if it equals 1
332518e2e1aSwdenk 				       it is a symlink and if it equals
333518e2e1aSwdenk 				       ~(__u32)0 there is no direct item.  The
334518e2e1aSwdenk 				       existence of this field really grates
335518e2e1aSwdenk 				       on me. Let's replace it with a macro
336518e2e1aSwdenk 				       based on sd_size and our tail
337518e2e1aSwdenk 				       suppression policy? */
338518e2e1aSwdenk   } __attribute__ ((__packed__)) u;
339518e2e1aSwdenk } __attribute__ ((__packed__));
340518e2e1aSwdenk 
341518e2e1aSwdenk #define stat_data_v2(ih)	(ih_version(ih) == ITEM_VERSION_2)
342518e2e1aSwdenk #define sd_v2_mode(sdp)		(__le16_to_cpu((sdp)->sd_mode))
343518e2e1aSwdenk #define sd_v2_nlink(sdp)	(__le32_to_cpu((sdp)->sd_nlink))
344518e2e1aSwdenk #define sd_v2_size(sdp)		(__le64_to_cpu((sdp)->sd_size))
345518e2e1aSwdenk #define sd_v2_uid(sdp)		(__le32_to_cpu((sdp)->sd_uid))
346518e2e1aSwdenk #define sd_v2_gid(sdp)		(__le32_to_cpu((sdp)->sd_gid))
347518e2e1aSwdenk #define sd_v2_mtime(sdp)	(__le32_to_cpu((sdp)->sd_mtime))
348518e2e1aSwdenk 
349518e2e1aSwdenk #define sd_mode(sdp)	     (__le16_to_cpu((sdp)->sd_mode))
350518e2e1aSwdenk #define sd_size(sdp)	     (__le32_to_cpu((sdp)->sd_size))
351518e2e1aSwdenk #define sd_size_hi(sdp)      (__le32_to_cpu((sdp)->sd_size_hi))
352518e2e1aSwdenk 
353518e2e1aSwdenk struct reiserfs_de_head
354518e2e1aSwdenk {
355518e2e1aSwdenk   __u32 deh_offset;  /* third component of the directory entry key */
356518e2e1aSwdenk   __u32 deh_dir_id;  /* objectid of the parent directory of the
357518e2e1aSwdenk 			object, that is referenced by directory entry */
358518e2e1aSwdenk   __u32 deh_objectid;/* objectid of the object, that is referenced by
359518e2e1aSwdenk 			directory entry */
360518e2e1aSwdenk   __u16 deh_location;/* offset of name in the whole item */
361518e2e1aSwdenk   __u16 deh_state;   /* whether 1) entry contains stat data (for
362518e2e1aSwdenk 			future), and 2) whether entry is hidden
363518e2e1aSwdenk 			(unlinked) */
364518e2e1aSwdenk };
365518e2e1aSwdenk 
366518e2e1aSwdenk #define DEH_SIZE (sizeof (struct reiserfs_de_head))
367518e2e1aSwdenk #define deh_offset(p_deh)	  (__le32_to_cpu((p_deh)->deh_offset))
368518e2e1aSwdenk #define deh_dir_id(p_deh)	  (__le32_to_cpu((p_deh)->deh_dir_id))
369518e2e1aSwdenk #define deh_objectid(p_deh)	  (__le32_to_cpu((p_deh)->deh_objectid))
370518e2e1aSwdenk #define deh_location(p_deh)	  (__le16_to_cpu((p_deh)->deh_location))
371518e2e1aSwdenk #define deh_state(p_deh)	  (__le16_to_cpu((p_deh)->deh_state))
372518e2e1aSwdenk 
373518e2e1aSwdenk 
374518e2e1aSwdenk #define DEH_Statdata (1 << 0)			/* not used now */
375518e2e1aSwdenk #define DEH_Visible  (1 << 2)
376518e2e1aSwdenk 
377518e2e1aSwdenk #define SD_OFFSET  0
378518e2e1aSwdenk #define SD_UNIQUENESS 0
379518e2e1aSwdenk #define DOT_OFFSET 1
380518e2e1aSwdenk #define DOT_DOT_OFFSET 2
381518e2e1aSwdenk #define DIRENTRY_UNIQUENESS 500
382518e2e1aSwdenk 
383518e2e1aSwdenk #define V1_TYPE_STAT_DATA 0x0
384518e2e1aSwdenk #define V1_TYPE_DIRECT 0xffffffff
385518e2e1aSwdenk #define V1_TYPE_INDIRECT 0xfffffffe
386518e2e1aSwdenk #define V1_TYPE_DIRECTORY_MAX 0xfffffffd
387518e2e1aSwdenk #define V2_TYPE_STAT_DATA 0
388518e2e1aSwdenk #define V2_TYPE_INDIRECT 1
389518e2e1aSwdenk #define V2_TYPE_DIRECT 2
390518e2e1aSwdenk #define V2_TYPE_DIRENTRY 3
391518e2e1aSwdenk 
392518e2e1aSwdenk #define REISERFS_ROOT_OBJECTID 2
393518e2e1aSwdenk #define REISERFS_ROOT_PARENT_OBJECTID 1
394518e2e1aSwdenk #define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
395518e2e1aSwdenk /* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
396518e2e1aSwdenk #define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
397518e2e1aSwdenk #define REISERFS_OLD_BLOCKSIZE 4096
398518e2e1aSwdenk 
399518e2e1aSwdenk #define S_ISREG(mode) (((mode) & 0170000) == 0100000)
400518e2e1aSwdenk #define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
401518e2e1aSwdenk #define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
402518e2e1aSwdenk 
403518e2e1aSwdenk #define PATH_MAX       1024	/* include/linux/limits.h */
404518e2e1aSwdenk #define MAX_LINK_COUNT	  5	/* number of symbolic links to follow */
405518e2e1aSwdenk 
406518e2e1aSwdenk /* The size of the node cache */
407518e2e1aSwdenk #define FSYSREISER_CACHE_SIZE 24*1024
408518e2e1aSwdenk #define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
409518e2e1aSwdenk #define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
410518e2e1aSwdenk 
411518e2e1aSwdenk /* Info about currently opened file */
412518e2e1aSwdenk struct fsys_reiser_fileinfo
413518e2e1aSwdenk {
414518e2e1aSwdenk   __u32 k_dir_id;
415518e2e1aSwdenk   __u32 k_objectid;
416518e2e1aSwdenk };
417518e2e1aSwdenk 
418518e2e1aSwdenk /* In memory info about the currently mounted filesystem */
419518e2e1aSwdenk struct fsys_reiser_info
420518e2e1aSwdenk {
421518e2e1aSwdenk   /* The last read item head */
422518e2e1aSwdenk   struct item_head *current_ih;
423518e2e1aSwdenk   /* The last read item */
424518e2e1aSwdenk   char *current_item;
425518e2e1aSwdenk   /* The information for the currently opened file */
426518e2e1aSwdenk   struct fsys_reiser_fileinfo fileinfo;
427518e2e1aSwdenk   /* The start of the journal */
428518e2e1aSwdenk   __u32 journal_block;
429518e2e1aSwdenk   /* The size of the journal */
430518e2e1aSwdenk   __u32 journal_block_count;
431518e2e1aSwdenk   /* The first valid descriptor block in journal
432518e2e1aSwdenk      (relative to journal_block) */
433518e2e1aSwdenk   __u32 journal_first_desc;
434518e2e1aSwdenk 
435518e2e1aSwdenk   /* The ReiserFS version. */
436518e2e1aSwdenk   __u16 version;
437518e2e1aSwdenk   /* The current depth of the reiser tree. */
438518e2e1aSwdenk   __u16 tree_depth;
439518e2e1aSwdenk   /* SECTOR_SIZE << blocksize_shift == blocksize. */
440518e2e1aSwdenk   __u8	blocksize_shift;
441518e2e1aSwdenk   /* 1 << full_blocksize_shift == blocksize. */
442518e2e1aSwdenk   __u8	fullblocksize_shift;
443518e2e1aSwdenk   /* The reiserfs block size  (must be a power of 2) */
444518e2e1aSwdenk   __u16 blocksize;
445518e2e1aSwdenk   /* The number of cached tree nodes */
446518e2e1aSwdenk   __u16 cached_slots;
447518e2e1aSwdenk   /* The number of valid transactions in journal */
448518e2e1aSwdenk   __u16 journal_transactions;
449518e2e1aSwdenk 
450518e2e1aSwdenk   unsigned int blocks[MAX_HEIGHT];
451518e2e1aSwdenk   unsigned int next_key_nr[MAX_HEIGHT];
452518e2e1aSwdenk };
453518e2e1aSwdenk 
454518e2e1aSwdenk /* The cached s+tree blocks in FSYS_BUF,  see below
455518e2e1aSwdenk  * for a more detailed description.
456518e2e1aSwdenk  */
457518e2e1aSwdenk #define ROOT	 ((char *) ((int) FSYS_BUF))
458518e2e1aSwdenk #define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift))
459518e2e1aSwdenk #define LEAF	 CACHE (DISK_LEAF_NODE_LEVEL)
460518e2e1aSwdenk 
461518e2e1aSwdenk #define BLOCKHEAD(cache) ((struct block_head *) cache)
462518e2e1aSwdenk #define ITEMHEAD	 ((struct item_head  *) ((int) LEAF + BLKH_SIZE))
463518e2e1aSwdenk #define KEY(cache)	 ((struct key	     *) ((int) cache + BLKH_SIZE))
464518e2e1aSwdenk #define DC(cache)	 ((struct disk_child *) \
465518e2e1aSwdenk 			  ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
466518e2e1aSwdenk /* The fsys_reiser_info block.
467518e2e1aSwdenk  */
468518e2e1aSwdenk #define INFO \
469518e2e1aSwdenk     ((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE))
470518e2e1aSwdenk /*
471518e2e1aSwdenk  * The journal cache.  For each transaction it contains the number of
472518e2e1aSwdenk  * blocks followed by the real block numbers of this transaction.
473518e2e1aSwdenk  *
474518e2e1aSwdenk  * If the block numbers of some transaction won't fit in this space,
475518e2e1aSwdenk  * this list is stopped with a 0xffffffff marker and the remaining
476518e2e1aSwdenk  * uncommitted transactions aren't cached.
477518e2e1aSwdenk  */
478518e2e1aSwdenk #define JOURNAL_START	 ((__u32 *) (INFO + 1))
479518e2e1aSwdenk #define JOURNAL_END	 ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
480518e2e1aSwdenk 
481518e2e1aSwdenk 
482518e2e1aSwdenk static __inline__ unsigned long
log2(unsigned long word)483518e2e1aSwdenk log2 (unsigned long word)
484518e2e1aSwdenk {
485518e2e1aSwdenk #ifdef __I386__
486518e2e1aSwdenk   __asm__ ("bsfl %1,%0"
487518e2e1aSwdenk 	   : "=r" (word)
488518e2e1aSwdenk 	   : "r" (word));
489518e2e1aSwdenk   return word;
490518e2e1aSwdenk #else
491518e2e1aSwdenk   int i;
492518e2e1aSwdenk 
493518e2e1aSwdenk   for(i=0; i<(8*sizeof(word)); i++)
494518e2e1aSwdenk     if ((1<<i) & word)
495518e2e1aSwdenk       return i;
496518e2e1aSwdenk 
497518e2e1aSwdenk   return 0;
498518e2e1aSwdenk #endif
499518e2e1aSwdenk }
500518e2e1aSwdenk 
501518e2e1aSwdenk static __inline__ int
is_power_of_two(unsigned long word)502518e2e1aSwdenk is_power_of_two (unsigned long word)
503518e2e1aSwdenk {
504518e2e1aSwdenk   return (word & -word) == word;
505518e2e1aSwdenk }
506518e2e1aSwdenk 
507518e2e1aSwdenk extern const char *bb_mode_string(int mode);
508518e2e1aSwdenk extern int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf);
509