Merge tag 'for-6.9/io_uring-20240310' of git://git.kernel.dk/linux
[sfrench/cifs-2.6.git] / fs / open.c
index 0a73afe04d34b15ae14f9b3e5177ac206290f6da..a7d4bb2c725f1e9bdde176f769c3a52df0627ab9 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -154,49 +154,52 @@ COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length
 }
 #endif
 
-long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
+long do_ftruncate(struct file *file, loff_t length, int small)
 {
        struct inode *inode;
        struct dentry *dentry;
-       struct fd f;
        int error;
 
-       error = -EINVAL;
-       if (length < 0)
-               goto out;
-       error = -EBADF;
-       f = fdget(fd);
-       if (!f.file)
-               goto out;
-
        /* explicitly opened as large or we are on 64-bit box */
-       if (f.file->f_flags & O_LARGEFILE)
+       if (file->f_flags & O_LARGEFILE)
                small = 0;
 
-       dentry = f.file->f_path.dentry;
+       dentry = file->f_path.dentry;
        inode = dentry->d_inode;
-       error = -EINVAL;
-       if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE))
-               goto out_putf;
+       if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
+               return -EINVAL;
 
-       error = -EINVAL;
        /* Cannot ftruncate over 2^31 bytes without large file support */
        if (small && length > MAX_NON_LFS)
-               goto out_putf;
+               return -EINVAL;
 
-       error = -EPERM;
        /* Check IS_APPEND on real upper inode */
-       if (IS_APPEND(file_inode(f.file)))
-               goto out_putf;
+       if (IS_APPEND(file_inode(file)))
+               return -EPERM;
        sb_start_write(inode->i_sb);
-       error = security_file_truncate(f.file);
+       error = security_file_truncate(file);
        if (!error)
-               error = do_truncate(file_mnt_idmap(f.file), dentry, length,
-                                   ATTR_MTIME | ATTR_CTIME, f.file);
+               error = do_truncate(file_mnt_idmap(file), dentry, length,
+                                   ATTR_MTIME | ATTR_CTIME, file);
        sb_end_write(inode->i_sb);
-out_putf:
+
+       return error;
+}
+
+long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
+{
+       struct fd f;
+       int error;
+
+       if (length < 0)
+               return -EINVAL;
+       f = fdget(fd);
+       if (!f.file)
+               return -EBADF;
+
+       error = do_ftruncate(f.file, length, small);
+
        fdput(f);
-out:
        return error;
 }