ReactOS 0.4.15-dev-8227-g32d615f
ext4_ext.h
Go to the documentation of this file.
1#ifndef _LINUX_EXT4_EXT
2#define _LINUX_EXT4_EXT
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 */
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 */
19typedef 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 */
30typedef 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 */
36}__attribute__ ((__packed__)) EXT4_EXTENT_IDX;
37
38/*
39 * Each block (leaves and indexes), even inode-stored has header.
40 */
41typedef 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
57static inline struct ext4_extent_tail *
59{
60 return (struct ext4_extent_tail *)(((char *)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 */
70{
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
124static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
125{
126 return get_ext4_header(inode);
127}
128
129static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
130{
131 return (struct ext4_extent_header *)bh->b_data;
132}
133
134static inline unsigned short ext_depth(struct inode *inode)
135{
136 return ext_inode_hdr(inode)->eh_depth;
137}
138
139static 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
145static 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
152{
153 return (ext->ee_len <= EXT_INIT_MAX_LEN
154 ? ext->ee_len
155 : (ext->ee_len - EXT_INIT_MAX_LEN));
156}
157
158static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
159{
161}
162
163static 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
169static 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 */
180{
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 */
193{
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 */
206static 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 */
218static 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
230static inline uint64_t ext_to_block(EXT4_EXTENT *extent)
231{
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
240static inline uint64_t idx_to_block(EXT4_EXTENT_IDX *idx)
241{
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
251int 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);
254int ext4_ext_tree_init(void *icb, handle_t *handle, struct inode *inode);
255int ext4_ext_truncate(void *icb, struct inode *inode, unsigned long start);
256
257#endif /* _LINUX_EXT4_EXT */
unsigned short int uint16_t
Definition: acefiex.h:54
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
unsigned int idx
Definition: utils.c:41
static const WCHAR *const ext[]
Definition: module.c:53
unsigned long long ext4_fsblk_t
Definition: ext3_fs_i.h:27
static void ext4_ext_mark_unwritten(struct ext4_extent *ext)
Definition: ext4_ext.h:163
#define EXT4_EXTENT_TAIL_OFFSET(hdr)
Definition: ext4_ext.h:53
int ext4_ext_tree_init(void *icb, handle_t *handle, struct inode *inode)
static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
Definition: ext4_ext.h:218
static struct ext4_extent_header * ext_inode_hdr(struct inode *inode)
Definition: ext4_ext.h:124
static int ext4_ext_is_unwritten(struct ext4_extent *ext)
Definition: ext4_ext.h:169
#define get_ext4_header(i)
Definition: ext4_ext.h:51
static void ext4_ext_mark_initialized(struct ext4_extent *ext)
Definition: ext4_ext.h:158
struct ext4_ext_path __attribute__
static void ext4_ext_mark_uninitialized(struct ext4_extent *ext)
Definition: ext4_ext.h:139
#define EXT_INIT_MAX_LEN
Definition: ext4_ext.h:101
static struct ext4_extent_header * ext_block_hdr(struct buffer_head *bh)
Definition: ext4_ext.h:129
static uint64_t ext_to_block(EXT4_EXTENT *extent)
Definition: ext4_ext.h:230
static struct ext4_extent_tail * find_ext4_extent_tail(struct ext4_extent_header *eh)
Definition: ext4_ext.h:58
int ext4_ext_truncate(void *icb, struct inode *inode, unsigned long start)
static uint64_t idx_to_block(EXT4_EXTENT_IDX *idx)
Definition: ext4_ext.h:240
static int ext4_ext_is_uninitialized(struct ext4_extent *ext)
Definition: ext4_ext.h:145
static ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
Definition: ext4_ext.h:192
static unsigned short ext_depth(struct inode *inode)
Definition: ext4_ext.h:134
static ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
Definition: ext4_ext.h:179
static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
Definition: ext4_ext.h:206
static uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext)
Definition: ext4_ext.h:151
int ext4_ext_get_blocks(void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t iblock, unsigned long max_blocks, struct buffer_head *bh_result, int create, int flags)
GLuint start
Definition: gl.h:1545
GLbitfield flags
Definition: glext.h:7161
static const struct access_res create[16]
Definition: package.c:7644
#define uint32_t
Definition: nsiface.idl:61
#define uint64_t
Definition: nsiface.idl:62
#define uint16_t
Definition: nsiface.idl:60
char * b_data
Definition: module.h:735
Definition: comerr.c:44
int p_maxdepth
Definition: ext4_ext.h:73
struct ext4_extent_header * p_hdr
Definition: ext4_ext.h:76
struct buffer_head * p_bh
Definition: ext4_ext.h:77
struct ext4_extent_idx * p_idx
Definition: ext4_ext.h:75
struct ext4_extent * p_ext
Definition: ext4_ext.h:74
ext4_fsblk_t p_block
Definition: ext4_ext.h:71
uint32_t eh_generation
Definition: ext4_ext.h:46
uint16_t eh_depth
Definition: ext4_ext.h:45
uint16_t eh_max
Definition: ext4_ext.h:44
uint16_t eh_magic
Definition: ext4_ext.h:42
uint16_t eh_entries
Definition: ext4_ext.h:43
uint16_t ei_leaf_hi
Definition: ext4_ext.h:34
uint16_t ei_unused
Definition: ext4_ext.h:35
uint32_t ei_leaf_lo
Definition: ext4_ext.h:32
uint32_t ei_block
Definition: ext4_ext.h:31
uint32_t et_checksum
Definition: ext4_ext.h:12
uint16_t ee_len
Definition: ext4_ext.h:21
uint32_t ee_block
Definition: ext4_ext.h:20
uint16_t ee_start_hi
Definition: ext4_ext.h:22
uint32_t ee_start_lo
Definition: ext4_ext.h:23
Definition: fs.h:78
static unsigned int block
Definition: xmlmemory.c:101