Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a07ea0b authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

compat_ioctl: inline all conversion handlers



This makes all ioctl conversion handlers called from
a single switch statement, leaving only COMPATIBLE_IOCTL
and ULONG_IOCTL statements in the table. This is somewhat
more space efficient and also lets us simplify the
handling of the lookup table significantly.

before:
   text    data     bss     dec     hex filename
   7619   14024    2080   23723    5cab obj/fs/compat_ioctl.o
after:
   7567   13352    2080   22999    59d7 obj/fs/compat_ioctl.o

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 348c4b90
Loading
Loading
Loading
Loading
+81 −54
Original line number Diff line number Diff line
@@ -635,12 +635,6 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a
	return err;
}

static __used int
ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
{
	return -EINVAL;
}

static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
{
	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
@@ -1241,6 +1235,8 @@ COMPATIBLE_IOCTL(MTIOCTOP)
/* Socket level stuff */
COMPATIBLE_IOCTL(FIOQSIZE)
#ifdef CONFIG_BLOCK
/* loop */
IGNORE_IOCTL(LOOP_CLR_FD)
/* SG stuff */
COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
@@ -1699,35 +1695,6 @@ COMPATIBLE_IOCTL(JSIOCGAXES)
COMPATIBLE_IOCTL(JSIOCGBUTTONS)
COMPATIBLE_IOCTL(JSIOCGNAME(0))

/* now things that need handlers */
#ifdef CONFIG_BLOCK
HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans)
#endif
HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans)
#ifdef CONFIG_BLOCK
HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
#endif
#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
/* One SMB ioctl needs translations. */
#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
/* block stuff */
#ifdef CONFIG_BLOCK
/* loop */
IGNORE_IOCTL(LOOP_CLR_FD)
/* Raw devices */
HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
#endif
/* Serial */
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
#ifdef TIOCGLTC
COMPATIBLE_IOCTL(TIOCGLTC)
COMPATIBLE_IOCTL(TIOCSLTC)
@@ -1743,24 +1710,7 @@ COMPATIBLE_IOCTL(TIOCSTART)
COMPATIBLE_IOCTL(TIOCSTOP)
#endif
/* Usbdevfs */
HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
/* i2c */
HANDLE_IOCTL(I2C_FUNCS, w_long)
HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
/* Not implemented in the native kernel */
HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)

/* dvb */
HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette)

/* parport */
COMPATIBLE_IOCTL(LPTIME)
@@ -1774,7 +1724,6 @@ COMPATIBLE_IOCTL(LPGETSTATUS)
COMPATIBLE_IOCTL(LPRESET)
/*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
COMPATIBLE_IOCTL(LPGETFLAGS)
HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans)

/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
   but we don't want warnings on other file systems. So declare
@@ -1810,6 +1759,83 @@ static inline unsigned long ioctl32_hash(unsigned long cmd)
	return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
}

/*
 * Convert common ioctl arguments based on their command number
 *
 * Please do not add any code in here. Instead, implement
 * a compat_ioctl operation in the place that handleѕ the
 * ioctl for the native case.
 */
static long do_ioctl_trans(int fd, unsigned int cmd,
		 unsigned long arg, struct file *file)
{
	switch (cmd) {
	case PPPIOCGIDLE32:
	case PPPIOCSCOMPRESS32:
		return ppp_ioctl_trans(fd, cmd, arg);
	case PPPIOCSPASS32:
	case PPPIOCSACTIVE32:
		return ppp_sock_fprog_ioctl_trans(fd, cmd, arg);
#ifdef CONFIG_BLOCK
	case SG_IO:
		return sg_ioctl_trans(fd, cmd, arg);
	case SG_GET_REQUEST_TABLE:
		return sg_grt_trans(fd, cmd, arg);
	case MTIOCGET32:
	case MTIOCPOS32:
		return mt_ioctl_trans(fd, cmd, arg);
	/* Raw devices */
	case RAW_SETBIND:
	case RAW_GETBIND:
		return raw_ioctl(fd, cmd, arg);
#endif
#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
	case AUTOFS_IOC_SETTIMEOUT32:
		return ioc_settimeout(fd, cmd, arg);
	/* One SMB ioctl needs translations. */
#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
	case SMB_IOC_GETMOUNTUID_32:
		return do_smb_getmountuid(fd, cmd, arg);
	/* Serial */
	case TIOCGSERIAL:
	case TIOCSSERIAL:
		return serial_struct_ioctl(fd, cmd, arg);
	/* Usbdevfs */
	case USBDEVFS_CONTROL32:
		return do_usbdevfs_control(fd, cmd, arg);
	case USBDEVFS_BULK32:
		return do_usbdevfs_bulk(fd, cmd, arg);
	case USBDEVFS_DISCSIGNAL32:
		return do_usbdevfs_discsignal(fd, cmd, arg);
	/* i2c */
	case I2C_FUNCS:
		return w_long(fd, cmd, arg);
	case I2C_RDWR:
		return do_i2c_rdwr_ioctl(fd, cmd, arg);
	case I2C_SMBUS:
		return do_i2c_smbus_ioctl(fd, cmd, arg);
	/* Not implemented in the native kernel */
	case RTC_IRQP_READ32:
	case RTC_IRQP_SET32:
	case RTC_EPOCH_READ32:
	case RTC_EPOCH_SET32:
		return rtc_ioctl(fd, cmd, arg);

	/* dvb */
	case VIDEO_GET_EVENT:
		return do_video_get_event(fd, cmd, arg);
	case VIDEO_STILLPICTURE:
		return do_video_stillpicture(fd, cmd, arg);
	case VIDEO_SET_SPU_PALETTE:
		return do_video_set_spu_palette(fd, cmd, arg);

	/* lp */
	case LPSETTIMEOUT:
		return lp_timeout_trans(fd, cmd, arg);
	}
	return -ENOIOCTLCMD;
}

static void compat_ioctl_error(struct file *filp, unsigned int fd,
		unsigned int cmd, unsigned long arg)
{
@@ -1906,7 +1932,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
			goto found_handler;
	}

	{
	error = do_ioctl_trans(fd, cmd, arg, filp);
	if (error == -ENOIOCTLCMD) {
		static int count;

		if (++count <= 50)