1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * GRUB -- GRand Unified Bootloader
5*4882a593Smuzhiyun * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * (C) Copyright 2003 - 2004
8*4882a593Smuzhiyun * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun /* An implementation for the ReiserFS filesystem ported from GRUB.
15*4882a593Smuzhiyun * Some parts of this code (mainly the structures and defines) are
16*4882a593Smuzhiyun * from the original reiser fs code, as found in the linux kernel.
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #ifndef __BYTE_ORDER
20*4882a593Smuzhiyun #if defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
21*4882a593Smuzhiyun #define __BYTE_ORDER __LITTLE_ENDIAN
22*4882a593Smuzhiyun #elif defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
23*4882a593Smuzhiyun #define __BYTE_ORDER __BIG_ENDIAN
24*4882a593Smuzhiyun #else
25*4882a593Smuzhiyun #error "unable to define __BYTE_ORDER"
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun #endif /* not __BYTE_ORDER */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define FSYS_BUFLEN 0x8000
30*4882a593Smuzhiyun #define FSYS_BUF fsys_buf
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* This is the new super block of a journaling reiserfs system */
33*4882a593Smuzhiyun struct reiserfs_super_block
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun __u32 s_block_count; /* blocks count */
36*4882a593Smuzhiyun __u32 s_free_blocks; /* free blocks count */
37*4882a593Smuzhiyun __u32 s_root_block; /* root block number */
38*4882a593Smuzhiyun __u32 s_journal_block; /* journal block number */
39*4882a593Smuzhiyun __u32 s_journal_dev; /* journal device number */
40*4882a593Smuzhiyun __u32 s_journal_size; /* size of the journal on FS creation. used to make sure they don't overflow it */
41*4882a593Smuzhiyun __u32 s_journal_trans_max; /* max number of blocks in a transaction. */
42*4882a593Smuzhiyun __u32 s_journal_magic; /* random value made on fs creation */
43*4882a593Smuzhiyun __u32 s_journal_max_batch; /* max number of blocks to batch into a trans */
44*4882a593Smuzhiyun __u32 s_journal_max_commit_age; /* in seconds, how old can an async commit be */
45*4882a593Smuzhiyun __u32 s_journal_max_trans_age; /* in seconds, how old can a transaction be */
46*4882a593Smuzhiyun __u16 s_blocksize; /* block size */
47*4882a593Smuzhiyun __u16 s_oid_maxsize; /* max size of object id array */
48*4882a593Smuzhiyun __u16 s_oid_cursize; /* current size of object id array */
49*4882a593Smuzhiyun __u16 s_state; /* valid or error */
50*4882a593Smuzhiyun char s_magic[16]; /* reiserfs magic string indicates that file system is reiserfs */
51*4882a593Smuzhiyun __u16 s_tree_height; /* height of disk tree */
52*4882a593Smuzhiyun __u16 s_bmap_nr; /* amount of bitmap blocks needed to address each block of file system */
53*4882a593Smuzhiyun __u16 s_version;
54*4882a593Smuzhiyun char s_unused[128]; /* zero filled by mkreiserfs */
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define sb_root_block(sbp) (__le32_to_cpu((sbp)->s_root_block))
59*4882a593Smuzhiyun #define sb_journal_block(sbp) (__le32_to_cpu((sbp)->s_journal_block))
60*4882a593Smuzhiyun #define set_sb_journal_block(sbp,v) ((sbp)->s_journal_block = __cpu_to_le32(v))
61*4882a593Smuzhiyun #define sb_journal_size(sbp) (__le32_to_cpu((sbp)->s_journal_size))
62*4882a593Smuzhiyun #define sb_blocksize(sbp) (__le16_to_cpu((sbp)->s_blocksize))
63*4882a593Smuzhiyun #define set_sb_blocksize(sbp,v) ((sbp)->s_blocksize = __cpu_to_le16(v))
64*4882a593Smuzhiyun #define sb_version(sbp) (__le16_to_cpu((sbp)->s_version))
65*4882a593Smuzhiyun #define set_sb_version(sbp,v) ((sbp)->s_version = __cpu_to_le16(v))
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun #define REISERFS_MAX_SUPPORTED_VERSION 2
69*4882a593Smuzhiyun #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
70*4882a593Smuzhiyun #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
71*4882a593Smuzhiyun #define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs"
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun #define MAX_HEIGHT 7
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* must be correct to keep the desc and commit structs at 4k */
76*4882a593Smuzhiyun #define JOURNAL_TRANS_HALF 1018
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* first block written in a commit. */
79*4882a593Smuzhiyun struct reiserfs_journal_desc {
80*4882a593Smuzhiyun __u32 j_trans_id; /* id of commit */
81*4882a593Smuzhiyun __u32 j_len; /* length of commit. len +1 is the commit block */
82*4882a593Smuzhiyun __u32 j_mount_id; /* mount id of this trans*/
83*4882a593Smuzhiyun __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */
84*4882a593Smuzhiyun char j_magic[12];
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun /* last block written in a commit */
88*4882a593Smuzhiyun struct reiserfs_journal_commit {
89*4882a593Smuzhiyun __u32 j_trans_id; /* must match j_trans_id from the desc block */
90*4882a593Smuzhiyun __u32 j_len; /* ditto */
91*4882a593Smuzhiyun __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */
92*4882a593Smuzhiyun char j_digest[16]; /* md5 sum of all the blocks involved, including desc and commit. not used, kill it */
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* this header block gets written whenever a transaction is considered
96*4882a593Smuzhiyun fully flushed, and is more recent than the last fully flushed
97*4882a593Smuzhiyun transaction.
98*4882a593Smuzhiyun fully flushed means all the log blocks and all the real blocks are
99*4882a593Smuzhiyun on disk, and this transaction does not need to be replayed.
100*4882a593Smuzhiyun */
101*4882a593Smuzhiyun struct reiserfs_journal_header {
102*4882a593Smuzhiyun /* id of last fully flushed transaction */
103*4882a593Smuzhiyun __u32 j_last_flush_trans_id;
104*4882a593Smuzhiyun /* offset in the log of where to start replay after a crash */
105*4882a593Smuzhiyun __u32 j_first_unflushed_offset;
106*4882a593Smuzhiyun /* mount id to detect very old transactions */
107*4882a593Smuzhiyun __u32 j_mount_id;
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* magic string to find desc blocks in the journal */
111*4882a593Smuzhiyun #define JOURNAL_DESC_MAGIC "ReIsErLB"
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /*
115*4882a593Smuzhiyun * directories use this key as well as old files
116*4882a593Smuzhiyun */
117*4882a593Smuzhiyun struct offset_v1
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun /*
120*4882a593Smuzhiyun * for regular files this is the offset to the first byte of the
121*4882a593Smuzhiyun * body, contained in the object-item, as measured from the start of
122*4882a593Smuzhiyun * the entire body of the object.
123*4882a593Smuzhiyun *
124*4882a593Smuzhiyun * for directory entries, k_offset consists of hash derived from
125*4882a593Smuzhiyun * hashing the name and using few bits (23 or more) of the resulting
126*4882a593Smuzhiyun * hash, and generation number that allows distinguishing names with
127*4882a593Smuzhiyun * hash collisions. If number of collisions overflows generation
128*4882a593Smuzhiyun * number, we return EEXIST. High order bit is 0 always
129*4882a593Smuzhiyun */
130*4882a593Smuzhiyun __u32 k_offset;
131*4882a593Smuzhiyun __u32 k_uniqueness;
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun struct offset_v2 {
135*4882a593Smuzhiyun /*
136*4882a593Smuzhiyun * for regular files this is the offset to the first byte of the
137*4882a593Smuzhiyun * body, contained in the object-item, as measured from the start of
138*4882a593Smuzhiyun * the entire body of the object.
139*4882a593Smuzhiyun *
140*4882a593Smuzhiyun * for directory entries, k_offset consists of hash derived from
141*4882a593Smuzhiyun * hashing the name and using few bits (23 or more) of the resulting
142*4882a593Smuzhiyun * hash, and generation number that allows distinguishing names with
143*4882a593Smuzhiyun * hash collisions. If number of collisions overflows generation
144*4882a593Smuzhiyun * number, we return EEXIST. High order bit is 0 always
145*4882a593Smuzhiyun */
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #if defined(__LITTLE_ENDIAN_BITFIELD)
148*4882a593Smuzhiyun /* little endian version */
149*4882a593Smuzhiyun __u64 k_offset:60;
150*4882a593Smuzhiyun __u64 k_type: 4;
151*4882a593Smuzhiyun #elif defined(__BIG_ENDIAN_BITFIELD)
152*4882a593Smuzhiyun /* big endian version */
153*4882a593Smuzhiyun __u64 k_type: 4;
154*4882a593Smuzhiyun __u64 k_offset:60;
155*4882a593Smuzhiyun #else
156*4882a593Smuzhiyun #error "__LITTLE_ENDIAN_BITFIELD or __BIG_ENDIAN_BITFIELD must be defined"
157*4882a593Smuzhiyun #endif
158*4882a593Smuzhiyun } __attribute__ ((__packed__));
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun #define TYPE_MAXTYPE 3
161*4882a593Smuzhiyun #define TYPE_ANY 15
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun #if (__BYTE_ORDER == __BIG_ENDIAN)
164*4882a593Smuzhiyun typedef union {
165*4882a593Smuzhiyun struct offset_v2 offset_v2;
166*4882a593Smuzhiyun __u64 linear;
167*4882a593Smuzhiyun } __attribute__ ((__packed__)) offset_v2_esafe_overlay;
168*4882a593Smuzhiyun
offset_v2_k_type(const struct offset_v2 * v2)169*4882a593Smuzhiyun static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 )
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
172*4882a593Smuzhiyun tmp.linear = __le64_to_cpu( tmp.linear );
173*4882a593Smuzhiyun return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
offset_v2_k_offset(const struct offset_v2 * v2)176*4882a593Smuzhiyun static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 )
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
179*4882a593Smuzhiyun tmp.linear = __le64_to_cpu( tmp.linear );
180*4882a593Smuzhiyun return tmp.offset_v2.k_offset;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun #elif (__BYTE_ORDER == __LITTLE_ENDIAN)
183*4882a593Smuzhiyun # define offset_v2_k_type(v2) ((v2)->k_type)
184*4882a593Smuzhiyun # define offset_v2_k_offset(v2) ((v2)->k_offset)
185*4882a593Smuzhiyun #else
186*4882a593Smuzhiyun #error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN"
187*4882a593Smuzhiyun #endif
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun struct key
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun /* packing locality: by default parent directory object id */
192*4882a593Smuzhiyun __u32 k_dir_id;
193*4882a593Smuzhiyun /* object identifier */
194*4882a593Smuzhiyun __u32 k_objectid;
195*4882a593Smuzhiyun /* the offset and node type (old and new form) */
196*4882a593Smuzhiyun union
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun struct offset_v1 v1;
199*4882a593Smuzhiyun struct offset_v2 v2;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun u;
202*4882a593Smuzhiyun };
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun #define KEY_SIZE (sizeof (struct key))
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun /* Header of a disk block. More precisely, header of a formatted leaf
207*4882a593Smuzhiyun or internal node, and not the header of an unformatted node. */
208*4882a593Smuzhiyun struct block_head
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun __u16 blk_level; /* Level of a block in the tree. */
211*4882a593Smuzhiyun __u16 blk_nr_item; /* Number of keys/items in a block. */
212*4882a593Smuzhiyun __u16 blk_free_space; /* Block free space in bytes. */
213*4882a593Smuzhiyun struct key blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes
214*4882a593Smuzhiyun only) */
215*4882a593Smuzhiyun };
216*4882a593Smuzhiyun #define BLKH_SIZE (sizeof (struct block_head))
217*4882a593Smuzhiyun #define DISK_LEAF_NODE_LEVEL 1 /* Leaf node level. */
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun struct item_head
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun /* Everything in the tree is found by searching for it based on
222*4882a593Smuzhiyun * its key.*/
223*4882a593Smuzhiyun struct key ih_key;
224*4882a593Smuzhiyun union {
225*4882a593Smuzhiyun /* The free space in the last unformatted node of an
226*4882a593Smuzhiyun indirect item if this is an indirect item. This
227*4882a593Smuzhiyun equals 0xFFFF iff this is a direct item or stat data
228*4882a593Smuzhiyun item. Note that the key, not this field, is used to
229*4882a593Smuzhiyun determine the item type, and thus which field this
230*4882a593Smuzhiyun union contains. */
231*4882a593Smuzhiyun __u16 ih_free_space;
232*4882a593Smuzhiyun /* Iff this is a directory item, this field equals the
233*4882a593Smuzhiyun number of directory entries in the directory item. */
234*4882a593Smuzhiyun __u16 ih_entry_count;
235*4882a593Smuzhiyun } __attribute__ ((__packed__)) u;
236*4882a593Smuzhiyun __u16 ih_item_len; /* total size of the item body */
237*4882a593Smuzhiyun __u16 ih_item_location; /* an offset to the item body
238*4882a593Smuzhiyun * within the block */
239*4882a593Smuzhiyun __u16 ih_version; /* 0 for all old items, 2 for new
240*4882a593Smuzhiyun ones. Highest bit is set by fsck
241*4882a593Smuzhiyun temporary, cleaned after all
242*4882a593Smuzhiyun done */
243*4882a593Smuzhiyun } __attribute__ ((__packed__));
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun /* size of item header */
246*4882a593Smuzhiyun #define IH_SIZE (sizeof (struct item_head))
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun #define ITEM_VERSION_1 0
249*4882a593Smuzhiyun #define ITEM_VERSION_2 1
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun #define ih_version(ih) (__le16_to_cpu((ih)->ih_version))
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun #define IH_KEY_OFFSET(ih) (ih_version(ih) == ITEM_VERSION_1 \
254*4882a593Smuzhiyun ? __le32_to_cpu((ih)->ih_key.u.v1.k_offset) \
255*4882a593Smuzhiyun : offset_v2_k_offset(&((ih)->ih_key.u.v2)))
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun #define IH_KEY_ISTYPE(ih, type) (ih_version(ih) == ITEM_VERSION_1 \
258*4882a593Smuzhiyun ? __le32_to_cpu((ih)->ih_key.u.v1.k_uniqueness) == V1_##type \
259*4882a593Smuzhiyun : offset_v2_k_type(&((ih)->ih_key.u.v2)) == V2_##type)
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun /***************************************************************************/
262*4882a593Smuzhiyun /* DISK CHILD */
263*4882a593Smuzhiyun /***************************************************************************/
264*4882a593Smuzhiyun /* Disk child pointer: The pointer from an internal node of the tree
265*4882a593Smuzhiyun to a node that is on disk. */
266*4882a593Smuzhiyun struct disk_child {
267*4882a593Smuzhiyun __u32 dc_block_number; /* Disk child's block number. */
268*4882a593Smuzhiyun __u16 dc_size; /* Disk child's used space. */
269*4882a593Smuzhiyun __u16 dc_reserved;
270*4882a593Smuzhiyun };
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun #define DC_SIZE (sizeof(struct disk_child))
273*4882a593Smuzhiyun #define dc_block_number(dc_p) (__le32_to_cpu((dc_p)->dc_block_number))
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun /*
277*4882a593Smuzhiyun * old stat data is 32 bytes long. We are going to distinguish new one by
278*4882a593Smuzhiyun * different size
279*4882a593Smuzhiyun */
280*4882a593Smuzhiyun struct stat_data_v1
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun __u16 sd_mode; /* file type, permissions */
283*4882a593Smuzhiyun __u16 sd_nlink; /* number of hard links */
284*4882a593Smuzhiyun __u16 sd_uid; /* owner */
285*4882a593Smuzhiyun __u16 sd_gid; /* group */
286*4882a593Smuzhiyun __u32 sd_size; /* file size */
287*4882a593Smuzhiyun __u32 sd_atime; /* time of last access */
288*4882a593Smuzhiyun __u32 sd_mtime; /* time file was last modified */
289*4882a593Smuzhiyun __u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
290*4882a593Smuzhiyun union {
291*4882a593Smuzhiyun __u32 sd_rdev;
292*4882a593Smuzhiyun __u32 sd_blocks; /* number of blocks file uses */
293*4882a593Smuzhiyun } __attribute__ ((__packed__)) u;
294*4882a593Smuzhiyun __u32 sd_first_direct_byte; /* first byte of file which is stored
295*4882a593Smuzhiyun in a direct item: except that if it
296*4882a593Smuzhiyun equals 1 it is a symlink and if it
297*4882a593Smuzhiyun equals ~(__u32)0 there is no
298*4882a593Smuzhiyun direct item. The existence of this
299*4882a593Smuzhiyun field really grates on me. Let's
300*4882a593Smuzhiyun replace it with a macro based on
301*4882a593Smuzhiyun sd_size and our tail suppression
302*4882a593Smuzhiyun policy. Someday. -Hans */
303*4882a593Smuzhiyun } __attribute__ ((__packed__));
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun #define stat_data_v1(ih) (ih_version(ih) == ITEM_VERSION_1)
306*4882a593Smuzhiyun #define sd_v1_mode(sdp) ((sdp)->sd_mode)
307*4882a593Smuzhiyun #define sd_v1_nlink(sdp) (__le16_to_cpu((sdp)->sd_nlink))
308*4882a593Smuzhiyun #define sd_v1_uid(sdp) (__le16_to_cpu((sdp)->sd_uid))
309*4882a593Smuzhiyun #define sd_v1_gid(sdp) (__le16_to_cpu((sdp)->sd_gid))
310*4882a593Smuzhiyun #define sd_v1_size(sdp) (__le32_to_cpu((sdp)->sd_size))
311*4882a593Smuzhiyun #define sd_v1_mtime(sdp) (__le32_to_cpu((sdp)->sd_mtime))
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun /* Stat Data on disk (reiserfs version of UFS disk inode minus the
314*4882a593Smuzhiyun address blocks) */
315*4882a593Smuzhiyun struct stat_data {
316*4882a593Smuzhiyun __u16 sd_mode; /* file type, permissions */
317*4882a593Smuzhiyun __u16 sd_attrs; /* persistent inode flags */
318*4882a593Smuzhiyun __u32 sd_nlink; /* number of hard links */
319*4882a593Smuzhiyun __u64 sd_size; /* file size */
320*4882a593Smuzhiyun __u32 sd_uid; /* owner */
321*4882a593Smuzhiyun __u32 sd_gid; /* group */
322*4882a593Smuzhiyun __u32 sd_atime; /* time of last access */
323*4882a593Smuzhiyun __u32 sd_mtime; /* time file was last modified */
324*4882a593Smuzhiyun __u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
325*4882a593Smuzhiyun __u32 sd_blocks;
326*4882a593Smuzhiyun union {
327*4882a593Smuzhiyun __u32 sd_rdev;
328*4882a593Smuzhiyun __u32 sd_generation;
329*4882a593Smuzhiyun /*__u32 sd_first_direct_byte; */
330*4882a593Smuzhiyun /* first byte of file which is stored in a
331*4882a593Smuzhiyun direct item: except that if it equals 1
332*4882a593Smuzhiyun it is a symlink and if it equals
333*4882a593Smuzhiyun ~(__u32)0 there is no direct item. The
334*4882a593Smuzhiyun existence of this field really grates
335*4882a593Smuzhiyun on me. Let's replace it with a macro
336*4882a593Smuzhiyun based on sd_size and our tail
337*4882a593Smuzhiyun suppression policy? */
338*4882a593Smuzhiyun } __attribute__ ((__packed__)) u;
339*4882a593Smuzhiyun } __attribute__ ((__packed__));
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun #define stat_data_v2(ih) (ih_version(ih) == ITEM_VERSION_2)
342*4882a593Smuzhiyun #define sd_v2_mode(sdp) (__le16_to_cpu((sdp)->sd_mode))
343*4882a593Smuzhiyun #define sd_v2_nlink(sdp) (__le32_to_cpu((sdp)->sd_nlink))
344*4882a593Smuzhiyun #define sd_v2_size(sdp) (__le64_to_cpu((sdp)->sd_size))
345*4882a593Smuzhiyun #define sd_v2_uid(sdp) (__le32_to_cpu((sdp)->sd_uid))
346*4882a593Smuzhiyun #define sd_v2_gid(sdp) (__le32_to_cpu((sdp)->sd_gid))
347*4882a593Smuzhiyun #define sd_v2_mtime(sdp) (__le32_to_cpu((sdp)->sd_mtime))
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun #define sd_mode(sdp) (__le16_to_cpu((sdp)->sd_mode))
350*4882a593Smuzhiyun #define sd_size(sdp) (__le32_to_cpu((sdp)->sd_size))
351*4882a593Smuzhiyun #define sd_size_hi(sdp) (__le32_to_cpu((sdp)->sd_size_hi))
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun struct reiserfs_de_head
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun __u32 deh_offset; /* third component of the directory entry key */
356*4882a593Smuzhiyun __u32 deh_dir_id; /* objectid of the parent directory of the
357*4882a593Smuzhiyun object, that is referenced by directory entry */
358*4882a593Smuzhiyun __u32 deh_objectid;/* objectid of the object, that is referenced by
359*4882a593Smuzhiyun directory entry */
360*4882a593Smuzhiyun __u16 deh_location;/* offset of name in the whole item */
361*4882a593Smuzhiyun __u16 deh_state; /* whether 1) entry contains stat data (for
362*4882a593Smuzhiyun future), and 2) whether entry is hidden
363*4882a593Smuzhiyun (unlinked) */
364*4882a593Smuzhiyun };
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun #define DEH_SIZE (sizeof (struct reiserfs_de_head))
367*4882a593Smuzhiyun #define deh_offset(p_deh) (__le32_to_cpu((p_deh)->deh_offset))
368*4882a593Smuzhiyun #define deh_dir_id(p_deh) (__le32_to_cpu((p_deh)->deh_dir_id))
369*4882a593Smuzhiyun #define deh_objectid(p_deh) (__le32_to_cpu((p_deh)->deh_objectid))
370*4882a593Smuzhiyun #define deh_location(p_deh) (__le16_to_cpu((p_deh)->deh_location))
371*4882a593Smuzhiyun #define deh_state(p_deh) (__le16_to_cpu((p_deh)->deh_state))
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun #define DEH_Statdata (1 << 0) /* not used now */
375*4882a593Smuzhiyun #define DEH_Visible (1 << 2)
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun #define SD_OFFSET 0
378*4882a593Smuzhiyun #define SD_UNIQUENESS 0
379*4882a593Smuzhiyun #define DOT_OFFSET 1
380*4882a593Smuzhiyun #define DOT_DOT_OFFSET 2
381*4882a593Smuzhiyun #define DIRENTRY_UNIQUENESS 500
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun #define V1_TYPE_STAT_DATA 0x0
384*4882a593Smuzhiyun #define V1_TYPE_DIRECT 0xffffffff
385*4882a593Smuzhiyun #define V1_TYPE_INDIRECT 0xfffffffe
386*4882a593Smuzhiyun #define V1_TYPE_DIRECTORY_MAX 0xfffffffd
387*4882a593Smuzhiyun #define V2_TYPE_STAT_DATA 0
388*4882a593Smuzhiyun #define V2_TYPE_INDIRECT 1
389*4882a593Smuzhiyun #define V2_TYPE_DIRECT 2
390*4882a593Smuzhiyun #define V2_TYPE_DIRENTRY 3
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun #define REISERFS_ROOT_OBJECTID 2
393*4882a593Smuzhiyun #define REISERFS_ROOT_PARENT_OBJECTID 1
394*4882a593Smuzhiyun #define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
395*4882a593Smuzhiyun /* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
396*4882a593Smuzhiyun #define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
397*4882a593Smuzhiyun #define REISERFS_OLD_BLOCKSIZE 4096
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun #define S_ISREG(mode) (((mode) & 0170000) == 0100000)
400*4882a593Smuzhiyun #define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
401*4882a593Smuzhiyun #define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun #define PATH_MAX 1024 /* include/linux/limits.h */
404*4882a593Smuzhiyun #define MAX_LINK_COUNT 5 /* number of symbolic links to follow */
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /* The size of the node cache */
407*4882a593Smuzhiyun #define FSYSREISER_CACHE_SIZE 24*1024
408*4882a593Smuzhiyun #define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
409*4882a593Smuzhiyun #define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun /* Info about currently opened file */
412*4882a593Smuzhiyun struct fsys_reiser_fileinfo
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun __u32 k_dir_id;
415*4882a593Smuzhiyun __u32 k_objectid;
416*4882a593Smuzhiyun };
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun /* In memory info about the currently mounted filesystem */
419*4882a593Smuzhiyun struct fsys_reiser_info
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun /* The last read item head */
422*4882a593Smuzhiyun struct item_head *current_ih;
423*4882a593Smuzhiyun /* The last read item */
424*4882a593Smuzhiyun char *current_item;
425*4882a593Smuzhiyun /* The information for the currently opened file */
426*4882a593Smuzhiyun struct fsys_reiser_fileinfo fileinfo;
427*4882a593Smuzhiyun /* The start of the journal */
428*4882a593Smuzhiyun __u32 journal_block;
429*4882a593Smuzhiyun /* The size of the journal */
430*4882a593Smuzhiyun __u32 journal_block_count;
431*4882a593Smuzhiyun /* The first valid descriptor block in journal
432*4882a593Smuzhiyun (relative to journal_block) */
433*4882a593Smuzhiyun __u32 journal_first_desc;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun /* The ReiserFS version. */
436*4882a593Smuzhiyun __u16 version;
437*4882a593Smuzhiyun /* The current depth of the reiser tree. */
438*4882a593Smuzhiyun __u16 tree_depth;
439*4882a593Smuzhiyun /* SECTOR_SIZE << blocksize_shift == blocksize. */
440*4882a593Smuzhiyun __u8 blocksize_shift;
441*4882a593Smuzhiyun /* 1 << full_blocksize_shift == blocksize. */
442*4882a593Smuzhiyun __u8 fullblocksize_shift;
443*4882a593Smuzhiyun /* The reiserfs block size (must be a power of 2) */
444*4882a593Smuzhiyun __u16 blocksize;
445*4882a593Smuzhiyun /* The number of cached tree nodes */
446*4882a593Smuzhiyun __u16 cached_slots;
447*4882a593Smuzhiyun /* The number of valid transactions in journal */
448*4882a593Smuzhiyun __u16 journal_transactions;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun unsigned int blocks[MAX_HEIGHT];
451*4882a593Smuzhiyun unsigned int next_key_nr[MAX_HEIGHT];
452*4882a593Smuzhiyun };
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /* The cached s+tree blocks in FSYS_BUF, see below
455*4882a593Smuzhiyun * for a more detailed description.
456*4882a593Smuzhiyun */
457*4882a593Smuzhiyun #define ROOT ((char *) ((int) FSYS_BUF))
458*4882a593Smuzhiyun #define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift))
459*4882a593Smuzhiyun #define LEAF CACHE (DISK_LEAF_NODE_LEVEL)
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun #define BLOCKHEAD(cache) ((struct block_head *) cache)
462*4882a593Smuzhiyun #define ITEMHEAD ((struct item_head *) ((int) LEAF + BLKH_SIZE))
463*4882a593Smuzhiyun #define KEY(cache) ((struct key *) ((int) cache + BLKH_SIZE))
464*4882a593Smuzhiyun #define DC(cache) ((struct disk_child *) \
465*4882a593Smuzhiyun ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
466*4882a593Smuzhiyun /* The fsys_reiser_info block.
467*4882a593Smuzhiyun */
468*4882a593Smuzhiyun #define INFO \
469*4882a593Smuzhiyun ((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE))
470*4882a593Smuzhiyun /*
471*4882a593Smuzhiyun * The journal cache. For each transaction it contains the number of
472*4882a593Smuzhiyun * blocks followed by the real block numbers of this transaction.
473*4882a593Smuzhiyun *
474*4882a593Smuzhiyun * If the block numbers of some transaction won't fit in this space,
475*4882a593Smuzhiyun * this list is stopped with a 0xffffffff marker and the remaining
476*4882a593Smuzhiyun * uncommitted transactions aren't cached.
477*4882a593Smuzhiyun */
478*4882a593Smuzhiyun #define JOURNAL_START ((__u32 *) (INFO + 1))
479*4882a593Smuzhiyun #define JOURNAL_END ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun static __inline__ unsigned long
log2(unsigned long word)483*4882a593Smuzhiyun log2 (unsigned long word)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun #ifdef __I386__
486*4882a593Smuzhiyun __asm__ ("bsfl %1,%0"
487*4882a593Smuzhiyun : "=r" (word)
488*4882a593Smuzhiyun : "r" (word));
489*4882a593Smuzhiyun return word;
490*4882a593Smuzhiyun #else
491*4882a593Smuzhiyun int i;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun for(i=0; i<(8*sizeof(word)); i++)
494*4882a593Smuzhiyun if ((1<<i) & word)
495*4882a593Smuzhiyun return i;
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun return 0;
498*4882a593Smuzhiyun #endif
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun static __inline__ int
is_power_of_two(unsigned long word)502*4882a593Smuzhiyun is_power_of_two (unsigned long word)
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun return (word & -word) == word;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun extern const char *bb_mode_string(int mode);
508*4882a593Smuzhiyun extern int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf);
509