ReactOS  0.4.14-dev-77-gd9e7c48
ext4_ext.h
Go to the documentation of this file.
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  */
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 */
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 *
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 {
72  int p_depth;
74  struct ext4_extent *p_ext;
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 
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  */
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  */
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_truncate(void *icb, struct inode *inode, unsigned long start);
256 
257 #endif /* _LINUX_EXT4_EXT */
static unsigned int block
Definition: xmlmemory.c:118
uint16_t eh_depth
Definition: ext4_ext.h:45
Definition: comerr.c:44
uint16_t ei_leaf_hi
Definition: ext4_ext.h:34
static int ext4_ext_is_uninitialized(struct ext4_extent *ext)
Definition: ext4_ext.h:145
uint32_t ee_start_lo
Definition: ext4_ext.h:23
static uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext)
Definition: ext4_ext.h:151
int p_maxdepth
Definition: ext4_ext.h:73
uint32_t ei_block
Definition: ext4_ext.h:31
static uint64_t idx_to_block(EXT4_EXTENT_IDX *idx)
Definition: ext4_ext.h:240
unsigned short int uint16_t
Definition: acefiex.h:54
#define uint16_t
Definition: nsiface.idl:60
uint16_t ee_start_hi
Definition: ext4_ext.h:22
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)
unsigned long long ext4_fsblk_t
Definition: ext3_fs_i.h:27
Definition: fs.h:78
int ext4_ext_tree_init(void *icb, handle_t *handle, struct inode *inode)
uint32_t ei_leaf_lo
Definition: ext4_ext.h:32
static struct ext4_extent_tail * find_ext4_extent_tail(struct ext4_extent_header *eh)
Definition: ext4_ext.h:58
static struct ext4_extent_header * ext_block_hdr(struct buffer_head *bh)
Definition: ext4_ext.h:129
unsigned int idx
Definition: utils.c:41
static void ext4_ext_mark_unwritten(struct ext4_extent *ext)
Definition: ext4_ext.h:163
uint32_t et_checksum
Definition: ext4_ext.h:12
char ext[3]
Definition: mkdosfs.c:358
static ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
Definition: ext4_ext.h:192
static ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
Definition: ext4_ext.h:179
struct ext4_ext_path __attribute__
Definition: log2.h:38
static unsigned short ext_depth(struct inode *inode)
Definition: ext4_ext.h:134
uint16_t ee_len
Definition: ext4_ext.h:21
GLbitfield flags
Definition: glext.h:7161
int ext4_ext_truncate(void *icb, struct inode *inode, unsigned long start)
static void ext4_ext_mark_initialized(struct ext4_extent *ext)
Definition: ext4_ext.h:158
#define EXT4_EXTENT_TAIL_OFFSET(hdr)
Definition: ext4_ext.h:53
static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
Definition: ext4_ext.h:206
uint16_t ei_unused
Definition: ext4_ext.h:35
static void ext4_ext_mark_uninitialized(struct ext4_extent *ext)
Definition: ext4_ext.h:139
#define get_ext4_header(i)
Definition: ext4_ext.h:51
static struct ext4_extent_header * ext_inode_hdr(struct inode *inode)
Definition: ext4_ext.h:124
char * b_data
Definition: module.h:725
#define uint64_t
Definition: nsiface.idl:62
uint16_t eh_entries
Definition: ext4_ext.h:43
static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
Definition: ext4_ext.h:218
UINT64 uint64_t
Definition: types.h:77
struct ext4_extent_idx * p_idx
Definition: ext4_ext.h:75
GLuint start
Definition: gl.h:1545
uint32_t ee_block
Definition: ext4_ext.h:20
uint16_t eh_magic
Definition: ext4_ext.h:42
struct buffer_head * p_bh
Definition: ext4_ext.h:77
struct ext4_extent_header * p_hdr
Definition: ext4_ext.h:76
UINT32 uint32_t
Definition: types.h:75
uint32_t eh_generation
Definition: ext4_ext.h:46
ext4_fsblk_t p_block
Definition: ext4_ext.h:71
static uint64_t ext_to_block(EXT4_EXTENT *extent)
Definition: ext4_ext.h:230
#define EXT_INIT_MAX_LEN
Definition: ext4_ext.h:101
#define uint32_t
Definition: nsiface.idl:61
uint16_t eh_max
Definition: ext4_ext.h:44
struct ext4_extent * p_ext
Definition: ext4_ext.h:74
static const struct access_res create[16]
Definition: package.c:7720
static int ext4_ext_is_unwritten(struct ext4_extent *ext)
Definition: ext4_ext.h:169