aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-08-28 10:40:33 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-08-28 10:40:33 -0400
commit55ad63bf3a30936aced50f13452735c2f58b234c (patch)
tree13733cfa690c83a0a75d8d38489e3cace096f9f9 /fs/ext4/extents.c
parenta36b44988cef1fc007535107013571fa691a2d7f (diff)
ext4: fix extent sanity checking code with AGGRESSIVE_TEST
The extents sanity-checking code depends on the ext4_ext_space_*() functions returning the maximum alloable size for eh_max; however, when the debugging #ifdef AGGRESSIVE_TEST is enabled to test the extent tree handling code, this prevents a normally created ext4 filesystem from being mounted with the errors: Aug 26 15:43:50 bsd086 kernel: [ 96.070277] EXT4-fs error (device sda8): ext4_ext_check_inode: bad header/extent in inode #8: too large eh_max - magic f30a, entries 1, max 4(3), depth 0(0) Aug 26 15:43:50 bsd086 kernel: [ 96.070526] EXT4-fs (sda8): no journal found Bug reported by Akira Fujita. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c60
1 files changed, 34 insertions, 26 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 8c20caf4aa5c..7a3832577923 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -229,57 +229,65 @@ ext4_ext_new_meta_block(handle_t *handle, struct inode *inode,
229 return newblock; 229 return newblock;
230} 230}
231 231
232static int ext4_ext_space_block(struct inode *inode) 232static inline int ext4_ext_space_block(struct inode *inode, int check)
233{ 233{
234 int size; 234 int size;
235 235
236 size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) 236 size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
237 / sizeof(struct ext4_extent); 237 / sizeof(struct ext4_extent);
238 if (!check) {
238#ifdef AGGRESSIVE_TEST 239#ifdef AGGRESSIVE_TEST
239 if (size > 6) 240 if (size > 6)
240 size = 6; 241 size = 6;
241#endif 242#endif
243 }
242 return size; 244 return size;
243} 245}
244 246
245static int ext4_ext_space_block_idx(struct inode *inode) 247static inline int ext4_ext_space_block_idx(struct inode *inode, int check)
246{ 248{
247 int size; 249 int size;
248 250
249 size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) 251 size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
250 / sizeof(struct ext4_extent_idx); 252 / sizeof(struct ext4_extent_idx);
253 if (!check) {
251#ifdef AGGRESSIVE_TEST 254#ifdef AGGRESSIVE_TEST
252 if (size > 5) 255 if (size > 5)
253 size = 5; 256 size = 5;
254#endif 257#endif
258 }
255 return size; 259 return size;
256} 260}
257 261
258static int ext4_ext_space_root(struct inode *inode) 262static inline int ext4_ext_space_root(struct inode *inode, int check)
259{ 263{
260 int size; 264 int size;
261 265
262 size = sizeof(EXT4_I(inode)->i_data); 266 size = sizeof(EXT4_I(inode)->i_data);
263 size -= sizeof(struct ext4_extent_header); 267 size -= sizeof(struct ext4_extent_header);
264 size /= sizeof(struct ext4_extent); 268 size /= sizeof(struct ext4_extent);
269 if (!check) {
265#ifdef AGGRESSIVE_TEST 270#ifdef AGGRESSIVE_TEST
266 if (size > 3) 271 if (size > 3)
267 size = 3; 272 size = 3;
268#endif 273#endif
274 }
269 return size; 275 return size;
270} 276}
271 277
272static int ext4_ext_space_root_idx(struct inode *inode) 278static inline int ext4_ext_space_root_idx(struct inode *inode, int check)
273{ 279{
274 int size; 280 int size;
275 281
276 size = sizeof(EXT4_I(inode)->i_data); 282 size = sizeof(EXT4_I(inode)->i_data);
277 size -= sizeof(struct ext4_extent_header); 283 size -= sizeof(struct ext4_extent_header);
278 size /= sizeof(struct ext4_extent_idx); 284 size /= sizeof(struct ext4_extent_idx);
285 if (!check) {
279#ifdef AGGRESSIVE_TEST 286#ifdef AGGRESSIVE_TEST
280 if (size > 4) 287 if (size > 4)
281 size = 4; 288 size = 4;
282#endif 289#endif
290 }
283 return size; 291 return size;
284} 292}
285 293
@@ -293,9 +301,9 @@ int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks)
293 int lcap, icap, rcap, leafs, idxs, num; 301 int lcap, icap, rcap, leafs, idxs, num;
294 int newextents = blocks; 302 int newextents = blocks;
295 303
296 rcap = ext4_ext_space_root_idx(inode); 304 rcap = ext4_ext_space_root_idx(inode, 0);
297 lcap = ext4_ext_space_block(inode); 305 lcap = ext4_ext_space_block(inode, 0);
298 icap = ext4_ext_space_block_idx(inode); 306 icap = ext4_ext_space_block_idx(inode, 0);
299 307
300 /* number of new leaf blocks needed */ 308 /* number of new leaf blocks needed */
301 num = leafs = (newextents + lcap - 1) / lcap; 309 num = leafs = (newextents + lcap - 1) / lcap;
@@ -320,14 +328,14 @@ ext4_ext_max_entries(struct inode *inode, int depth)
320 328
321 if (depth == ext_depth(inode)) { 329 if (depth == ext_depth(inode)) {
322 if (depth == 0) 330 if (depth == 0)
323 max = ext4_ext_space_root(inode); 331 max = ext4_ext_space_root(inode, 1);
324 else 332 else
325 max = ext4_ext_space_root_idx(inode); 333 max = ext4_ext_space_root_idx(inode, 1);
326 } else { 334 } else {
327 if (depth == 0) 335 if (depth == 0)
328 max = ext4_ext_space_block(inode); 336 max = ext4_ext_space_block(inode, 1);
329 else 337 else
330 max = ext4_ext_space_block_idx(inode); 338 max = ext4_ext_space_block_idx(inode, 1);
331 } 339 }
332 340
333 return max; 341 return max;
@@ -626,7 +634,7 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
626 eh->eh_depth = 0; 634 eh->eh_depth = 0;
627 eh->eh_entries = 0; 635 eh->eh_entries = 0;
628 eh->eh_magic = EXT4_EXT_MAGIC; 636 eh->eh_magic = EXT4_EXT_MAGIC;
629 eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode)); 637 eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode, 0));
630 ext4_mark_inode_dirty(handle, inode); 638 ext4_mark_inode_dirty(handle, inode);
631 ext4_ext_invalidate_cache(inode); 639 ext4_ext_invalidate_cache(inode);
632 return 0; 640 return 0;
@@ -851,7 +859,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
851 859
852 neh = ext_block_hdr(bh); 860 neh = ext_block_hdr(bh);
853 neh->eh_entries = 0; 861 neh->eh_entries = 0;
854 neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode)); 862 neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode, 0));
855 neh->eh_magic = EXT4_EXT_MAGIC; 863 neh->eh_magic = EXT4_EXT_MAGIC;
856 neh->eh_depth = 0; 864 neh->eh_depth = 0;
857 ex = EXT_FIRST_EXTENT(neh); 865 ex = EXT_FIRST_EXTENT(neh);
@@ -927,7 +935,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
927 neh = ext_block_hdr(bh); 935 neh = ext_block_hdr(bh);
928 neh->eh_entries = cpu_to_le16(1); 936 neh->eh_entries = cpu_to_le16(1);
929 neh->eh_magic = EXT4_EXT_MAGIC; 937 neh->eh_magic = EXT4_EXT_MAGIC;
930 neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode)); 938 neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode, 0));
931 neh->eh_depth = cpu_to_le16(depth - i); 939 neh->eh_depth = cpu_to_le16(depth - i);
932 fidx = EXT_FIRST_INDEX(neh); 940 fidx = EXT_FIRST_INDEX(neh);
933 fidx->ei_block = border; 941 fidx->ei_block = border;
@@ -1052,9 +1060,9 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1052 /* old root could have indexes or leaves 1060 /* old root could have indexes or leaves
1053 * so calculate e_max right way */ 1061 * so calculate e_max right way */
1054 if (ext_depth(inode)) 1062 if (ext_depth(inode))
1055 neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode)); 1063 neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode, 0));
1056 else 1064 else
1057 neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode)); 1065 neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode, 0));
1058 neh->eh_magic = EXT4_EXT_MAGIC; 1066 neh->eh_magic = EXT4_EXT_MAGIC;
1059 set_buffer_uptodate(bh); 1067 set_buffer_uptodate(bh);
1060 unlock_buffer(bh); 1068 unlock_buffer(bh);
@@ -1069,7 +1077,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1069 goto out; 1077 goto out;
1070 1078
1071 curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; 1079 curp->p_hdr->eh_magic = EXT4_EXT_MAGIC;
1072 curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode)); 1080 curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode, 0));
1073 curp->p_hdr->eh_entries = cpu_to_le16(1); 1081 curp->p_hdr->eh_entries = cpu_to_le16(1);
1074 curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); 1082 curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
1075 1083
@@ -2348,7 +2356,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
2348 if (err == 0) { 2356 if (err == 0) {
2349 ext_inode_hdr(inode)->eh_depth = 0; 2357 ext_inode_hdr(inode)->eh_depth = 0;
2350 ext_inode_hdr(inode)->eh_max = 2358 ext_inode_hdr(inode)->eh_max =
2351 cpu_to_le16(ext4_ext_space_root(inode)); 2359 cpu_to_le16(ext4_ext_space_root(inode, 0));
2352 err = ext4_ext_dirty(handle, inode, path); 2360 err = ext4_ext_dirty(handle, inode, path);
2353 } 2361 }
2354 } 2362 }