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#define EXT4_MAX_EXTENT_DEPTH 5
107
108#define EXT4_EXTENT_TAIL_OFFSET(hdr) \
109 (sizeof(struct ext4_extent_header) + \
110 (sizeof(struct ext4_extent) * le16_to_cpu((hdr)->eh_max)))
111
112static inline struct ext4_extent_tail *
113find_ext4_extent_tail(struct ext4_extent_header *eh)
114{
115 return (struct ext4_extent_tail *)(((void *)eh) +
116 EXT4_EXTENT_TAIL_OFFSET(eh));
117}
118
119
120
121
122
123
124struct ext4_ext_path {
125 ext4_fsblk_t p_block;
126 __u16 p_depth;
127 struct ext4_extent *p_ext;
128 struct ext4_extent_idx *p_idx;
129 struct ext4_extent_header *p_hdr;
130 struct buffer_head *p_bh;
131};
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154#define EXT_INIT_MAX_LEN (1UL << 15)
155#define EXT_UNWRITTEN_MAX_LEN (EXT_INIT_MAX_LEN - 1)
156
157
158#define EXT_FIRST_EXTENT(__hdr__) \
159 ((struct ext4_extent *) (((char *) (__hdr__)) + \
160 sizeof(struct ext4_extent_header)))
161#define EXT_FIRST_INDEX(__hdr__) \
162 ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \
163 sizeof(struct ext4_extent_header)))
164#define EXT_HAS_FREE_INDEX(__path__) \
165 (le16_to_cpu((__path__)->p_hdr->eh_entries) \
166 < le16_to_cpu((__path__)->p_hdr->eh_max))
167#define EXT_LAST_EXTENT(__hdr__) \
168 (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
169#define EXT_LAST_INDEX(__hdr__) \
170 (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
171#define EXT_MAX_EXTENT(__hdr__) \
172 (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
173#define EXT_MAX_INDEX(__hdr__) \
174 (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
175
176static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
177{
178 return (struct ext4_extent_header *) EXT4_I(inode)->i_data;
179}
180
181static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
182{
183 return (struct ext4_extent_header *) bh->b_data;
184}
185
186static inline unsigned short ext_depth(struct inode *inode)
187{
188 return le16_to_cpu(ext_inode_hdr(inode)->eh_depth);
189}
190
191static inline void ext4_ext_mark_unwritten(struct ext4_extent *ext)
192{
193
194 BUG_ON((le16_to_cpu(ext->ee_len) & ~EXT_INIT_MAX_LEN) == 0);
195 ext->ee_len |= cpu_to_le16(EXT_INIT_MAX_LEN);
196}
197
198static inline int ext4_ext_is_unwritten(struct ext4_extent *ext)
199{
200
201 return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
202}
203
204static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
205{
206 return (le16_to_cpu(ext->ee_len) <= EXT_INIT_MAX_LEN ?
207 le16_to_cpu(ext->ee_len) :
208 (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
209}
210
211static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
212{
213 ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext));
214}
215
216
217
218
219
220static inline ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
221{
222 ext4_fsblk_t block;
223
224 block = le32_to_cpu(ex->ee_start_lo);
225 block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
226 return block;
227}
228
229
230
231
232
233static inline ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
234{
235 ext4_fsblk_t block;
236
237 block = le32_to_cpu(ix->ei_leaf_lo);
238 block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
239 return block;
240}
241
242
243
244
245
246
247static inline void ext4_ext_store_pblock(struct ext4_extent *ex,
248 ext4_fsblk_t pb)
249{
250 ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
251 ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
252 0xffff);
253}
254
255
256
257
258
259
260static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix,
261 ext4_fsblk_t pb)
262{
263 ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
264 ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
265 0xffff);
266}
267
268#define ext4_ext_dirty(handle, inode, path) \
269 __ext4_ext_dirty(__func__, __LINE__, (handle), (inode), (path))
270int __ext4_ext_dirty(const char *where, unsigned int line, handle_t *handle,
271 struct inode *inode, struct ext4_ext_path *path);
272
273#endif
274
275