]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.18.85/ext4-fix-interaction-between-i_size-fallocate-and-delalloc-after-a-crash.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.18.85 / ext4-fix-interaction-between-i_size-fallocate-and-delalloc-after-a-crash.patch
CommitLineData
d992de84
GKH
1From 51e3ae81ec58e95f10a98ef3dd6d7bce5d8e35a2 Mon Sep 17 00:00:00 2001
2From: Theodore Ts'o <tytso@mit.edu>
3Date: Fri, 6 Oct 2017 23:09:55 -0400
4Subject: ext4: fix interaction between i_size, fallocate, and delalloc after a crash
5
6From: Theodore Ts'o <tytso@mit.edu>
7
8commit 51e3ae81ec58e95f10a98ef3dd6d7bce5d8e35a2 upstream.
9
10If there are pending writes subject to delayed allocation, then i_size
11will show size after the writes have completed, while i_disksize
12contains the value of i_size on the disk (since the writes have not
13been persisted to disk).
14
15If fallocate(2) is called with the FALLOC_FL_KEEP_SIZE flag, either
16with or without the FALLOC_FL_ZERO_RANGE flag set, and the new size
17after the fallocate(2) is between i_size and i_disksize, then after a
18crash, if a journal commit has resulted in the changes made by the
19fallocate() call to be persisted after a crash, but the delayed
20allocation write has not resolved itself, i_size would not be updated,
21and this would cause the following e2fsck complaint:
22
23Inode 12, end of extent exceeds allowed value
24 (logical block 33, physical block 33441, len 7)
25
26This can only take place on a sparse file, where the fallocate(2) call
27is allocating blocks in a range which is before a pending delayed
28allocation write which is extending i_size. Since this situation is
29quite rare, and the window in which the crash must take place is
30typically < 30 seconds, in practice this condition will rarely happen.
31
32Nevertheless, it can be triggered in testing, and in particular by
33xfstests generic/456.
34
35Signed-off-by: Theodore Ts'o <tytso@mit.edu>
36Reported-by: Amir Goldstein <amir73il@gmail.com>
37Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38
39---
40 fs/ext4/extents.c | 6 ++++--
41 1 file changed, 4 insertions(+), 2 deletions(-)
42
43--- a/fs/ext4/extents.c
44+++ b/fs/ext4/extents.c
45@@ -4807,7 +4807,8 @@ static long ext4_zero_range(struct file
46 }
47
48 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
49- offset + len > i_size_read(inode)) {
50+ (offset + len > i_size_read(inode) ||
51+ offset + len > EXT4_I(inode)->i_disksize)) {
52 new_size = offset + len;
53 ret = inode_newsize_ok(inode, new_size);
54 if (ret)
55@@ -4951,7 +4952,8 @@ long ext4_fallocate(struct file *file, i
56 }
57
58 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
59- offset + len > i_size_read(inode)) {
60+ (offset + len > i_size_read(inode) ||
61+ offset + len > EXT4_I(inode)->i_disksize)) {
62 new_size = offset + len;
63 ret = inode_newsize_ok(inode, new_size);
64 if (ret)