[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191009191044.308087-6-arnd@arndb.de>
Date: Wed, 9 Oct 2019 21:10:06 +0200
From: Arnd Bergmann <arnd@...db.de>
To: Al Viro <viro@...iv.linux.org.uk>
Cc: linux-kernel@...r.kernel.org, y2038@...ts.linaro.org,
linux-fsdevel@...r.kernel.org, Arnd Bergmann <arnd@...db.de>
Subject: [PATCH v6 06/43] compat_sys_ioctl(): make parallel to do_vfs_ioctl()
From: Al Viro <viro@...iv.linux.org.uk>
Handle ioctls that might be handled without reaching ->ioctl() in
native case on the top level there. The counterpart of vfs_ioctl()
(i.e. calling ->unlock_ioctl(), etc.) left as-is; eventually
that would turn simply into the call of ->compat_ioctl(), but
that'll take more work. Once that is done, we can move the
remains of compat_sys_ioctl() into fs/ioctl.c and finally bury
fs/compat_ioctl.c.
Signed-off-by: Al Viro <viro@...iv.linux.org.uk>
Signed-off-by: Arnd Bergmann <arnd@...db.de>
---
fs/compat_ioctl.c | 63 +++++++++++++++++++++--------------------------
1 file changed, 28 insertions(+), 35 deletions(-)
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index ce995d4fa1f4..ecbd5254b547 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -487,19 +487,7 @@ static unsigned int ioctl_pointer[] = {
/* compatible ioctls first */
/* Little t */
COMPATIBLE_IOCTL(TIOCOUTQ)
-/* Little f */
-COMPATIBLE_IOCTL(FIOCLEX)
-COMPATIBLE_IOCTL(FIONCLEX)
-COMPATIBLE_IOCTL(FIOASYNC)
-COMPATIBLE_IOCTL(FIONBIO)
-COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
-COMPATIBLE_IOCTL(FS_IOC_FIEMAP)
-/* 0x00 */
-COMPATIBLE_IOCTL(FIBMAP)
-COMPATIBLE_IOCTL(FIGETBSZ)
/* 'X' - originally XFS but some now in the VFS */
-COMPATIBLE_IOCTL(FIFREEZE)
-COMPATIBLE_IOCTL(FITHAW)
COMPATIBLE_IOCTL(FITRIM)
#ifdef CONFIG_BLOCK
/* Big S */
@@ -971,19 +959,39 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
if (error)
goto out_fput;
- /*
- * To allow the compat_ioctl handlers to be self contained
- * we need to check the common ioctls here first.
- * Just handle them with the standard handlers below.
- */
switch (cmd) {
+ /* these are never seen by ->ioctl(), no argument or int argument */
case FIOCLEX:
case FIONCLEX:
+ case FIFREEZE:
+ case FITHAW:
+ case FICLONE:
+ goto do_ioctl;
+ /* these are never seen by ->ioctl(), pointer argument */
case FIONBIO:
case FIOASYNC:
case FIOQSIZE:
- break;
-
+ case FS_IOC_FIEMAP:
+ case FIGETBSZ:
+ case FICLONERANGE:
+ case FIDEDUPERANGE:
+ goto found_handler;
+ /*
+ * The next group is the stuff handled inside file_ioctl().
+ * For regular files these never reach ->ioctl(); for
+ * devices, sockets, etc. they do and one (FIONREAD) is
+ * even accepted in some cases. In all those cases
+ * argument has the same type, so we can handle these
+ * here, shunting them towards do_vfs_ioctl().
+ * ->compat_ioctl() will never see any of those.
+ */
+ /* pointer argument, never actually handled by ->ioctl() */
+ case FIBMAP:
+ goto found_handler;
+ /* handled by some ->ioctl(); always a pointer to int */
+ case FIONREAD:
+ goto found_handler;
+ /* these two get messy on amd64 due to alignment differences */
#if defined(CONFIG_X86_64)
case FS_IOC_RESVSP_32:
case FS_IOC_RESVSP64_32:
@@ -992,23 +1000,8 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
#else
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
- error = ioctl_preallocate(f.file, compat_ptr(arg));
- goto out_fput;
-#endif
-
- case FICLONE:
- goto do_ioctl;
- case FICLONERANGE:
- case FIDEDUPERANGE:
- case FS_IOC_FIEMAP:
- case FIGETBSZ:
goto found_handler;
-
- case FIBMAP:
- case FIONREAD:
- if (S_ISREG(file_inode(f.file)->i_mode))
- break;
- /*FALL THROUGH*/
+#endif
default:
if (f.file->f_op->compat_ioctl) {
--
2.20.0
Powered by blists - more mailing lists