diff options
-rw-r--r-- | fs/ext4/extents.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7733e2943367..c7c42c9c7bf7 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2266,7 +2266,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2266 | ex->ee_len = orig_ex.ee_len; | 2266 | ex->ee_len = orig_ex.ee_len; |
2267 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2267 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2268 | ext4_ext_dirty(handle, inode, path + depth); | 2268 | ext4_ext_dirty(handle, inode, path + depth); |
2269 | return le16_to_cpu(ex->ee_len); | 2269 | /* zeroed the full extent */ |
2270 | return allocated; | ||
2270 | } | 2271 | } |
2271 | 2272 | ||
2272 | /* ex1: ee_block to iblock - 1 : uninitialized */ | 2273 | /* ex1: ee_block to iblock - 1 : uninitialized */ |
@@ -2311,11 +2312,45 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2311 | ex->ee_len = orig_ex.ee_len; | 2312 | ex->ee_len = orig_ex.ee_len; |
2312 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2313 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2313 | ext4_ext_dirty(handle, inode, path + depth); | 2314 | ext4_ext_dirty(handle, inode, path + depth); |
2314 | return le16_to_cpu(ex->ee_len); | 2315 | /* zeroed the full extent */ |
2316 | return allocated; | ||
2315 | 2317 | ||
2316 | } else if (err) | 2318 | } else if (err) |
2317 | goto fix_extent_len; | 2319 | goto fix_extent_len; |
2318 | 2320 | ||
2321 | /* | ||
2322 | * We need to zero out the second half because | ||
2323 | * an fallocate request can update file size and | ||
2324 | * converting the second half to initialized extent | ||
2325 | * implies that we can leak some junk data to user | ||
2326 | * space. | ||
2327 | */ | ||
2328 | err = ext4_ext_zeroout(inode, ex3); | ||
2329 | if (err) { | ||
2330 | /* | ||
2331 | * We should actually mark the | ||
2332 | * second half as uninit and return error | ||
2333 | * Insert would have changed the extent | ||
2334 | */ | ||
2335 | depth = ext_depth(inode); | ||
2336 | ext4_ext_drop_refs(path); | ||
2337 | path = ext4_ext_find_extent(inode, | ||
2338 | iblock, path); | ||
2339 | if (IS_ERR(path)) { | ||
2340 | err = PTR_ERR(path); | ||
2341 | return err; | ||
2342 | } | ||
2343 | ex = path[depth].p_ext; | ||
2344 | err = ext4_ext_get_access(handle, inode, | ||
2345 | path + depth); | ||
2346 | if (err) | ||
2347 | return err; | ||
2348 | ext4_ext_mark_uninitialized(ex); | ||
2349 | ext4_ext_dirty(handle, inode, path + depth); | ||
2350 | return err; | ||
2351 | } | ||
2352 | |||
2353 | /* zeroed the second half */ | ||
2319 | return allocated; | 2354 | return allocated; |
2320 | } | 2355 | } |
2321 | ex3 = &newex; | 2356 | ex3 = &newex; |
@@ -2333,7 +2368,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2333 | ex->ee_len = orig_ex.ee_len; | 2368 | ex->ee_len = orig_ex.ee_len; |
2334 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2369 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2335 | ext4_ext_dirty(handle, inode, path + depth); | 2370 | ext4_ext_dirty(handle, inode, path + depth); |
2336 | return le16_to_cpu(ex->ee_len); | 2371 | /* zeroed the full extent */ |
2372 | return allocated; | ||
2337 | 2373 | ||
2338 | } else if (err) | 2374 | } else if (err) |
2339 | goto fix_extent_len; | 2375 | goto fix_extent_len; |
@@ -2381,7 +2417,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2381 | ex->ee_len = orig_ex.ee_len; | 2417 | ex->ee_len = orig_ex.ee_len; |
2382 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2418 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2383 | ext4_ext_dirty(handle, inode, path + depth); | 2419 | ext4_ext_dirty(handle, inode, path + depth); |
2384 | return le16_to_cpu(ex->ee_len); | 2420 | /* zero out the first half */ |
2421 | return allocated; | ||
2385 | } | 2422 | } |
2386 | } | 2423 | } |
2387 | /* | 2424 | /* |
@@ -2448,7 +2485,8 @@ insert: | |||
2448 | ex->ee_len = orig_ex.ee_len; | 2485 | ex->ee_len = orig_ex.ee_len; |
2449 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2486 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); |
2450 | ext4_ext_dirty(handle, inode, path + depth); | 2487 | ext4_ext_dirty(handle, inode, path + depth); |
2451 | return le16_to_cpu(ex->ee_len); | 2488 | /* zero out the first half */ |
2489 | return allocated; | ||
2452 | } else if (err) | 2490 | } else if (err) |
2453 | goto fix_extent_len; | 2491 | goto fix_extent_len; |
2454 | out: | 2492 | out: |