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