aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2011-10-25 05:35:05 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-10-25 05:35:05 -0400
commit750c9c47a5f9daa88333ac435a1afe4d4b428230 (patch)
tree5782bce0abf292317f0f8a176c23d1dca822a985 /fs/ext4/extents.c
parent1939dd84b3f52e9c8d1b46dffae2058f16a3ff6a (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/extents.c')
-rw-r--r--fs/ext4/extents.c103
1 files changed, 12 insertions, 91 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 385ebb43533..d0e3f333d3f 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--;