1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#ifndef _EXT4_EXTENTS
20#define _EXT4_EXTENTS
21
22#include "ext4.h"
23
24
25
26
27
28
29
30#define AGGRESSIVE_TEST_
31
32
33
34
35
36
37#define EXTENTS_STATS__
38
39
40
41
42
43#define CHECK_BINSEARCH__
44
45
46
47
48
49#define EXT_STATS_
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67struct ext4_extent_tail {
68 __le32 et_checksum;
69};
70
71
72
73
74
75struct ext4_extent {
76 __le32 ee_block;
77 __le16 ee_len;
78 __le16 ee_start_hi;
79 __le32 ee_start_lo;
80};
81
82
83
84
85
86struct ext4_extent_idx {
87 __le32 ei_block;
88 __le32 ei_leaf_lo;
89
90 __le16 ei_leaf_hi;
91 __u16 ei_unused;
92};
93
94
95
96
97struct ext4_extent_header {
98 __le16 eh_magic;
99 __le16 eh_entries;
100 __le16 eh_max;
101 __le16 eh_depth;
102 __le32 eh_generation;
103};
104
105#define EXT4_EXT_MAGIC cpu_to_le16(0xf30a)
106
107#define EXT4_EXTENT_TAIL_OFFSET(hdr) \
108 (sizeof(struct ext4_extent_header) + \
109 (sizeof(struct ext4_extent) * le16_to_cpu((hdr)->eh_max)))
110
111static inline struct ext4_extent_tail *
112find_ext4_extent_tail(struct ext4_extent_header *eh)
113{
114 return (struct ext4_extent_tail *)(((void *)eh) +
115 EXT4_EXTENT_TAIL_OFFSET(eh));
116}
117
118
119
120
121
122
123struct ext4_ext_path {
124 ext4_fsblk_t p_block;
125 __u16 p_depth;
126 struct ext4_extent *p_ext;
127 struct ext4_extent_idx *p_idx;
128 struct ext4_extent_header *p_hdr;
129 struct buffer_head *p_bh;
130};
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153#define EXT_INIT_MAX_LEN (1UL << 15)
154#define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1)
155
156
157#define EXT_FIRST_EXTENT(__hdr__) \
158 ((struct ext4_extent *) (((char *) (__hdr__)) + \
159 sizeof(struct ext4_extent_header)))
160#define EXT_FIRST_INDEX(__hdr__) \
161 ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \
162 sizeof(struct ext4_extent_header)))
163#define EXT_HAS_FREE_INDEX(__path__) \
164 (le16_to_cpu((__path__)->p_hdr->eh_entries) \
165 < le16_to_cpu((__path__)->p_hdr->eh_max))
166#define EXT_LAST_EXTENT(__hdr__) \
167 (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
168#define EXT_LAST_INDEX(__hdr__) \
169 (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
170#define EXT_MAX_EXTENT(__hdr__) \
171 (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
172#define EXT_MAX_INDEX(__hdr__) \
173 (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
174
175static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
176{
177 return (struct ext4_extent_header *) EXT4_I(inode)->i_data;
178}
179
180static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
181{
182 return (struct ext4_extent_header *) bh->b_data;
183}
184
185static inline unsigned short ext_depth(struct inode *inode)
186{
187 return le16_to_cpu(ext_inode_hdr(inode)->eh_depth);
188}
189
190static inline void ext4_ext_mark_uninitialized(struct ext4_extent *ext)
191{
192
193 BUG_ON((le16_to_cpu(ext->ee_len) & ~EXT_INIT_MAX_LEN) == 0);
194 ext->ee_len |= cpu_to_le16(EXT_INIT_MAX_LEN);
195}
196
197static inline int ext4_ext_is_uninitialized(struct ext4_extent *ext)
198{
199
200 return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
201}
202
203static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
204{
205 return (le16_to_cpu(ext->ee_len) <= EXT_INIT_MAX_LEN ?
206 le16_to_cpu(ext->ee_len) :
207 (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
208}
209
210static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
211{
212 ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext));
213}
214
215
216
217
218
219static inline ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
220{
221 ext4_fsblk_t block;
222
223 block = le32_to_cpu(ex->ee_start_lo);
224 block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
225 return block;
226}
227
228
229
230
231
232static inline ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
233{
234 ext4_fsblk_t block;
235
236 block = le32_to_cpu(ix->ei_leaf_lo);
237 block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
238 return block;
239}
240
241
242
243
244
245
246static inline void ext4_ext_store_pblock(struct ext4_extent *ex,
247 ext4_fsblk_t pb)
248{
249 ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
250 ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
251 0xffff);
252}
253
254
255
256
257
258
259static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix,
260 ext4_fsblk_t pb)
261{
262 ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
263 ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
264 0xffff);
265}
266
267#define ext4_ext_dirty(handle, inode, path) \
268 __ext4_ext_dirty(__func__, __LINE__, (handle), (inode), (path))
269int __ext4_ext_dirty(const char *where, unsigned int line, handle_t *handle,
270 struct inode *inode, struct ext4_ext_path *path);
271
272#endif
273
274