aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/extents.c48
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;
2454out: 2492out: