diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-05-21 18:04:16 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2009-12-10 16:52:09 -0500 |
commit | 5a07ea0b97f206ed23a5850079b7f322e7730869 (patch) | |
tree | 7de142305d8cae9bbee2c182cd7f1e4abcdc39cc /fs/compat_ioctl.c | |
parent | 348c4b9078ba8d9bef2e453c7ded07fde4748c79 (diff) |
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: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/compat_ioctl.c')
-rw-r--r-- | fs/compat_ioctl.c | 135 |
1 files changed, 81 insertions, 54 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index a383424f1b25..0cd76e9e843a 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -635,12 +635,6 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a | |||
635 | return err; | 635 | return err; |
636 | } | 636 | } |
637 | 637 | ||
638 | static __used int | ||
639 | ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
640 | { | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) | 638 | static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) |
645 | { | 639 | { |
646 | return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); | 640 | return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); |
@@ -1241,6 +1235,8 @@ COMPATIBLE_IOCTL(MTIOCTOP) | |||
1241 | /* Socket level stuff */ | 1235 | /* Socket level stuff */ |
1242 | COMPATIBLE_IOCTL(FIOQSIZE) | 1236 | COMPATIBLE_IOCTL(FIOQSIZE) |
1243 | #ifdef CONFIG_BLOCK | 1237 | #ifdef CONFIG_BLOCK |
1238 | /* loop */ | ||
1239 | IGNORE_IOCTL(LOOP_CLR_FD) | ||
1244 | /* SG stuff */ | 1240 | /* SG stuff */ |
1245 | COMPATIBLE_IOCTL(SG_SET_TIMEOUT) | 1241 | COMPATIBLE_IOCTL(SG_SET_TIMEOUT) |
1246 | COMPATIBLE_IOCTL(SG_GET_TIMEOUT) | 1242 | COMPATIBLE_IOCTL(SG_GET_TIMEOUT) |
@@ -1699,35 +1695,6 @@ COMPATIBLE_IOCTL(JSIOCGAXES) | |||
1699 | COMPATIBLE_IOCTL(JSIOCGBUTTONS) | 1695 | COMPATIBLE_IOCTL(JSIOCGBUTTONS) |
1700 | COMPATIBLE_IOCTL(JSIOCGNAME(0)) | 1696 | COMPATIBLE_IOCTL(JSIOCGNAME(0)) |
1701 | 1697 | ||
1702 | /* now things that need handlers */ | ||
1703 | #ifdef CONFIG_BLOCK | ||
1704 | HANDLE_IOCTL(SG_IO,sg_ioctl_trans) | ||
1705 | HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) | ||
1706 | #endif | ||
1707 | HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) | ||
1708 | HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) | ||
1709 | HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) | ||
1710 | HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) | ||
1711 | #ifdef CONFIG_BLOCK | ||
1712 | HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) | ||
1713 | HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) | ||
1714 | #endif | ||
1715 | #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) | ||
1716 | HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) | ||
1717 | /* One SMB ioctl needs translations. */ | ||
1718 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) | ||
1719 | HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) | ||
1720 | /* block stuff */ | ||
1721 | #ifdef CONFIG_BLOCK | ||
1722 | /* loop */ | ||
1723 | IGNORE_IOCTL(LOOP_CLR_FD) | ||
1724 | /* Raw devices */ | ||
1725 | HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) | ||
1726 | HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) | ||
1727 | #endif | ||
1728 | /* Serial */ | ||
1729 | HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl) | ||
1730 | HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) | ||
1731 | #ifdef TIOCGLTC | 1698 | #ifdef TIOCGLTC |
1732 | COMPATIBLE_IOCTL(TIOCGLTC) | 1699 | COMPATIBLE_IOCTL(TIOCGLTC) |
1733 | COMPATIBLE_IOCTL(TIOCSLTC) | 1700 | COMPATIBLE_IOCTL(TIOCSLTC) |
@@ -1743,24 +1710,7 @@ COMPATIBLE_IOCTL(TIOCSTART) | |||
1743 | COMPATIBLE_IOCTL(TIOCSTOP) | 1710 | COMPATIBLE_IOCTL(TIOCSTOP) |
1744 | #endif | 1711 | #endif |
1745 | /* Usbdevfs */ | 1712 | /* Usbdevfs */ |
1746 | HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control) | ||
1747 | HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk) | ||
1748 | HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) | ||
1749 | COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) | 1713 | COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) |
1750 | /* i2c */ | ||
1751 | HANDLE_IOCTL(I2C_FUNCS, w_long) | ||
1752 | HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) | ||
1753 | HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) | ||
1754 | /* Not implemented in the native kernel */ | ||
1755 | HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) | ||
1756 | HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) | ||
1757 | HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) | ||
1758 | HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) | ||
1759 | |||
1760 | /* dvb */ | ||
1761 | HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) | ||
1762 | HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) | ||
1763 | HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette) | ||
1764 | 1714 | ||
1765 | /* parport */ | 1715 | /* parport */ |
1766 | COMPATIBLE_IOCTL(LPTIME) | 1716 | COMPATIBLE_IOCTL(LPTIME) |
@@ -1774,7 +1724,6 @@ COMPATIBLE_IOCTL(LPGETSTATUS) | |||
1774 | COMPATIBLE_IOCTL(LPRESET) | 1724 | COMPATIBLE_IOCTL(LPRESET) |
1775 | /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ | 1725 | /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ |
1776 | COMPATIBLE_IOCTL(LPGETFLAGS) | 1726 | COMPATIBLE_IOCTL(LPGETFLAGS) |
1777 | HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) | ||
1778 | 1727 | ||
1779 | /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, | 1728 | /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, |
1780 | but we don't want warnings on other file systems. So declare | 1729 | 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) | |||
1810 | return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; | 1759 | return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; |
1811 | } | 1760 | } |
1812 | 1761 | ||
1762 | /* | ||
1763 | * Convert common ioctl arguments based on their command number | ||
1764 | * | ||
1765 | * Please do not add any code in here. Instead, implement | ||
1766 | * a compat_ioctl operation in the place that handleѕ the | ||
1767 | * ioctl for the native case. | ||
1768 | */ | ||
1769 | static long do_ioctl_trans(int fd, unsigned int cmd, | ||
1770 | unsigned long arg, struct file *file) | ||
1771 | { | ||
1772 | switch (cmd) { | ||
1773 | case PPPIOCGIDLE32: | ||
1774 | case PPPIOCSCOMPRESS32: | ||
1775 | return ppp_ioctl_trans(fd, cmd, arg); | ||
1776 | case PPPIOCSPASS32: | ||
1777 | case PPPIOCSACTIVE32: | ||
1778 | return ppp_sock_fprog_ioctl_trans(fd, cmd, arg); | ||
1779 | #ifdef CONFIG_BLOCK | ||
1780 | case SG_IO: | ||
1781 | return sg_ioctl_trans(fd, cmd, arg); | ||
1782 | case SG_GET_REQUEST_TABLE: | ||
1783 | return sg_grt_trans(fd, cmd, arg); | ||
1784 | case MTIOCGET32: | ||
1785 | case MTIOCPOS32: | ||
1786 | return mt_ioctl_trans(fd, cmd, arg); | ||
1787 | /* Raw devices */ | ||
1788 | case RAW_SETBIND: | ||
1789 | case RAW_GETBIND: | ||
1790 | return raw_ioctl(fd, cmd, arg); | ||
1791 | #endif | ||
1792 | #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) | ||
1793 | case AUTOFS_IOC_SETTIMEOUT32: | ||
1794 | return ioc_settimeout(fd, cmd, arg); | ||
1795 | /* One SMB ioctl needs translations. */ | ||
1796 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) | ||
1797 | case SMB_IOC_GETMOUNTUID_32: | ||
1798 | return do_smb_getmountuid(fd, cmd, arg); | ||
1799 | /* Serial */ | ||
1800 | case TIOCGSERIAL: | ||
1801 | case TIOCSSERIAL: | ||
1802 | return serial_struct_ioctl(fd, cmd, arg); | ||
1803 | /* Usbdevfs */ | ||
1804 | case USBDEVFS_CONTROL32: | ||
1805 | return do_usbdevfs_control(fd, cmd, arg); | ||
1806 | case USBDEVFS_BULK32: | ||
1807 | return do_usbdevfs_bulk(fd, cmd, arg); | ||
1808 | case USBDEVFS_DISCSIGNAL32: | ||
1809 | return do_usbdevfs_discsignal(fd, cmd, arg); | ||
1810 | /* i2c */ | ||
1811 | case I2C_FUNCS: | ||
1812 | return w_long(fd, cmd, arg); | ||
1813 | case I2C_RDWR: | ||
1814 | return do_i2c_rdwr_ioctl(fd, cmd, arg); | ||
1815 | case I2C_SMBUS: | ||
1816 | return do_i2c_smbus_ioctl(fd, cmd, arg); | ||
1817 | /* Not implemented in the native kernel */ | ||
1818 | case RTC_IRQP_READ32: | ||
1819 | case RTC_IRQP_SET32: | ||
1820 | case RTC_EPOCH_READ32: | ||
1821 | case RTC_EPOCH_SET32: | ||
1822 | return rtc_ioctl(fd, cmd, arg); | ||
1823 | |||
1824 | /* dvb */ | ||
1825 | case VIDEO_GET_EVENT: | ||
1826 | return do_video_get_event(fd, cmd, arg); | ||
1827 | case VIDEO_STILLPICTURE: | ||
1828 | return do_video_stillpicture(fd, cmd, arg); | ||
1829 | case VIDEO_SET_SPU_PALETTE: | ||
1830 | return do_video_set_spu_palette(fd, cmd, arg); | ||
1831 | |||
1832 | /* lp */ | ||
1833 | case LPSETTIMEOUT: | ||
1834 | return lp_timeout_trans(fd, cmd, arg); | ||
1835 | } | ||
1836 | return -ENOIOCTLCMD; | ||
1837 | } | ||
1838 | |||
1813 | static void compat_ioctl_error(struct file *filp, unsigned int fd, | 1839 | static void compat_ioctl_error(struct file *filp, unsigned int fd, |
1814 | unsigned int cmd, unsigned long arg) | 1840 | unsigned int cmd, unsigned long arg) |
1815 | { | 1841 | { |
@@ -1906,7 +1932,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
1906 | goto found_handler; | 1932 | goto found_handler; |
1907 | } | 1933 | } |
1908 | 1934 | ||
1909 | { | 1935 | error = do_ioctl_trans(fd, cmd, arg, filp); |
1936 | if (error == -ENOIOCTLCMD) { | ||
1910 | static int count; | 1937 | static int count; |
1911 | 1938 | ||
1912 | if (++count <= 50) | 1939 | if (++count <= 50) |