diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2011-10-25 05:35:05 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-10-25 05:35:05 -0400 |
commit | 750c9c47a5f9daa88333ac435a1afe4d4b428230 (patch) | |
tree | 5782bce0abf292317f0f8a176c23d1dca822a985 /fs/ext4 | |
parent | 1939dd84b3f52e9c8d1b46dffae2058f16a3ff6a (diff) |
ext4: remove messy logic from ext4_ext_rm_leaf
- Both callers(truncate and punch_hole) already aligned left end point
so we no longer need split logic here.
- Remove dead duplicated code.
- Call ext4_ext_dirty only after we have updated eh_entries, otherwise
we'll loose entries update. Regression caused by d583fb87a3ff0
266'th testcase in xfstests (http://patchwork.ozlabs.org/patch/120872)
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 103 |
1 files changed, 12 insertions, 91 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 385ebb435332..d0e3f333d3f0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2311,13 +2311,12 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2311 | int err = 0, correct_index = 0; | 2311 | int err = 0, correct_index = 0; |
2312 | int depth = ext_depth(inode), credits; | 2312 | int depth = ext_depth(inode), credits; |
2313 | struct ext4_extent_header *eh; | 2313 | struct ext4_extent_header *eh; |
2314 | ext4_lblk_t a, b, block; | 2314 | ext4_lblk_t a, b; |
2315 | unsigned num; | 2315 | unsigned num; |
2316 | ext4_lblk_t ex_ee_block; | 2316 | ext4_lblk_t ex_ee_block; |
2317 | unsigned short ex_ee_len; | 2317 | unsigned short ex_ee_len; |
2318 | unsigned uninitialized = 0; | 2318 | unsigned uninitialized = 0; |
2319 | struct ext4_extent *ex; | 2319 | struct ext4_extent *ex; |
2320 | struct ext4_map_blocks map; | ||
2321 | 2320 | ||
2322 | /* the header must be checked already in ext4_ext_remove_space() */ | 2321 | /* the header must be checked already in ext4_ext_remove_space() */ |
2323 | ext_debug("truncate since %u in leaf\n", start); | 2322 | ext_debug("truncate since %u in leaf\n", start); |
@@ -2360,86 +2359,18 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2360 | ex_ee_block = le32_to_cpu(ex->ee_block); | 2359 | ex_ee_block = le32_to_cpu(ex->ee_block); |
2361 | ex_ee_len = ext4_ext_get_actual_len(ex); | 2360 | ex_ee_len = ext4_ext_get_actual_len(ex); |
2362 | continue; | 2361 | continue; |
2363 | } else if (a != ex_ee_block && | 2362 | } else if (b != ex_ee_block + ex_ee_len - 1) { |
2364 | b != ex_ee_block + ex_ee_len - 1) { | 2363 | EXT4_ERROR_INODE(inode," bad truncate %u:%u\n", |
2365 | /* | 2364 | start, end); |
2366 | * If this is a truncate, then this condition should | 2365 | err = -EIO; |
2367 | * never happen because at least one of the end points | 2366 | goto out; |
2368 | * needs to be on the edge of the extent. | ||
2369 | */ | ||
2370 | if (end == EXT_MAX_BLOCKS - 1) { | ||
2371 | ext_debug(" bad truncate %u:%u\n", | ||
2372 | start, end); | ||
2373 | block = 0; | ||
2374 | num = 0; | ||
2375 | err = -EIO; | ||
2376 | goto out; | ||
2377 | } | ||
2378 | /* | ||
2379 | * else this is a hole punch, so the extent needs to | ||
2380 | * be split since neither edge of the hole is on the | ||
2381 | * extent edge | ||
2382 | */ | ||
2383 | else{ | ||
2384 | map.m_pblk = ext4_ext_pblock(ex); | ||
2385 | map.m_lblk = ex_ee_block; | ||
2386 | map.m_len = b - ex_ee_block; | ||
2387 | |||
2388 | err = ext4_split_extent(handle, | ||
2389 | inode, path, &map, 0, | ||
2390 | EXT4_GET_BLOCKS_PUNCH_OUT_EXT | | ||
2391 | EXT4_GET_BLOCKS_PRE_IO); | ||
2392 | |||
2393 | if (err < 0) | ||
2394 | goto out; | ||
2395 | |||
2396 | ex_ee_len = ext4_ext_get_actual_len(ex); | ||
2397 | |||
2398 | b = ex_ee_block+ex_ee_len - 1 < end ? | ||
2399 | ex_ee_block+ex_ee_len - 1 : end; | ||
2400 | |||
2401 | /* Then remove tail of this extent */ | ||
2402 | block = ex_ee_block; | ||
2403 | num = a - block; | ||
2404 | } | ||
2405 | } else if (a != ex_ee_block) { | 2367 | } else if (a != ex_ee_block) { |
2406 | /* remove tail of the extent */ | 2368 | /* remove tail of the extent */ |
2407 | block = ex_ee_block; | 2369 | num = a - ex_ee_block; |
2408 | num = a - block; | ||
2409 | } else if (b != ex_ee_block + ex_ee_len - 1) { | ||
2410 | /* remove head of the extent */ | ||
2411 | block = b; | ||
2412 | num = ex_ee_block + ex_ee_len - b; | ||
2413 | |||
2414 | /* | ||
2415 | * If this is a truncate, this condition | ||
2416 | * should never happen | ||
2417 | */ | ||
2418 | if (end == EXT_MAX_BLOCKS - 1) { | ||
2419 | ext_debug(" bad truncate %u:%u\n", | ||
2420 | start, end); | ||
2421 | err = -EIO; | ||
2422 | goto out; | ||
2423 | } | ||
2424 | } else { | 2370 | } else { |
2425 | /* remove whole extent: excellent! */ | 2371 | /* remove whole extent: excellent! */ |
2426 | block = ex_ee_block; | ||
2427 | num = 0; | 2372 | num = 0; |
2428 | if (a != ex_ee_block) { | ||
2429 | ext_debug(" bad truncate %u:%u\n", | ||
2430 | start, end); | ||
2431 | err = -EIO; | ||
2432 | goto out; | ||
2433 | } | ||
2434 | |||
2435 | if (b != ex_ee_block + ex_ee_len - 1) { | ||
2436 | ext_debug(" bad truncate %u:%u\n", | ||
2437 | start, end); | ||
2438 | err = -EIO; | ||
2439 | goto out; | ||
2440 | } | ||
2441 | } | 2373 | } |
2442 | |||
2443 | /* | 2374 | /* |
2444 | * 3 for leaf, sb, and inode plus 2 (bmap and group | 2375 | * 3 for leaf, sb, and inode plus 2 (bmap and group |
2445 | * descriptor) for each block group; assume two block | 2376 | * descriptor) for each block group; assume two block |
@@ -2466,19 +2397,10 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2466 | if (err) | 2397 | if (err) |
2467 | goto out; | 2398 | goto out; |
2468 | 2399 | ||
2469 | if (num == 0) { | 2400 | if (num == 0) |
2470 | /* this extent is removed; mark slot entirely unused */ | 2401 | /* this extent is removed; mark slot entirely unused */ |
2471 | ext4_ext_store_pblock(ex, 0); | 2402 | ext4_ext_store_pblock(ex, 0); |
2472 | } else if (block != ex_ee_block) { | ||
2473 | /* | ||
2474 | * If this was a head removal, then we need to update | ||
2475 | * the physical block since it is now at a different | ||
2476 | * location | ||
2477 | */ | ||
2478 | ext4_ext_store_pblock(ex, ext4_ext_pblock(ex) + (b-a)); | ||
2479 | } | ||
2480 | 2403 | ||
2481 | ex->ee_block = cpu_to_le32(block); | ||
2482 | ex->ee_len = cpu_to_le16(num); | 2404 | ex->ee_len = cpu_to_le16(num); |
2483 | /* | 2405 | /* |
2484 | * Do not mark uninitialized if all the blocks in the | 2406 | * Do not mark uninitialized if all the blocks in the |
@@ -2486,11 +2408,6 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2486 | */ | 2408 | */ |
2487 | if (uninitialized && num) | 2409 | if (uninitialized && num) |
2488 | ext4_ext_mark_uninitialized(ex); | 2410 | ext4_ext_mark_uninitialized(ex); |
2489 | |||
2490 | err = ext4_ext_dirty(handle, inode, path + depth); | ||
2491 | if (err) | ||
2492 | goto out; | ||
2493 | |||
2494 | /* | 2411 | /* |
2495 | * If the extent was completely released, | 2412 | * If the extent was completely released, |
2496 | * we need to remove it from the leaf | 2413 | * we need to remove it from the leaf |
@@ -2513,6 +2430,10 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2513 | } else | 2430 | } else |
2514 | *partial_cluster = 0; | 2431 | *partial_cluster = 0; |
2515 | 2432 | ||
2433 | err = ext4_ext_dirty(handle, inode, path + depth); | ||
2434 | if (err) | ||
2435 | goto out; | ||
2436 | |||
2516 | ext_debug("new extent: %u:%u:%llu\n", block, num, | 2437 | ext_debug("new extent: %u:%u:%llu\n", block, num, |
2517 | ext4_ext_pblock(ex)); | 2438 | ext4_ext_pblock(ex)); |
2518 | ex--; | 2439 | ex--; |