]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ext4: factor out ext4_do_fallocate()
authorZhang Yi <yi.zhang@huawei.com>
Thu, 24 Jul 2025 02:57:13 +0000 (22:57 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Aug 2025 08:48:45 +0000 (09:48 +0100)
[ Upstream commit fd2f764826df5489b849a8937b5a093aae5b1816 ]

Now the real job of normal fallocate are open coded in ext4_fallocate(),
factor out a new helper ext4_do_fallocate() to do the real job, like
others functions (e.g. ext4_zero_range()) in ext4_fallocate() do, this
can make the code more clear, no functional changes.

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Link: https://patch.msgid.link/20241220011637.1157197-9-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Stable-dep-of: 29ec9bed2395 ("ext4: fix incorrect punch max_end")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ext4/extents.c

index 961e7b634401d0bf564d077045d29ad653f1c5af..eb58f7a1ab5aa22f91ab64a7771fd8af615abd96 100644 (file)
@@ -4690,6 +4690,58 @@ out:
        return ret;
 }
 
+static long ext4_do_fallocate(struct file *file, loff_t offset,
+                             loff_t len, int mode)
+{
+       struct inode *inode = file_inode(file);
+       loff_t end = offset + len;
+       loff_t new_size = 0;
+       ext4_lblk_t start_lblk, len_lblk;
+       int ret;
+
+       trace_ext4_fallocate_enter(inode, offset, len, mode);
+
+       start_lblk = offset >> inode->i_blkbits;
+       len_lblk = EXT4_MAX_BLOCKS(len, offset, inode->i_blkbits);
+
+       inode_lock(inode);
+
+       /* We only support preallocation for extent-based files only. */
+       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+           (end > inode->i_size || end > EXT4_I(inode)->i_disksize)) {
+               new_size = end;
+               ret = inode_newsize_ok(inode, new_size);
+               if (ret)
+                       goto out;
+       }
+
+       /* Wait all existing dio workers, newcomers will block on i_rwsem */
+       inode_dio_wait(inode);
+
+       ret = file_modified(file);
+       if (ret)
+               goto out;
+
+       ret = ext4_alloc_file_blocks(file, start_lblk, len_lblk, new_size,
+                                    EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT);
+       if (ret)
+               goto out;
+
+       if (file->f_flags & O_SYNC && EXT4_SB(inode->i_sb)->s_journal) {
+               ret = ext4_fc_commit(EXT4_SB(inode->i_sb)->s_journal,
+                                       EXT4_I(inode)->i_sync_tid);
+       }
+out:
+       inode_unlock(inode);
+       trace_ext4_fallocate_exit(inode, offset, len_lblk, ret);
+       return ret;
+}
+
 /*
  * preallocate space for a file. This implements ext4's fallocate file
  * operation, which gets called from sys_fallocate system call.
@@ -4700,12 +4752,7 @@ out:
 long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
 {
        struct inode *inode = file_inode(file);
-       loff_t new_size = 0;
-       unsigned int max_blocks;
-       int ret = 0;
-       int flags;
-       ext4_lblk_t lblk;
-       unsigned int blkbits = inode->i_blkbits;
+       int ret;
 
        /*
         * Encrypted inodes can't handle collapse range or insert
@@ -4727,71 +4774,19 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        ret = ext4_convert_inline_data(inode);
        inode_unlock(inode);
        if (ret)
-               goto exit;
+               return ret;
 
-       if (mode & FALLOC_FL_PUNCH_HOLE) {
+       if (mode & FALLOC_FL_PUNCH_HOLE)
                ret = ext4_punch_hole(file, offset, len);
-               goto exit;
-       }
-
-       if (mode & FALLOC_FL_COLLAPSE_RANGE) {
+       else if (mode & FALLOC_FL_COLLAPSE_RANGE)
                ret = ext4_collapse_range(file, offset, len);
-               goto exit;
-       }
-
-       if (mode & FALLOC_FL_INSERT_RANGE) {
+       else if (mode & FALLOC_FL_INSERT_RANGE)
                ret = ext4_insert_range(file, offset, len);
-               goto exit;
-       }
-
-       if (mode & FALLOC_FL_ZERO_RANGE) {
+       else if (mode & FALLOC_FL_ZERO_RANGE)
                ret = ext4_zero_range(file, offset, len, mode);
-               goto exit;
-       }
-       trace_ext4_fallocate_enter(inode, offset, len, mode);
-       lblk = offset >> blkbits;
-
-       max_blocks = EXT4_MAX_BLOCKS(len, offset, blkbits);
-       flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT;
-
-       inode_lock(inode);
-
-       /*
-        * We only support preallocation for extent-based files only
-        */
-       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
-               ret = -EOPNOTSUPP;
-               goto out;
-       }
-
-       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
-           (offset + len > inode->i_size ||
-            offset + len > EXT4_I(inode)->i_disksize)) {
-               new_size = offset + len;
-               ret = inode_newsize_ok(inode, new_size);
-               if (ret)
-                       goto out;
-       }
-
-       /* Wait all existing dio workers, newcomers will block on i_rwsem */
-       inode_dio_wait(inode);
-
-       ret = file_modified(file);
-       if (ret)
-               goto out;
-
-       ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags);
-       if (ret)
-               goto out;
+       else
+               ret = ext4_do_fallocate(file, offset, len, mode);
 
-       if (file->f_flags & O_SYNC && EXT4_SB(inode->i_sb)->s_journal) {
-               ret = ext4_fc_commit(EXT4_SB(inode->i_sb)->s_journal,
-                                       EXT4_I(inode)->i_sync_tid);
-       }
-out:
-       inode_unlock(inode);
-       trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
-exit:
        return ret;
 }