add patch fix-zeroing-of-page-during-writeback
[ext4-patch-queue.git] / remove-i_size-check-from-do_fallocate
blob31fb847cb1d4ff2475325a99561989dd6e6e13e1
1 fs: move falloc collapse range check into the filesystem methods
3 From: Lukas Czerner <lczerner@redhat.com>
5 Currently in do_fallocate in collapse range case we're checking
6 whether offset + len is not bigger than i_size.  However there is
7 nothing which would prevent i_size from changing so the check is
8 pointless.  It should be done in the file system itself and the file
9 system needs to make sure that i_size is not going to change.  The
10 i_size check for the other fallocate modes are also done in the
11 filesystems.
13 As it is now we can easily crash the kernel by having two processes
14 doing truncate and fallocate collapse range at the same time.  This
15 can be reproduced on ext4 and it is theoretically possible on xfs even
16 though I was not able to trigger it with this simple test.
18 This commit removes the check from do_fallocate and adds it to the
19 file system.
21 Signed-off-by: Lukas Czerner <lczerner@redhat.com>
22 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
23 Acked-by: Dave Chinner <david@fromorbit.com>
24 Reviewed-by: Christoph Hellwig <hch@lst.de>
25 ---
26 v2: Update description and change subject as suggested by hch
28  fs/ext4/extents.c | 11 +++++++++--
29  fs/open.c         |  8 --------
30  fs/xfs/xfs_file.c | 10 +++++++++-
31  3 files changed, 18 insertions(+), 11 deletions(-)
33 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
34 index 0177150..ff823b7 100644
35 --- a/fs/ext4/extents.c
36 +++ b/fs/ext4/extents.c
37 @@ -5364,8 +5364,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
38         loff_t new_size;
39         int ret;
41 -       BUG_ON(offset + len > i_size_read(inode));
43         /* Collapse range works only on fs block size aligned offsets. */
44         if (offset & (EXT4_BLOCK_SIZE(sb) - 1) ||
45             len & (EXT4_BLOCK_SIZE(sb) - 1))
46 @@ -5387,6 +5385,15 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
47         /* Take mutex lock */
48         mutex_lock(&inode->i_mutex);
50 +       /*
51 +        * There is no need to overlap collapse range with EOF, in which case
52 +        * it is effectively a truncate operation
53 +        */
54 +       if (offset + len >= i_size_read(inode)) {
55 +               ret = -EINVAL;
56 +               goto out_mutex;
57 +       }
59         if (IS_SWAPFILE(inode)) {
60                 ret = -ETXTBSY;
61                 goto out_mutex;
62 diff --git a/fs/open.c b/fs/open.c
63 index fe48b2f..bd42341 100644
64 --- a/fs/open.c
65 +++ b/fs/open.c
66 @@ -284,14 +284,6 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
67         if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
68                 return -EFBIG;
70 -       /*
71 -        * There is no need to overlap collapse range with EOF, in which case
72 -        * it is effectively a truncate operation
73 -        */
74 -       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
75 -           (offset + len >= i_size_read(inode)))
76 -               return -EINVAL;
78         if (!file->f_op->fallocate)
79                 return -EOPNOTSUPP;
81 diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
82 index 003c005..4ba0ae9 100644
83 --- a/fs/xfs/xfs_file.c
84 +++ b/fs/xfs/xfs_file.c
85 @@ -840,7 +840,15 @@ xfs_file_fallocate(
86                         goto out_unlock;
87                 }
89 -               ASSERT(offset + len < i_size_read(inode));
90 +               /*
91 +                * There is no need to overlap collapse range with EOF,
92 +                * in which case it is effectively a truncate operation
93 +                */
94 +               if (offset + len >= i_size_read(inode)) {
95 +                       error = -EINVAL;
96 +                       goto out_unlock;
97 +               }
99                 new_size = i_size_read(inode) - len;
101                 error = xfs_collapse_file_space(ip, offset, len);
102 -- 
103 1.8.3.1
106 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
107 the body of a message to majordomo@vger.kernel.org
108 More majordomo info at  http://vger.kernel.org/majordomo-info.html