diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2009-11-05 13:13:51 -0500 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2009-12-10 16:52:10 -0500 |
| commit | 789f0f89118a80a3ff5309371e5820f623ed2a53 (patch) | |
| tree | b4f178d169be07bdc9cbc629d4f9dab896233408 | |
| parent | 5a07ea0b97f206ed23a5850079b7f322e7730869 (diff) | |
compat_ioctl: simplify calling of handlers
The compat_ioctl array now contains only entries for ioctl numbers
that do not require a separate handler. By special-casing the
ULONG_IOCTL case in the do_ioctl_trans function, we can kill the
final use of a function pointer in the array.
text data bss dec hex filename
7539 13352 2080 22971 59bb before/fs/compat_ioctl.o
7910 8552 2080 18542 486e after/fs/compat_ioctl.o
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
| -rw-r--r-- | fs/compat_ioctl.c | 86 |
1 files changed, 39 insertions, 47 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 0cd76e9e843a..7895bdb0c304 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -115,12 +115,6 @@ | |||
| 115 | #include <asm/fbio.h> | 115 | #include <asm/fbio.h> |
| 116 | #endif | 116 | #endif |
| 117 | 117 | ||
| 118 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, | ||
| 119 | unsigned long arg, struct file *f) | ||
| 120 | { | ||
| 121 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); | ||
| 122 | } | ||
| 123 | |||
| 124 | static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) | 118 | static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) |
| 125 | { | 119 | { |
| 126 | mm_segment_t old_fs = get_fs(); | 120 | mm_segment_t old_fs = get_fs(); |
| @@ -1055,25 +1049,13 @@ static int compat_ioctl_preallocate(struct file *file, unsigned long arg) | |||
| 1055 | #endif | 1049 | #endif |
| 1056 | 1050 | ||
| 1057 | 1051 | ||
| 1058 | typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int, | ||
| 1059 | unsigned long, struct file *); | ||
| 1060 | |||
| 1061 | struct ioctl_trans { | 1052 | struct ioctl_trans { |
| 1062 | unsigned long cmd; | 1053 | unsigned long cmd; |
| 1063 | ioctl_trans_handler_t handler; | ||
| 1064 | struct ioctl_trans *next; | 1054 | struct ioctl_trans *next; |
| 1065 | }; | 1055 | }; |
| 1066 | 1056 | ||
| 1067 | #define HANDLE_IOCTL(cmd,handler) \ | ||
| 1068 | { (cmd), (ioctl_trans_handler_t)(handler) }, | ||
| 1069 | |||
| 1070 | /* pointer to compatible structure or no argument */ | 1057 | /* pointer to compatible structure or no argument */ |
| 1071 | #define COMPATIBLE_IOCTL(cmd) \ | 1058 | #define COMPATIBLE_IOCTL(cmd) { (cmd), }, |
| 1072 | { (cmd), do_ioctl32_pointer }, | ||
| 1073 | |||
| 1074 | /* argument is an unsigned long integer, not a pointer */ | ||
| 1075 | #define ULONG_IOCTL(cmd) \ | ||
| 1076 | { (cmd), (ioctl_trans_handler_t)sys_ioctl }, | ||
| 1077 | 1059 | ||
| 1078 | /* ioctl should not be warned about even if it's not implemented. | 1060 | /* ioctl should not be warned about even if it's not implemented. |
| 1079 | Valid reasons to use this: | 1061 | Valid reasons to use this: |
| @@ -1095,7 +1077,6 @@ COMPATIBLE_IOCTL(TCSETA) | |||
| 1095 | COMPATIBLE_IOCTL(TCSETAW) | 1077 | COMPATIBLE_IOCTL(TCSETAW) |
| 1096 | COMPATIBLE_IOCTL(TCSETAF) | 1078 | COMPATIBLE_IOCTL(TCSETAF) |
| 1097 | COMPATIBLE_IOCTL(TCSBRK) | 1079 | COMPATIBLE_IOCTL(TCSBRK) |
| 1098 | ULONG_IOCTL(TCSBRKP) | ||
| 1099 | COMPATIBLE_IOCTL(TCXONC) | 1080 | COMPATIBLE_IOCTL(TCXONC) |
| 1100 | COMPATIBLE_IOCTL(TCFLSH) | 1081 | COMPATIBLE_IOCTL(TCFLSH) |
| 1101 | COMPATIBLE_IOCTL(TCGETS) | 1082 | COMPATIBLE_IOCTL(TCGETS) |
| @@ -1105,7 +1086,6 @@ COMPATIBLE_IOCTL(TCSETSF) | |||
| 1105 | COMPATIBLE_IOCTL(TIOCLINUX) | 1086 | COMPATIBLE_IOCTL(TIOCLINUX) |
| 1106 | COMPATIBLE_IOCTL(TIOCSBRK) | 1087 | COMPATIBLE_IOCTL(TIOCSBRK) |
| 1107 | COMPATIBLE_IOCTL(TIOCCBRK) | 1088 | COMPATIBLE_IOCTL(TIOCCBRK) |
| 1108 | ULONG_IOCTL(TIOCMIWAIT) | ||
| 1109 | COMPATIBLE_IOCTL(TIOCGICOUNT) | 1089 | COMPATIBLE_IOCTL(TIOCGICOUNT) |
| 1110 | /* Little t */ | 1090 | /* Little t */ |
| 1111 | COMPATIBLE_IOCTL(TIOCGETD) | 1091 | COMPATIBLE_IOCTL(TIOCGETD) |
| @@ -1127,7 +1107,6 @@ COMPATIBLE_IOCTL(TIOCSTI) | |||
| 1127 | COMPATIBLE_IOCTL(TIOCOUTQ) | 1107 | COMPATIBLE_IOCTL(TIOCOUTQ) |
| 1128 | COMPATIBLE_IOCTL(TIOCSPGRP) | 1108 | COMPATIBLE_IOCTL(TIOCSPGRP) |
| 1129 | COMPATIBLE_IOCTL(TIOCGPGRP) | 1109 | COMPATIBLE_IOCTL(TIOCGPGRP) |
| 1130 | ULONG_IOCTL(TIOCSCTTY) | ||
| 1131 | COMPATIBLE_IOCTL(TIOCGPTN) | 1110 | COMPATIBLE_IOCTL(TIOCGPTN) |
| 1132 | COMPATIBLE_IOCTL(TIOCSPTLCK) | 1111 | COMPATIBLE_IOCTL(TIOCSPTLCK) |
| 1133 | COMPATIBLE_IOCTL(TIOCSERGETLSR) | 1112 | COMPATIBLE_IOCTL(TIOCSERGETLSR) |
| @@ -1158,32 +1137,21 @@ COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) | |||
| 1158 | COMPATIBLE_IOCTL(RAID_AUTORUN) | 1137 | COMPATIBLE_IOCTL(RAID_AUTORUN) |
| 1159 | COMPATIBLE_IOCTL(CLEAR_ARRAY) | 1138 | COMPATIBLE_IOCTL(CLEAR_ARRAY) |
| 1160 | COMPATIBLE_IOCTL(ADD_NEW_DISK) | 1139 | COMPATIBLE_IOCTL(ADD_NEW_DISK) |
| 1161 | ULONG_IOCTL(HOT_REMOVE_DISK) | ||
| 1162 | COMPATIBLE_IOCTL(SET_ARRAY_INFO) | 1140 | COMPATIBLE_IOCTL(SET_ARRAY_INFO) |
| 1163 | COMPATIBLE_IOCTL(SET_DISK_INFO) | 1141 | COMPATIBLE_IOCTL(SET_DISK_INFO) |
| 1164 | COMPATIBLE_IOCTL(WRITE_RAID_INFO) | 1142 | COMPATIBLE_IOCTL(WRITE_RAID_INFO) |
| 1165 | COMPATIBLE_IOCTL(UNPROTECT_ARRAY) | 1143 | COMPATIBLE_IOCTL(UNPROTECT_ARRAY) |
| 1166 | COMPATIBLE_IOCTL(PROTECT_ARRAY) | 1144 | COMPATIBLE_IOCTL(PROTECT_ARRAY) |
| 1167 | ULONG_IOCTL(HOT_ADD_DISK) | ||
| 1168 | ULONG_IOCTL(SET_DISK_FAULTY) | ||
| 1169 | COMPATIBLE_IOCTL(RUN_ARRAY) | 1145 | COMPATIBLE_IOCTL(RUN_ARRAY) |
| 1170 | COMPATIBLE_IOCTL(STOP_ARRAY) | 1146 | COMPATIBLE_IOCTL(STOP_ARRAY) |
| 1171 | COMPATIBLE_IOCTL(STOP_ARRAY_RO) | 1147 | COMPATIBLE_IOCTL(STOP_ARRAY_RO) |
| 1172 | COMPATIBLE_IOCTL(RESTART_ARRAY_RW) | 1148 | COMPATIBLE_IOCTL(RESTART_ARRAY_RW) |
| 1173 | COMPATIBLE_IOCTL(GET_BITMAP_FILE) | 1149 | COMPATIBLE_IOCTL(GET_BITMAP_FILE) |
| 1174 | ULONG_IOCTL(SET_BITMAP_FILE) | ||
| 1175 | /* Keyboard -- can be removed once tty3270 uses ops->compat_ioctl */ | ||
| 1176 | ULONG_IOCTL(KDSIGACCEPT) | ||
| 1177 | COMPATIBLE_IOCTL(KDGETKEYCODE) | 1150 | COMPATIBLE_IOCTL(KDGETKEYCODE) |
| 1178 | COMPATIBLE_IOCTL(KDSETKEYCODE) | 1151 | COMPATIBLE_IOCTL(KDSETKEYCODE) |
| 1179 | ULONG_IOCTL(KIOCSOUND) | ||
| 1180 | ULONG_IOCTL(KDMKTONE) | ||
| 1181 | COMPATIBLE_IOCTL(KDGKBTYPE) | 1152 | COMPATIBLE_IOCTL(KDGKBTYPE) |
| 1182 | ULONG_IOCTL(KDSETMODE) | ||
| 1183 | COMPATIBLE_IOCTL(KDGETMODE) | 1153 | COMPATIBLE_IOCTL(KDGETMODE) |
| 1184 | ULONG_IOCTL(KDSKBMODE) | ||
| 1185 | COMPATIBLE_IOCTL(KDGKBMODE) | 1154 | COMPATIBLE_IOCTL(KDGKBMODE) |
| 1186 | ULONG_IOCTL(KDSKBMETA) | ||
| 1187 | COMPATIBLE_IOCTL(KDGKBMETA) | 1155 | COMPATIBLE_IOCTL(KDGKBMETA) |
| 1188 | COMPATIBLE_IOCTL(KDGKBENT) | 1156 | COMPATIBLE_IOCTL(KDGKBENT) |
| 1189 | COMPATIBLE_IOCTL(KDSKBENT) | 1157 | COMPATIBLE_IOCTL(KDSKBENT) |
| @@ -1193,9 +1161,7 @@ COMPATIBLE_IOCTL(KDGKBDIACR) | |||
| 1193 | COMPATIBLE_IOCTL(KDSKBDIACR) | 1161 | COMPATIBLE_IOCTL(KDSKBDIACR) |
| 1194 | COMPATIBLE_IOCTL(KDKBDREP) | 1162 | COMPATIBLE_IOCTL(KDKBDREP) |
| 1195 | COMPATIBLE_IOCTL(KDGKBLED) | 1163 | COMPATIBLE_IOCTL(KDGKBLED) |
| 1196 | ULONG_IOCTL(KDSKBLED) | ||
| 1197 | COMPATIBLE_IOCTL(KDGETLED) | 1164 | COMPATIBLE_IOCTL(KDGETLED) |
| 1198 | ULONG_IOCTL(KDSETLED) | ||
| 1199 | #ifdef CONFIG_BLOCK | 1165 | #ifdef CONFIG_BLOCK |
| 1200 | /* Big S */ | 1166 | /* Big S */ |
| 1201 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) | 1167 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) |
| @@ -1241,7 +1207,6 @@ IGNORE_IOCTL(LOOP_CLR_FD) | |||
| 1241 | COMPATIBLE_IOCTL(SG_SET_TIMEOUT) | 1207 | COMPATIBLE_IOCTL(SG_SET_TIMEOUT) |
| 1242 | COMPATIBLE_IOCTL(SG_GET_TIMEOUT) | 1208 | COMPATIBLE_IOCTL(SG_GET_TIMEOUT) |
| 1243 | COMPATIBLE_IOCTL(SG_EMULATED_HOST) | 1209 | COMPATIBLE_IOCTL(SG_EMULATED_HOST) |
| 1244 | ULONG_IOCTL(SG_SET_TRANSFORM) | ||
| 1245 | COMPATIBLE_IOCTL(SG_GET_TRANSFORM) | 1210 | COMPATIBLE_IOCTL(SG_GET_TRANSFORM) |
| 1246 | COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) | 1211 | COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) |
| 1247 | COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) | 1212 | COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) |
| @@ -1478,8 +1443,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) | |||
| 1478 | COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) | 1443 | COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) |
| 1479 | COMPATIBLE_IOCTL(OSS_GETVERSION) | 1444 | COMPATIBLE_IOCTL(OSS_GETVERSION) |
| 1480 | /* AUTOFS */ | 1445 | /* AUTOFS */ |
| 1481 | ULONG_IOCTL(AUTOFS_IOC_READY) | ||
| 1482 | ULONG_IOCTL(AUTOFS_IOC_FAIL) | ||
| 1483 | COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) | 1446 | COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) |
| 1484 | COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) | 1447 | COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) |
| 1485 | COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) | 1448 | COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) |
| @@ -1588,14 +1551,10 @@ COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) | |||
| 1588 | COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) | 1551 | COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) |
| 1589 | COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) | 1552 | COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) |
| 1590 | /* NBD */ | 1553 | /* NBD */ |
| 1591 | ULONG_IOCTL(NBD_SET_SOCK) | ||
| 1592 | ULONG_IOCTL(NBD_SET_BLKSIZE) | ||
| 1593 | ULONG_IOCTL(NBD_SET_SIZE) | ||
| 1594 | COMPATIBLE_IOCTL(NBD_DO_IT) | 1554 | COMPATIBLE_IOCTL(NBD_DO_IT) |
| 1595 | COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) | 1555 | COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) |
| 1596 | COMPATIBLE_IOCTL(NBD_CLEAR_QUE) | 1556 | COMPATIBLE_IOCTL(NBD_CLEAR_QUE) |
| 1597 | COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) | 1557 | COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) |
| 1598 | ULONG_IOCTL(NBD_SET_SIZE_BLOCKS) | ||
| 1599 | COMPATIBLE_IOCTL(NBD_DISCONNECT) | 1558 | COMPATIBLE_IOCTL(NBD_DISCONNECT) |
| 1600 | /* i2c */ | 1559 | /* i2c */ |
| 1601 | COMPATIBLE_IOCTL(I2C_SLAVE) | 1560 | COMPATIBLE_IOCTL(I2C_SLAVE) |
| @@ -1833,6 +1792,43 @@ static long do_ioctl_trans(int fd, unsigned int cmd, | |||
| 1833 | case LPSETTIMEOUT: | 1792 | case LPSETTIMEOUT: |
| 1834 | return lp_timeout_trans(fd, cmd, arg); | 1793 | return lp_timeout_trans(fd, cmd, arg); |
| 1835 | } | 1794 | } |
| 1795 | |||
| 1796 | /* | ||
| 1797 | * These take an integer instead of a pointer as 'arg', | ||
| 1798 | * so we must not do a compat_ptr() translation. | ||
| 1799 | */ | ||
| 1800 | switch (cmd) { | ||
| 1801 | /* Big T */ | ||
| 1802 | case TCSBRKP: | ||
| 1803 | case TIOCMIWAIT: | ||
| 1804 | case TIOCSCTTY: | ||
| 1805 | /* RAID */ | ||
| 1806 | case HOT_REMOVE_DISK: | ||
| 1807 | case HOT_ADD_DISK: | ||
| 1808 | case SET_DISK_FAULTY: | ||
| 1809 | case SET_BITMAP_FILE: | ||
| 1810 | /* Big K */ | ||
| 1811 | case KDSIGACCEPT: | ||
| 1812 | case KIOCSOUND: | ||
| 1813 | case KDMKTONE: | ||
| 1814 | case KDSETMODE: | ||
| 1815 | case KDSKBMODE: | ||
| 1816 | case KDSKBMETA: | ||
| 1817 | case KDSKBLED: | ||
| 1818 | case KDSETLED: | ||
| 1819 | /* SG stuff */ | ||
| 1820 | case SG_SET_TRANSFORM: | ||
| 1821 | /* AUTOFS */ | ||
| 1822 | case AUTOFS_IOC_READY: | ||
| 1823 | case AUTOFS_IOC_FAIL: | ||
| 1824 | /* NBD */ | ||
| 1825 | case NBD_SET_SOCK: | ||
| 1826 | case NBD_SET_BLKSIZE: | ||
| 1827 | case NBD_SET_SIZE: | ||
| 1828 | case NBD_SET_SIZE_BLOCKS: | ||
| 1829 | return do_vfs_ioctl(file, fd, cmd, arg); | ||
| 1830 | } | ||
| 1831 | |||
| 1836 | return -ENOIOCTLCMD; | 1832 | return -ENOIOCTLCMD; |
| 1837 | } | 1833 | } |
| 1838 | 1834 | ||
| @@ -1944,11 +1940,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
| 1944 | goto out_fput; | 1940 | goto out_fput; |
| 1945 | 1941 | ||
| 1946 | found_handler: | 1942 | found_handler: |
| 1947 | if (t->handler) { | 1943 | arg = (unsigned long)compat_ptr(arg); |
| 1948 | error = t->handler(fd, cmd, arg, filp); | ||
| 1949 | goto out_fput; | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | do_ioctl: | 1944 | do_ioctl: |
| 1953 | error = do_vfs_ioctl(filp, fd, cmd, arg); | 1945 | error = do_vfs_ioctl(filp, fd, cmd, arg); |
| 1954 | out_fput: | 1946 | out_fput: |
