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 *
find_ext4_extent_tail(struct ext4_extent_header * eh)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 
ext_inode_hdr(struct inode * inode)124 static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
125 {
126 	return get_ext4_header(inode);
127 }
128 
ext_block_hdr(struct buffer_head * bh)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 
ext_depth(struct inode * inode)134 static inline unsigned short ext_depth(struct inode *inode)
135 {
136 	return ext_inode_hdr(inode)->eh_depth;
137 }
138 
ext4_ext_mark_uninitialized(struct ext4_extent * ext)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 
ext4_ext_is_uninitialized(struct ext4_extent * ext)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 
ext4_ext_get_actual_len(struct ext4_extent * ext)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 
ext4_ext_mark_initialized(struct ext4_extent * ext)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 
ext4_ext_mark_unwritten(struct ext4_extent * ext)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 
ext4_ext_is_unwritten(struct ext4_extent * ext)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  */
ext4_ext_pblock(struct ext4_extent * ex)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  */
ext4_idx_pblock(struct ext4_extent_idx * ix)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  */
ext4_ext_store_pblock(struct ext4_extent * ex,ext4_fsblk_t pb)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  */
ext4_idx_store_pblock(struct ext4_extent_idx * ix,ext4_fsblk_t pb)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 
ext_to_block(EXT4_EXTENT * extent)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 
idx_to_block(EXT4_EXTENT_IDX * idx)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_truncate(void *icb, struct inode *inode, unsigned long start);
256 
257 #endif	/* _LINUX_EXT4_EXT */
258