Blame view

fs/ext4/ext4_extents.h 9.23 KB
a86c61812   Alex Tomas   [PATCH] ext3: add...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
   * Written by Alex Tomas <alex@clusterfs.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public Licens
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
   */
3dcf54515   Christoph Hellwig   ext4: move header...
18
19
  #ifndef _EXT4_EXTENTS
  #define _EXT4_EXTENTS
a86c61812   Alex Tomas   [PATCH] ext3: add...
20

3dcf54515   Christoph Hellwig   ext4: move header...
21
  #include "ext4.h"
a86c61812   Alex Tomas   [PATCH] ext3: add...
22
23
  
  /*
bbf2f9fb1   Robert P. J. Day   Fix misspellings ...
24
   * With AGGRESSIVE_TEST defined, the capacity of index/leaf blocks
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
25
26
27
   * becomes very small, so index split, in-depth growing and
   * other hard changes happen much more often.
   * This is for debug purposes only.
a86c61812   Alex Tomas   [PATCH] ext3: add...
28
   */
bbf2f9fb1   Robert P. J. Day   Fix misspellings ...
29
  #define AGGRESSIVE_TEST_
a86c61812   Alex Tomas   [PATCH] ext3: add...
30
31
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
32
33
34
   * With EXTENTS_STATS defined, the number of blocks and extents
   * are collected in the truncate path. They'll be shown at
   * umount time.
a86c61812   Alex Tomas   [PATCH] ext3: add...
35
36
37
38
   */
  #define EXTENTS_STATS__
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
39
40
   * If CHECK_BINSEARCH is defined, then the results of the binary search
   * will also be checked by linear search.
a86c61812   Alex Tomas   [PATCH] ext3: add...
41
42
43
44
   */
  #define CHECK_BINSEARCH__
  
  /*
553f90089   Mingming   ext4: Show unwrit...
45
   * Turn on EXT_DEBUG to get lots of info about extents operations.
a86c61812   Alex Tomas   [PATCH] ext3: add...
46
47
48
49
50
51
52
53
54
   */
  #define EXT_DEBUG__
  #ifdef EXT_DEBUG
  #define ext_debug(a...)		printk(a)
  #else
  #define ext_debug(a...)
  #endif
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
55
56
   * If EXT_STATS is defined then stats numbers are collected.
   * These number will be displayed at umount time.
a86c61812   Alex Tomas   [PATCH] ext3: add...
57
58
59
60
61
   */
  #define EXT_STATS_
  
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
62
63
64
   * ext4_inode has i_block array (60 bytes total).
   * The first 12 bytes store ext4_extent_header;
   * the remainder stores an array of ext4_extent.
a86c61812   Alex Tomas   [PATCH] ext3: add...
65
66
67
   */
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
68
69
   * This is the extent on-disk structure.
   * It's used at the bottom of the tree.
a86c61812   Alex Tomas   [PATCH] ext3: add...
70
71
72
73
74
   */
  struct ext4_extent {
  	__le32	ee_block;	/* first logical block extent covers */
  	__le16	ee_len;		/* number of blocks covered by extent */
  	__le16	ee_start_hi;	/* high 16 bits of physical block */
b377611d1   Aneesh Kumar K.V   ext4: Convert ext...
75
  	__le32	ee_start_lo;	/* low 32 bits of physical block */
a86c61812   Alex Tomas   [PATCH] ext3: add...
76
77
78
  };
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
79
80
   * This is index on-disk structure.
   * It's used at all the levels except the bottom.
a86c61812   Alex Tomas   [PATCH] ext3: add...
81
82
83
   */
  struct ext4_extent_idx {
  	__le32	ei_block;	/* index covers logical blocks from 'block' */
d8dd0b454   Aneesh Kumar K.V   ext4: Convert ext...
84
  	__le32	ei_leaf_lo;	/* pointer to the physical block of the next *
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
85
  				 * level. leaf or next index could be there */
a86c61812   Alex Tomas   [PATCH] ext3: add...
86
87
88
89
90
  	__le16	ei_leaf_hi;	/* high 16 bits of physical block */
  	__u16	ei_unused;
  };
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
91
   * Each block (leaves and indexes), even inode-stored has header.
a86c61812   Alex Tomas   [PATCH] ext3: add...
92
93
94
95
96
   */
  struct ext4_extent_header {
  	__le16	eh_magic;	/* probably will support different formats */
  	__le16	eh_entries;	/* number of valid entries */
  	__le16	eh_max;		/* capacity of store in entries */
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
97
  	__le16	eh_depth;	/* has tree real underlying blocks? */
a86c61812   Alex Tomas   [PATCH] ext3: add...
98
99
100
101
102
103
  	__le32	eh_generation;	/* generation of the tree */
  };
  
  #define EXT4_EXT_MAGIC		cpu_to_le16(0xf30a)
  
  /*
d0d856e8b   Randy Dunlap   [PATCH] ext4: cle...
104
105
106
   * Array of ext4_ext_path contains path to some extent.
   * Creation/lookup routines use it for traversal/splitting/etc.
   * Truncate uses it to simulate recursive walking.
a86c61812   Alex Tomas   [PATCH] ext3: add...
107
108
   */
  struct ext4_ext_path {
f65e6fba1   Alex Tomas   [PATCH] ext4: 48b...
109
  	ext4_fsblk_t			p_block;
a86c61812   Alex Tomas   [PATCH] ext3: add...
110
111
112
113
114
115
116
117
118
119
  	__u16				p_depth;
  	struct ext4_extent		*p_ext;
  	struct ext4_extent_idx		*p_idx;
  	struct ext4_extent_header	*p_hdr;
  	struct buffer_head		*p_bh;
  };
  
  /*
   * structure for external API
   */
6873fa0de   Eric Sandeen   Hook ext4 to the ...
120
121
122
123
124
125
  /*
   * to be called by ext4_ext_walk_space()
   * negative retcode - error
   * positive retcode - signal for ext4_ext_walk_space(), see below
   * callback must return valid extent (passed or newly created)
   */
c03f8aa9a   Lukas Czerner   ext4: use FIEMAP_...
126
  typedef int (*ext_prepare_callback)(struct inode *, ext4_lblk_t,
6873fa0de   Eric Sandeen   Hook ext4 to the ...
127
128
129
130
131
132
  					struct ext4_ext_cache *,
  					struct ext4_extent *, void *);
  
  #define EXT_CONTINUE   0
  #define EXT_BREAK      1
  #define EXT_REPEAT     2
a86c61812   Alex Tomas   [PATCH] ext3: add...
133

f17722f91   Lukas Czerner   ext4: Fix max fil...
134
135
136
137
138
  /*
   * Maximum number of logical blocks in a file; ext4_extent's ee_block is
   * __le32.
   */
  #define EXT_MAX_BLOCKS	0xffffffff
a86c61812   Alex Tomas   [PATCH] ext3: add...
139

749269fac   Amit Arora   Change on-disk fo...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  /*
   * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
   * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
   * MSB of ee_len field in the extent datastructure to signify if this
   * particular extent is an initialized extent or an uninitialized (i.e.
   * preallocated).
   * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
   * uninitialized extent.
   * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
   * uninitialized one. In other words, if MSB of ee_len is set, it is an
   * uninitialized extent with only one special scenario when ee_len = 0x8000.
   * In this case we can not have an uninitialized extent of zero length and
   * thus we make it as a special case of initialized extent with 0x8000 length.
   * This way we get better extent-to-group alignment for initialized extents.
   * Hence, the maximum number of blocks we can have in an *initialized*
   * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
   */
  #define EXT_INIT_MAX_LEN	(1UL << 15)
  #define EXT_UNINIT_MAX_LEN	(EXT_INIT_MAX_LEN - 1)
471d4011a   Suparna Bhattacharya   [PATCH] ext4: uni...
159

a86c61812   Alex Tomas   [PATCH] ext3: add...
160
161
162
163
164
165
166
167
  
  #define EXT_FIRST_EXTENT(__hdr__) \
  	((struct ext4_extent *) (((char *) (__hdr__)) +		\
  				 sizeof(struct ext4_extent_header)))
  #define EXT_FIRST_INDEX(__hdr__) \
  	((struct ext4_extent_idx *) (((char *) (__hdr__)) +	\
  				     sizeof(struct ext4_extent_header)))
  #define EXT_HAS_FREE_INDEX(__path__) \
8c55e2041   Dave Kleikamp   EXT4: Fix whitespace
168
169
  	(le16_to_cpu((__path__)->p_hdr->eh_entries) \
  				     < le16_to_cpu((__path__)->p_hdr->eh_max))
a86c61812   Alex Tomas   [PATCH] ext3: add...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  #define EXT_LAST_EXTENT(__hdr__) \
  	(EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
  #define EXT_LAST_INDEX(__hdr__) \
  	(EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
  #define EXT_MAX_EXTENT(__hdr__) \
  	(EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
  #define EXT_MAX_INDEX(__hdr__) \
  	(EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
  
  static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
  {
  	return (struct ext4_extent_header *) EXT4_I(inode)->i_data;
  }
  
  static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
  {
  	return (struct ext4_extent_header *) bh->b_data;
  }
  
  static inline unsigned short ext_depth(struct inode *inode)
  {
  	return le16_to_cpu(ext_inode_hdr(inode)->eh_depth);
  }
a86c61812   Alex Tomas   [PATCH] ext3: add...
193
194
195
  static inline void
  ext4_ext_invalidate_cache(struct inode *inode)
  {
b05e6ae58   Theodore Ts'o   ext4: drop ec_typ...
196
  	EXT4_I(inode)->i_cached_extent.ec_len = 0;
a86c61812   Alex Tomas   [PATCH] ext3: add...
197
  }
a2df2a634   Amit Arora   fallocate support...
198
199
  static inline void ext4_ext_mark_uninitialized(struct ext4_extent *ext)
  {
749269fac   Amit Arora   Change on-disk fo...
200
201
202
  	/* We can not have an uninitialized extent of zero length! */
  	BUG_ON((le16_to_cpu(ext->ee_len) & ~EXT_INIT_MAX_LEN) == 0);
  	ext->ee_len |= cpu_to_le16(EXT_INIT_MAX_LEN);
a2df2a634   Amit Arora   fallocate support...
203
204
205
206
  }
  
  static inline int ext4_ext_is_uninitialized(struct ext4_extent *ext)
  {
749269fac   Amit Arora   Change on-disk fo...
207
208
  	/* Extent with ee_len of 0x8000 is treated as an initialized extent */
  	return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
a2df2a634   Amit Arora   fallocate support...
209
210
211
212
  }
  
  static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
  {
749269fac   Amit Arora   Change on-disk fo...
213
214
215
  	return (le16_to_cpu(ext->ee_len) <= EXT_INIT_MAX_LEN ?
  		le16_to_cpu(ext->ee_len) :
  		(le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
a2df2a634   Amit Arora   fallocate support...
216
  }
0031462b5   Mingming Cao   ext4: Split unini...
217
218
219
220
  static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
  {
  	ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext));
  }
bf89d16f6   Theodore Ts'o   ext4: rename {ext...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  /*
   * ext4_ext_pblock:
   * combine low and high parts of physical block number into ext4_fsblk_t
   */
  static inline ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
  {
  	ext4_fsblk_t block;
  
  	block = le32_to_cpu(ex->ee_start_lo);
  	block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
  	return block;
  }
  
  /*
   * ext4_idx_pblock:
   * combine low and high parts of a leaf physical block number into ext4_fsblk_t
   */
  static inline ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
  {
  	ext4_fsblk_t block;
  
  	block = le32_to_cpu(ix->ei_leaf_lo);
  	block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
  	return block;
  }
  
  /*
   * ext4_ext_store_pblock:
   * stores a large physical block number into an extent struct,
   * breaking it into parts
   */
  static inline void ext4_ext_store_pblock(struct ext4_extent *ex,
  					 ext4_fsblk_t pb)
  {
  	ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
  	ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
  				      0xffff);
  }
  
  /*
   * ext4_idx_store_pblock:
   * stores a large physical block number into an index struct,
   * breaking it into parts
   */
  static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix,
  					 ext4_fsblk_t pb)
  {
  	ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
  	ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
  				     0xffff);
  }
9d0be5023   Theodore Ts'o   ext4: Calculate m...
272
  extern int ext4_ext_calc_metadata_amount(struct inode *inode,
01f49d0b9   Theodore Ts'o   ext4: use ext4_lb...
273
  					 ext4_lblk_t lblocks);
a86c61812   Alex Tomas   [PATCH] ext3: add...
274
  extern int ext4_extent_tree_init(handle_t *, struct inode *);
ee12b6306   Mingming Cao   ext4: journal cre...
275
276
277
  extern int ext4_ext_calc_credits_for_single_extent(struct inode *inode,
  						   int num,
  						   struct ext4_ext_path *path);
748de6736   Akira Fujita   ext4: online defr...
278
279
280
  extern int ext4_can_extents_be_merged(struct inode *inode,
  				      struct ext4_extent *ex1,
  				      struct ext4_extent *ex2);
0031462b5   Mingming Cao   ext4: Split unini...
281
  extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *, int);
725d26d3f   Aneesh Kumar K.V   ext4: Introduce e...
282
283
  extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
  							struct ext4_ext_path *);
b35905c16   Aneesh Kumar K.V   ext4: Fix memory ...
284
  extern void ext4_ext_drop_refs(struct ext4_ext_path *);
7a262f7c6   Aneesh Kumar K.V   ext4: Validate ex...
285
  extern int ext4_ext_check_inode(struct inode *inode);
7b415bf60   Aditya Kali   ext4: Fix bigallo...
286
287
  extern int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk,
  				      int search_hint_reverse);
3dcf54515   Christoph Hellwig   ext4: move header...
288
  #endif /* _EXT4_EXTENTS */
a86c61812   Alex Tomas   [PATCH] ext3: add...
289