]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ext4: factor out ext4_do_fallocate()
authorZhang Yi <yi.zhang@huawei.com>
Fri, 20 Dec 2024 01:16:35 +0000 (09:16 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 10 Feb 2025 12:48:25 +0000 (07:48 -0500)
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>
fs/ext4/extents.c

index be44dd7aacdb6ccf81420d1775db5fb87b43032d..a8bbbf8a9950ac349cc48536adece34e38f1ba0a 100644 (file)
@@ -4689,6 +4689,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.
@@ -4699,12 +4751,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
@@ -4726,71 +4773,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;
 }