a4f063805a17116369855e4e1304baaf9329eb13
[reactos.git] / reactos / drivers / filesystems / ext2_new / inc / linux / ext4_ext.h
1 #ifndef _LINUX_EXT4_EXT
2 #define _LINUX_EXT4_EXT
3
4 /*
5 * This is the extent tail on-disk structure.
6 * All other extent structures are 12 bytes long. It turns out that
7 * block_size % 12 >= 4 for at least all powers of 2 greater than 512, which
8 * covers all valid ext4 block sizes. Therefore, this tail structure can be
9 * crammed into the end of the block without having to rebalance the tree.
10 */
11 struct ext4_extent_tail {
12 uint32_t et_checksum; /* crc32c(uuid+inum+extent_block) */
13 };
14
15 /*
16 * This is the extent on-disk structure.
17 * It's used at the bottom of the tree.
18 */
19 typedef struct ext4_extent {
20 uint32_t ee_block; /* first logical block extent covers */
21 uint16_t ee_len; /* number of blocks covered by extent */
22 uint16_t ee_start_hi; /* high 16 bits of physical block */
23 uint32_t ee_start_lo; /* low 32 bits of physical block */
24 } __attribute__ ((__packed__)) EXT4_EXTENT;
25
26 /*
27 * This is index on-disk structure.
28 * It's used at all the levels except the bottom.
29 */
30 typedef struct ext4_extent_idx {
31 uint32_t ei_block; /* index covers logical blocks from 'block' */
32 uint32_t ei_leaf_lo; /* pointer to the physical block of the next *
33 * level. leaf or next index could be there */
34 uint16_t ei_leaf_hi; /* high 16 bits of physical block */
35 uint16_t ei_unused;
36 }__attribute__ ((__packed__)) EXT4_EXTENT_IDX;
37
38 /*
39 * Each block (leaves and indexes), even inode-stored has header.
40 */
41 typedef struct ext4_extent_header {
42 uint16_t eh_magic; /* probably will support different formats */
43 uint16_t eh_entries; /* number of valid entries */
44 uint16_t eh_max; /* capacity of store in entries */
45 uint16_t eh_depth; /* has tree real underlying blocks? */
46 uint32_t eh_generation; /* generation of the tree */
47 }__attribute__ ((__packed__)) EXT4_EXTENT_HEADER;
48
49
50 #define EXT4_EXT_MAGIC 0xf30a
51 #define get_ext4_header(i) ((struct ext4_extent_header *) (i)->i_block)
52
53 #define EXT4_EXTENT_TAIL_OFFSET(hdr) \
54 (sizeof(struct ext4_extent_header) + \
55 (sizeof(struct ext4_extent) * (hdr)->eh_max))
56
57 static inline struct ext4_extent_tail *
58 find_ext4_extent_tail(struct ext4_extent_header *eh)
59 {
60 return (struct ext4_extent_tail *)(((char *)eh) +
61 EXT4_EXTENT_TAIL_OFFSET(eh));
62 }
63
64 /*
65 * Array of ext4_ext_path contains path to some extent.
66 * Creation/lookup routines use it for traversal/splitting/etc.
67 * Truncate uses it to simulate recursive walking.
68 */
69 struct ext4_ext_path
70 {
71 ext4_fsblk_t p_block;
72 int p_depth;
73 int p_maxdepth;
74 struct ext4_extent *p_ext;
75 struct ext4_extent_idx *p_idx;
76 struct ext4_extent_header *p_hdr;
77 struct buffer_head *p_bh;
78 };
79
80 /*
81 * structure for external API
82 */
83
84 /*
85 * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
86 * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
87 * MSB of ee_len field in the extent datastructure to signify if this
88 * particular extent is an initialized extent or an uninitialized (i.e.
89 * preallocated).
90 * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
91 * uninitialized extent.
92 * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
93 * uninitialized one. In other words, if MSB of ee_len is set, it is an
94 * uninitialized extent with only one special scenario when ee_len = 0x8000.
95 * In this case we can not have an uninitialized extent of zero length and
96 * thus we make it as a special case of initialized extent with 0x8000 length.
97 * This way we get better extent-to-group alignment for initialized extents.
98 * Hence, the maximum number of blocks we can have in an *initialized*
99 * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
100 */
101 #define EXT_INIT_MAX_LEN (1UL << 15)
102 #define EXT_UNWRITTEN_MAX_LEN (EXT_INIT_MAX_LEN - 1)
103
104 #define EXT_EXTENT_SIZE sizeof(struct ext4_extent)
105 #define EXT_INDEX_SIZE sizeof(struct ext4_extent_idx)
106
107 #define EXT_FIRST_EXTENT(__hdr__) \
108 ((struct ext4_extent *)(((char *)(__hdr__)) + \
109 sizeof(struct ext4_extent_header)))
110 #define EXT_FIRST_INDEX(__hdr__) \
111 ((struct ext4_extent_idx *)(((char *)(__hdr__)) + \
112 sizeof(struct ext4_extent_header)))
113 #define EXT_HAS_FREE_INDEX(__path__) \
114 ((__path__)->p_hdr->eh_entries < (__path__)->p_hdr->eh_max)
115 #define EXT_LAST_EXTENT(__hdr__) \
116 (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_entries - 1)
117 #define EXT_LAST_INDEX(__hdr__) \
118 (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_entries - 1)
119 #define EXT_MAX_EXTENT(__hdr__) \
120 (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_max - 1)
121 #define EXT_MAX_INDEX(__hdr__) \
122 (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_max - 1)
123
124 static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
125 {
126 return get_ext4_header(inode);
127 }
128
129 static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
130 {
131 return (struct ext4_extent_header *)bh->b_data;
132 }
133
134 static inline unsigned short ext_depth(struct inode *inode)
135 {
136 return ext_inode_hdr(inode)->eh_depth;
137 }
138
139 static inline void ext4_ext_mark_uninitialized(struct ext4_extent *ext)
140 {
141 /* We can not have an uninitialized extent of zero length! */
142 ext->ee_len |= EXT_INIT_MAX_LEN;
143 }
144
145 static inline int ext4_ext_is_uninitialized(struct ext4_extent *ext)
146 {
147 /* Extent with ee_len of 0x8000 is treated as an initialized extent */
148 return (ext->ee_len > EXT_INIT_MAX_LEN);
149 }
150
151 static inline uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext)
152 {
153 return (ext->ee_len <= EXT_INIT_MAX_LEN
154 ? ext->ee_len
155 : (ext->ee_len - EXT_INIT_MAX_LEN));
156 }
157
158 static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
159 {
160 ext->ee_len = ext4_ext_get_actual_len(ext);
161 }
162
163 static inline void ext4_ext_mark_unwritten(struct ext4_extent *ext)
164 {
165 /* We can not have an unwritten extent of zero length! */
166 ext->ee_len |= EXT_INIT_MAX_LEN;
167 }
168
169 static inline int ext4_ext_is_unwritten(struct ext4_extent *ext)
170 {
171 /* Extent with ee_len of 0x8000 is treated as an initialized extent */
172 return (ext->ee_len > EXT_INIT_MAX_LEN);
173 }
174
175 /*
176 * ext4_ext_pblock:
177 * combine low and high parts of physical block number into ext4_fsblk_t
178 */
179 static inline ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
180 {
181 ext4_fsblk_t block;
182
183 block = ex->ee_start_lo;
184 block |= ((ext4_fsblk_t)ex->ee_start_hi << 31) << 1;
185 return block;
186 }
187
188 /*
189 * ext4_idx_pblock:
190 * combine low and high parts of a leaf physical block number into ext4_fsblk_t
191 */
192 static inline ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
193 {
194 ext4_fsblk_t block;
195
196 block = ix->ei_leaf_lo;
197 block |= ((ext4_fsblk_t)ix->ei_leaf_hi << 31) << 1;
198 return block;
199 }
200
201 /*
202 * ext4_ext_store_pblock:
203 * stores a large physical block number into an extent struct,
204 * breaking it into parts
205 */
206 static inline void ext4_ext_store_pblock(struct ext4_extent *ex,
207 ext4_fsblk_t pb)
208 {
209 ex->ee_start_lo = (uint32_t)(pb & 0xffffffff);
210 ex->ee_start_hi = (uint16_t)((pb >> 31) >> 1) & 0xffff;
211 }
212
213 /*
214 * ext4_idx_store_pblock:
215 * stores a large physical block number into an index struct,
216 * breaking it into parts
217 */
218 static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix,
219 ext4_fsblk_t pb)
220 {
221 ix->ei_leaf_lo = (uint32_t)(pb & 0xffffffff);
222 ix->ei_leaf_hi = (uint16_t)((pb >> 31) >> 1) & 0xffff;
223 }
224
225 #define ext4_ext_dirty(icb, handle, inode, path) \
226 __ext4_ext_dirty("", __LINE__, (icb), (handle), (inode), (path))
227
228 #define INODE_HAS_EXTENT(i) ((i)->i_flags & EXT2_EXTENTS_FL)
229
230 static inline uint64_t ext_to_block(EXT4_EXTENT *extent)
231 {
232 uint64_t block;
233
234 block = (uint64_t)extent->ee_start_lo;
235 block |= ((uint64_t) extent->ee_start_hi << 31) << 1;
236
237 return block;
238 }
239
240 static inline uint64_t idx_to_block(EXT4_EXTENT_IDX *idx)
241 {
242 uint64_t block;
243
244 block = (uint64_t)idx->ei_leaf_lo;
245 block |= ((uint64_t) idx->ei_leaf_hi << 31) << 1;
246
247 return block;
248 }
249
250
251 int ext4_ext_get_blocks(void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t iblock,
252 unsigned long max_blocks, struct buffer_head *bh_result,
253 int create, int flags);
254 int ext4_ext_tree_init(void *icb, handle_t *handle, struct inode *inode);
255 int ext4_ext_remove_space(void *icb, struct inode *inode, unsigned long start);
256
257 #endif /* _LINUX_EXT4_EXT */