Sync ext4 encryption as of commit dffd334e4d7134
[ext4-patch-queue.git] / fix-loss-of-delalloc-extent-info-in-ext4_zero_range
blobe58920f82713f96ba37e057832405c783de5ba6d
1 ext4: fix loss of delalloc extent info in ext4_zero_range()
3 From: Eric Whitney <enwlinux@gmail.com>
5 In ext4_zero_range(), removing a file's entire block range from the
6 extent status tree removes all records of that file's delalloc extents.
7 The delalloc accounting code uses this information, and its loss can
8 then lead to accounting errors and kernel warnings at writeback time and
9 subsequent file system damage.  This is most noticeable on bigalloc
10 file systems where code in ext4_ext_map_blocks() handles cases where
11 delalloc extents share clusters with a newly allocated extent.
13 Because we're not deleting a block range and are correctly updating the
14 status of its associated extent, there is no need to remove anything
15 from the extent status tree.
17 When this patch is combined with an unrelated bug fix for
18 ext4_zero_range(), kernel warnings and e2fsck errors reported during
19 xfstests runs on bigalloc filesystems are greatly reduced without
20 introducing regressions on other xfstests-bld test scenarios.
22 Signed-off-by: Eric Whitney <enwlinux@gmail.com>
23 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
24 ---
25  fs/ext4/extents.c | 13 -------------
26  1 file changed, 13 deletions(-)
28 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
29 index bed4308..c187cc3 100644
30 --- a/fs/ext4/extents.c
31 +++ b/fs/ext4/extents.c
32 @@ -4847,19 +4847,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
33                                              flags, mode);
34                 if (ret)
35                         goto out_dio;
36 -               /*
37 -                * Remove entire range from the extent status tree.
38 -                *
39 -                * ext4_es_remove_extent(inode, lblk, max_blocks) is
40 -                * NOT sufficient.  I'm not sure why this is the case,
41 -                * but let's be conservative and remove the extent
42 -                * status tree for the entire inode.  There should be
43 -                * no outstanding delalloc extents thanks to the
44 -                * filemap_write_and_wait_range() call above.
45 -                */
46 -               ret = ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
47 -               if (ret)
48 -                       goto out_dio;
49         }
50         if (!partial_begin && !partial_end)
51                 goto out_dio;
52 -- 
53 2.1.0