OSDN Git Service

compat: move FS_IOC_RESVSP_32 handling to fs/ioctl.c
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 21 Apr 2019 23:24:03 +0000 (19:24 -0400)
committerArnd Bergmann <arnd@arndb.de>
Wed, 23 Oct 2019 15:15:57 +0000 (17:15 +0200)
... and lose the ridiculous games with compat_alloc_user_space()
there.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
fs/compat_ioctl.c
fs/ioctl.c
include/linux/falloc.h

index 46e8a8f..ce995d4 100644 (file)
@@ -467,41 +467,6 @@ static int rtc_ioctl(struct file *file,
        return -ENOIOCTLCMD;
 }
 
-/* on ia32 l_start is on a 32-bit boundary */
-#if defined(CONFIG_X86_64)
-struct space_resv_32 {
-       __s16           l_type;
-       __s16           l_whence;
-       __s64           l_start __attribute__((packed));
-                       /* len == 0 means until end of file */
-       __s64           l_len __attribute__((packed));
-       __s32           l_sysid;
-       __u32           l_pid;
-       __s32           l_pad[4];       /* reserve area */
-};
-
-#define FS_IOC_RESVSP_32               _IOW ('X', 40, struct space_resv_32)
-#define FS_IOC_RESVSP64_32     _IOW ('X', 42, struct space_resv_32)
-
-/* just account for different alignment */
-static int compat_ioctl_preallocate(struct file *file,
-                       struct space_resv_32    __user *p32)
-{
-       struct space_resv       __user *p = compat_alloc_user_space(sizeof(*p));
-
-       if (copy_in_user(&p->l_type,    &p32->l_type,   sizeof(s16)) ||
-           copy_in_user(&p->l_whence,  &p32->l_whence, sizeof(s16)) ||
-           copy_in_user(&p->l_start,   &p32->l_start,  sizeof(s64)) ||
-           copy_in_user(&p->l_len,     &p32->l_len,    sizeof(s64)) ||
-           copy_in_user(&p->l_sysid,   &p32->l_sysid,  sizeof(s32)) ||
-           copy_in_user(&p->l_pid,     &p32->l_pid,    sizeof(u32)) ||
-           copy_in_user(&p->l_pad,     &p32->l_pad,    4*sizeof(u32)))
-               return -EFAULT;
-
-       return ioctl_preallocate(file, p);
-}
-#endif
-
 /*
  * simple reversible transform to make our table more evenly
  * distributed after sorting.
index e14bd85..812061b 100644 (file)
@@ -491,6 +491,35 @@ int ioctl_preallocate(struct file *filp, void __user *argp)
        return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
 }
 
+/* on ia32 l_start is on a 32-bit boundary */
+#if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
+/* just account for different alignment */
+int compat_ioctl_preallocate(struct file *file,
+                               struct space_resv_32 __user *argp)
+{
+       struct inode *inode = file_inode(file);
+       struct space_resv_32 sr;
+
+       if (copy_from_user(&sr, argp, sizeof(sr)))
+               return -EFAULT;
+
+       switch (sr.l_whence) {
+       case SEEK_SET:
+               break;
+       case SEEK_CUR:
+               sr.l_start += file->f_pos;
+               break;
+       case SEEK_END:
+               sr.l_start += i_size_read(inode);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return vfs_fallocate(file, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
+}
+#endif
+
 static int file_ioctl(struct file *filp, unsigned int cmd,
                unsigned long arg)
 {
index 674d59f..fc61fdb 100644 (file)
@@ -29,4 +29,24 @@ struct space_resv {
                                         FALLOC_FL_INSERT_RANGE |       \
                                         FALLOC_FL_UNSHARE_RANGE)
 
+/* on ia32 l_start is on a 32-bit boundary */
+#if defined(CONFIG_X86_64)
+struct space_resv_32 {
+       __s16           l_type;
+       __s16           l_whence;
+       __s64           l_start __attribute__((packed));
+                       /* len == 0 means until end of file */
+       __s64           l_len __attribute__((packed));
+       __s32           l_sysid;
+       __u32           l_pid;
+       __s32           l_pad[4];       /* reserve area */
+};
+
+#define FS_IOC_RESVSP_32               _IOW ('X', 40, struct space_resv_32)
+#define FS_IOC_RESVSP64_32     _IOW ('X', 42, struct space_resv_32)
+
+int compat_ioctl_preallocate(struct file *, struct space_resv_32 __user *);
+
+#endif
+
 #endif /* _FALLOC_H_ */