diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 42c4c0c892ed..612c3d2c3824 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -99,7 +99,7 @@ static int ext4_ext_journal_restart(handle_t *handle, int needed) | |||
99 | if (handle->h_buffer_credits > needed) | 99 | if (handle->h_buffer_credits > needed) |
100 | return 0; | 100 | return 0; |
101 | err = ext4_journal_extend(handle, needed); | 101 | err = ext4_journal_extend(handle, needed); |
102 | if (err) | 102 | if (err <= 0) |
103 | return err; | 103 | return err; |
104 | return ext4_journal_restart(handle, needed); | 104 | return ext4_journal_restart(handle, needed); |
105 | } | 105 | } |
@@ -1441,7 +1441,7 @@ unsigned int ext4_ext_check_overlap(struct inode *inode, | |||
1441 | 1441 | ||
1442 | /* | 1442 | /* |
1443 | * get the next allocated block if the extent in the path | 1443 | * get the next allocated block if the extent in the path |
1444 | * is before the requested block(s) | 1444 | * is before the requested block(s) |
1445 | */ | 1445 | */ |
1446 | if (b2 < b1) { | 1446 | if (b2 < b1) { |
1447 | b2 = ext4_ext_next_allocated_block(path); | 1447 | b2 = ext4_ext_next_allocated_block(path); |
@@ -1910,9 +1910,13 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
1910 | BUG_ON(b != ex_ee_block + ex_ee_len - 1); | 1910 | BUG_ON(b != ex_ee_block + ex_ee_len - 1); |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | /* at present, extent can't cross block group: */ | 1913 | /* |
1914 | /* leaf + bitmap + group desc + sb + inode */ | 1914 | * 3 for leaf, sb, and inode plus 2 (bmap and group |
1915 | credits = 5; | 1915 | * descriptor) for each block group; assume two block |
1916 | * groups plus ex_ee_len/blocks_per_block_group for | ||
1917 | * the worst case | ||
1918 | */ | ||
1919 | credits = 7 + 2*(ex_ee_len/EXT4_BLOCKS_PER_GROUP(inode->i_sb)); | ||
1916 | if (ex == EXT_FIRST_EXTENT(eh)) { | 1920 | if (ex == EXT_FIRST_EXTENT(eh)) { |
1917 | correct_index = 1; | 1921 | correct_index = 1; |
1918 | credits += (ext_depth(inode)) + 1; | 1922 | credits += (ext_depth(inode)) + 1; |
@@ -2323,7 +2327,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2323 | unsigned int newdepth; | 2327 | unsigned int newdepth; |
2324 | /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */ | 2328 | /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */ |
2325 | if (allocated <= EXT4_EXT_ZERO_LEN) { | 2329 | if (allocated <= EXT4_EXT_ZERO_LEN) { |
2326 | /* Mark first half uninitialized. | 2330 | /* |
2331 | * iblock == ee_block is handled by the zerouout | ||
2332 | * at the beginning. | ||
2333 | * Mark first half uninitialized. | ||
2327 | * Mark second half initialized and zero out the | 2334 | * Mark second half initialized and zero out the |
2328 | * initialized extent | 2335 | * initialized extent |
2329 | */ | 2336 | */ |
@@ -2346,7 +2353,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2346 | ex->ee_len = orig_ex.ee_len; | 2353 | ex->ee_len = orig_ex.ee_len; |
2347 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2354 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2348 | ext4_ext_dirty(handle, inode, path + depth); | 2355 | ext4_ext_dirty(handle, inode, path + depth); |
2349 | /* zeroed the full extent */ | 2356 | /* blocks available from iblock */ |
2350 | return allocated; | 2357 | return allocated; |
2351 | 2358 | ||
2352 | } else if (err) | 2359 | } else if (err) |
@@ -2374,6 +2381,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2374 | err = PTR_ERR(path); | 2381 | err = PTR_ERR(path); |
2375 | return err; | 2382 | return err; |
2376 | } | 2383 | } |
2384 | /* get the second half extent details */ | ||
2377 | ex = path[depth].p_ext; | 2385 | ex = path[depth].p_ext; |
2378 | err = ext4_ext_get_access(handle, inode, | 2386 | err = ext4_ext_get_access(handle, inode, |
2379 | path + depth); | 2387 | path + depth); |
@@ -2403,6 +2411,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2403 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2411 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2404 | ext4_ext_dirty(handle, inode, path + depth); | 2412 | ext4_ext_dirty(handle, inode, path + depth); |
2405 | /* zeroed the full extent */ | 2413 | /* zeroed the full extent */ |
2414 | /* blocks available from iblock */ | ||
2406 | return allocated; | 2415 | return allocated; |
2407 | 2416 | ||
2408 | } else if (err) | 2417 | } else if (err) |
@@ -2418,23 +2427,22 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2418 | */ | 2427 | */ |
2419 | orig_ex.ee_len = cpu_to_le16(ee_len - | 2428 | orig_ex.ee_len = cpu_to_le16(ee_len - |
2420 | ext4_ext_get_actual_len(ex3)); | 2429 | ext4_ext_get_actual_len(ex3)); |
2421 | if (newdepth != depth) { | 2430 | depth = newdepth; |
2422 | depth = newdepth; | 2431 | ext4_ext_drop_refs(path); |
2423 | ext4_ext_drop_refs(path); | 2432 | path = ext4_ext_find_extent(inode, iblock, path); |
2424 | path = ext4_ext_find_extent(inode, iblock, path); | 2433 | if (IS_ERR(path)) { |
2425 | if (IS_ERR(path)) { | 2434 | err = PTR_ERR(path); |
2426 | err = PTR_ERR(path); | 2435 | goto out; |
2427 | goto out; | ||
2428 | } | ||
2429 | eh = path[depth].p_hdr; | ||
2430 | ex = path[depth].p_ext; | ||
2431 | if (ex2 != &newex) | ||
2432 | ex2 = ex; | ||
2433 | |||
2434 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
2435 | if (err) | ||
2436 | goto out; | ||
2437 | } | 2436 | } |
2437 | eh = path[depth].p_hdr; | ||
2438 | ex = path[depth].p_ext; | ||
2439 | if (ex2 != &newex) | ||
2440 | ex2 = ex; | ||
2441 | |||
2442 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
2443 | if (err) | ||
2444 | goto out; | ||
2445 | |||
2438 | allocated = max_blocks; | 2446 | allocated = max_blocks; |
2439 | 2447 | ||
2440 | /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying | 2448 | /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying |
@@ -2452,6 +2460,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2452 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2460 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2453 | ext4_ext_dirty(handle, inode, path + depth); | 2461 | ext4_ext_dirty(handle, inode, path + depth); |
2454 | /* zero out the first half */ | 2462 | /* zero out the first half */ |
2463 | /* blocks available from iblock */ | ||
2455 | return allocated; | 2464 | return allocated; |
2456 | } | 2465 | } |
2457 | } | 2466 | } |