reduce code in fs/compat_ioctl.c
Subsystems (31)
Arnd Bergmann
maintainercover reduce code in fs/compat_ioctl.c
Quoted 9 lines · Christoph Hellwig
Quoted 7 lines · Arnd Bergmann
BTW, I now have a set of 25 patches that moves all handlers from
fs/compat_ioctl.cover to the respective drivers and subsystems, but I'm not sure how to best test that.
I intend to at least give it a test run on my Opteron for the whatever ioctls I normally use, but the rest is just guesswork. Christoph, can you review those patches?
Quoted 3 lines
I'm not sure moving everything from
fs/compat_ioctl.cis a good idea. Everything that is just in a single driver or subsystem that has common ioctl code - sure. else it doesn't make a lot of sense.
Ok, here is my full set of patches, let's see which ones are sensible and which ones we are better off without.
Getting rid of fs/compat_ioctl.c completely could at least simplify the compat_sys_ioctl() code a bit and would also make sure that we only build the handlers into the kernel that can be used potentially, which reduces the binary size.
The patch set is still largely untested, except for a single compile test, but at least some of the patches are very simple, so maybe I can get a quick ack or nack on them.
In general, I'm just moving over the handlers to the respective subsystem without changing the logic, so the patch should not have any effect on the ioctl operation itself, but it also means that the handlers still use compat_alloc_user_space or get_fs/set_fs when it's not really necessary.
Arnd <><
drivers/block/ioctl.c | 549 +++++ drivers/block/loop.c | 76 drivers/block/paride/pcd.c | 1 drivers/block/paride/pd.c | 1 drivers/block/paride/pt.c | 1 drivers/block/pktcdvd.c | 20 drivers/bluetooth/hci_ldisc.c | 22 drivers/cdrom/Makefile | 2 drivers/cdrom/aztcd.c | 1 drivers/cdrom/cdu31a.c | 1 drivers/cdrom/cm206.c | 1 drivers/cdrom/compat.c | 163 + drivers/cdrom/gscd.c | 1 drivers/cdrom/mcdx.c | 1 drivers/cdrom/optcd.c | 1 drivers/cdrom/sbpcd.c | 1 drivers/cdrom/sjcd.c | 1 drivers/cdrom/sonycd535.c | 2 drivers/char/Makefile | 1 drivers/char/compat_mtio.c | 81 drivers/char/ftape/zftape/zftape-init.c | 1 drivers/char/n_tty.c | 1 drivers/char/raw.c | 91 drivers/char/tty_io.c | 191 + drivers/char/viotape.c | 1 drivers/char/vt.c | 3 drivers/char/vt_ioctl.c | 195 + drivers/i2c/i2c-dev.c | 141 + drivers/ide/ide-cd.c | 1 drivers/ide/ide-floppy.c | 1 drivers/ide/ide-tape.c | 1 drivers/media/radio/miropcm20-radio.c | 1 drivers/media/radio/radio-aimslab.c | 1 drivers/media/radio/radio-aztech.c | 1 drivers/media/radio/radio-cadet.c | 1 drivers/media/radio/radio-gemtek-pci.c | 1 drivers/media/radio/radio-gemtek.c | 1 drivers/media/radio/radio-maestro.c | 1 drivers/media/radio/radio-maxiradio.c | 1 drivers/media/radio/radio-rtrack2.c | 1 drivers/media/radio/radio-sf16fmi.c | 1 drivers/media/radio/radio-sf16fmr2.c | 1 drivers/media/radio/radio-terratec.c | 1 drivers/media/radio/radio-trust.c | 1 drivers/media/radio/radio-typhoon.c | 1 drivers/media/radio/radio-zoltrix.c | 1 drivers/media/video/Makefile | 2 drivers/media/video/arv.c | 1 drivers/media/video/bttv-driver.c | 1 drivers/media/video/bw-qcam.c | 1 drivers/media/video/c-qcam.c | 1 drivers/media/video/compat_ioctl.c | 318 +++ drivers/media/video/cpia.c | 1 drivers/media/video/cx88/cx88-video.c | 2 drivers/media/video/meye.c | 1 drivers/media/video/pms.c | 1 drivers/media/video/saa5249.c | 1 drivers/media/video/saa7134/saa7134-video.c | 2 drivers/media/video/stradis.c | 1 drivers/media/video/w9966.c | 1 drivers/media/video/zoran_driver.c | 1 drivers/media/video/zr36120.c | 1 drivers/mtd/mtdchar.c | 94 drivers/net/ppp_generic.c | 179 + drivers/s390/char/tape_char.c | 1 drivers/scsi/osst.c | 2 drivers/scsi/sg.c | 154 + drivers/scsi/sr.c | 1 drivers/scsi/st.c | 2 drivers/usb/core/devio.c | 139 + drivers/usb/media/dsbr100.c | 1 drivers/usb/media/ov511.c | 1 drivers/usb/media/pwc/pwc-if.c | 1 drivers/usb/media/se401.c | 1 drivers/usb/media/stv680.c | 1 drivers/usb/media/usbvideo.c | 1 drivers/usb/media/vicam.c | 1 drivers/usb/media/w9968cf.c | 1 drivers/video/fbmem.c | 147 + fs/autofs/root.c | 35 fs/autofs4/root.c | 41 fs/block_dev.c | 10 fs/cifs/cifsfs.c | 10 fs/cifs/cifsfs.h | 2 fs/cifs/ioctl.c | 29 fs/compat.c | 27 fs/compat_ioctl.c | 2918 ---------------------------- fs/ext2/dir.c | 3 fs/ext2/ext2.h | 1 fs/ext2/file.c | 6 fs/ext2/ioctl.c | 31 fs/ext3/dir.c | 3 fs/ext3/file.c | 3 fs/ext3/ioctl.c | 66 fs/fat/dir.c | 54 fs/hfsplus/dir.c | 4 fs/hfsplus/hfsplus_fs.h | 4 fs/hfsplus/inode.c | 4 fs/hfsplus/ioctl.c | 29 fs/ncpfs/dir.c | 3 fs/ncpfs/file.c | 4 fs/ncpfs/ioctl.c | 241 ++ fs/reiserfs/dir.c | 3 fs/reiserfs/file.c | 4 fs/reiserfs/ioctl.c | 36 fs/smbfs/dir.c | 4 fs/smbfs/file.c | 4 fs/smbfs/ioctl.c | 16 fs/smbfs/proto.h | 1 fs/xfs/linux-2.6/xfs_ioctl32.c | 15 include/linux/cdrom.h | 2 include/linux/compat_ioctl.h | 387 --- include/linux/ext2_fs.h | 7 include/linux/ext3_fs.h | 1 include/linux/fs.h | 3 include/linux/ioctl32.h | 2 include/linux/mtio.h | 12 include/linux/ncp_fs.h | 1 include/linux/net.h | 2 include/linux/reiserfs_fs.h | 9 include/linux/socket.h | 4 include/linux/tty.h | 2 include/linux/tty_driver.h | 4 include/linux/tty_ldisc.h | 2 include/linux/videodev.h | 2 include/net/sock.h | 9 net/atm/common.h | 1 net/atm/ioctl.c | 167 + net/atm/pvc.c | 3 net/atm/svc.c | 3 net/bluetooth/bnep/sock.c | 1 net/bluetooth/cmtp/sock.c | 1 net/bluetooth/hci_sock.c | 1 net/bluetooth/hidp/sock.c | 1 net/bluetooth/rfcomm/sock.c | 1 net/compat.c | 1456 +++++++++---- net/socket.c | 7 137 files changed, 4527 insertions(+), 3807 deletions(-)
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Arnd Bergmann
maintainerPATCH 1/25 compat: Remove leftovers from register_ioctl32_conversion
We don't need the semaphore any more since we no longer write to the ioctl32 hash table while the kernel is running.
fs/compat.c +0 -7
@@ -268,7 +268,6 @@#define IOCTL_HASHSIZE 256static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE ]; -static DECLARE_RWSEM (ioctl32_sem);extern struct ioctl_trans ioctl_start[];extern int ioctl_table_size;
@@ -390,14 +389,10 @@break ; } -/* When register_ioctl32_conversion is finally gone remove -this lock! -AK */ -down_read (&ioctl32_sem);for (t = ioctl32_hash_table[ioctl32_hash (cmd)]; t; t = t->next) {if (t->cmd == cmd) goto found_handler; } -up_read (&ioctl32_sem);if (S_ISSOCK (filp->f_dentry->d_inode->i_mode) && cmd >=SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE +15 )) {
@@ -417,11 +412,9 @@lock_kernel (); error = t->handler (fd, cmd, arg, filp);unlock_kernel (); -up_read (&ioctl32_sem); goto out_fput; } -up_read (&ioctl32_sem); do_ioctl: error =vfs_ioctl (filp, fd, cmd, arg); out_fput:
include/linux/ioctl32.h +0 -2
@@ -1,8 +1,6 @@#ifndef IOCTL32_H #define IOCTL32_H 1 -#include <linux/compiler.h> /* for __deprecated */ -struct file ; typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
--
Re: [PATCH 01/25] compat: Remove leftovers from register_ioctl32_conversion
Quoted 2 lines · Arnd Bergmann
We don't need the semaphore any more since we no longer write to the ioctl32 hash table while the kernel is running.
Could we *please* get rid of this ridiculous return type of compat_ioctl?
->ioctl() returns 32bit value. Everywhere. On 32 and 64 bit platforms. Having ->compat_ioctl() return value twice wider than not just emulated ->ioctl(), but native one as well...
Let's kill that stupidity before adding fsckloads of new instances.
Re: [PATCH 01/25] compat: Remove leftovers from register_ioctl32_conversion
In reply to Arnd BergmannQuoted 2 lines · Arnd Bergmann
We don't need the semaphore any more since we no longer write to the ioctl32 hash table while the kernel is running.
Yes good patch. In fact I had a similar patch in one of my trees for a long time, just didn't get around to submit it yet.
-Andi
Arnd Bergmann
maintainerPATCH 2/25 net: move socket ioctl32 to net/compat.c
In reply to Arnd BergmannThis patch is very experimental and completely untested.
A substantial amount of the compat_ioctl code deals with socked ioctls. This patch moves all socket ioctl conversions over to net/compat.c in order to get it closer to the respective device drivers.
It also adds the infrastructure to do compat_ioctl specific to proto_ops, which will be used in further patches.
Also, the SIOCDEVPRIVATE handling is now local to a single file and can probably be made driver specific in the future.
All the conversion handlers are basically unmodified in order to minimize the risk of silently breaking stuff.
fs/compat_ioctl.c +0 -845
@@ -413,408 +413,6 @@return err; } -#ifdef CONFIG_NET -static int do_siocgstamp (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct compat_timeval __user *up =compat_ptr (arg); -struct timeval ktv; -mm_segment_t old_fs =get_fs (); -int err; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&ktv); -set_fs (old_fs); -if (!err) { - err =put_user (ktv.tv_sec, &up->tv_sec); - err |=__put_user (ktv.tv_usec, &up->tv_usec); - } -return err; -} - -struct ifmap32 { -compat_ulong_t mem_start; -compat_ulong_t mem_end; -unsigned short base_addr; -unsigned char irq; -unsigned char dma; -unsigned char port; -}; - -struct ifreq32 { -#define IFHWADDRLEN 6 -#define IFNAMSIZ 16 -union { -char ifrn_name[IFNAMSIZ ];/* if name, e.g. "en0" */ - } ifr_ifrn; -union { -struct sockaddr ifru_addr; -struct sockaddr ifru_dstaddr; -struct sockaddr ifru_broadaddr; -struct sockaddr ifru_netmask; -struct sockaddr ifru_hwaddr; -short ifru_flags; -compat_int_t ifru_ivalue; -compat_int_t ifru_mtu; -struct ifmap32 ifru_map; -char ifru_slave[IFNAMSIZ ];/* Just fits the size */ -char ifru_newname[IFNAMSIZ ]; -compat_caddr_t ifru_data; -/* XXXX? ifru_settings should be here */ - } ifr_ifru; -}; - -struct ifconf32 { -compat_int_t ifc_len;/* size of buffer */ -compat_caddr_t ifcbuf; -}; - -static int dev_ifname32 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct net_device *dev; -struct ifreq32 ifr32; -int err; - -if (copy_from_user (&ifr32,compat_ptr (arg),sizeof (ifr32))) -return -EFAULT ; - - dev =dev_get_by_index (ifr32.ifr_ifindex); -if (!dev) -return -ENODEV ; - -strlcpy (ifr32.ifr_name, dev->name,sizeof (ifr32.ifr_name)); -dev_put (dev); - - err =copy_to_user (compat_ptr (arg), &ifr32,sizeof (ifr32)); -return (err ? -EFAULT :0 ); -} - -static int dev_ifconf (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ifconf32 ifc32; -struct ifconf ifc; -struct ifconf __user *uifc; -struct ifreq32 __user *ifr32; -struct ifreq __user *ifr; -unsigned int i, j; -int err; - -if (copy_from_user (&ifc32,compat_ptr (arg),sizeof (struct ifconf32 ))) -return -EFAULT ; - -if (ifc32.ifcbuf ==0 ) { - ifc32.ifc_len =0 ; - ifc.ifc_len =0 ; - ifc.ifc_req =NULL ; - uifc =compat_alloc_user_space (sizeof (struct ifconf )); - }else { -size_t len =((ifc32.ifc_len /sizeof (struct ifreq32 )) +1 ) * -sizeof (struct ifreq ); - uifc =compat_alloc_user_space (sizeof (struct ifconf ) + len); - ifc.ifc_len = len; - ifr = ifc.ifc_req = (void __user *)(uifc +1 ); - ifr32 =compat_ptr (ifc32.ifcbuf); -for (i =0 ; i < ifc32.ifc_len; i +=sizeof (struct ifreq32 )) { -if (copy_in_user (ifr, ifr32,sizeof (struct ifreq32 ))) -return -EFAULT ; - ifr++; - ifr32++; - } - } -if (copy_to_user (uifc, &ifc,sizeof (struct ifconf ))) -return -EFAULT ; - - err =sys_ioctl (fd,SIOCGIFCONF , (unsigned long )uifc); -if (err) -return err; - -if (copy_from_user (&ifc, uifc,sizeof (struct ifconf ))) -return -EFAULT ; - - ifr = ifc.ifc_req; - ifr32 =compat_ptr (ifc32.ifcbuf); -for (i =0 , j =0 ; i < ifc32.ifc_len && j < ifc.ifc_len; - i +=sizeof (struct ifreq32 ), j +=sizeof (struct ifreq )) { -if (copy_in_user (ifr32, ifr,sizeof (struct ifreq32 ))) -return -EFAULT ; - ifr32++; - ifr++; - } - -if (ifc32.ifcbuf ==0 ) { -/* Translate from 64-bit structure multiple to -* a 32-bit one. -*/ - i = ifc.ifc_len; - i = ((i /sizeof (struct ifreq )) *sizeof (struct ifreq32 )); - ifc32.ifc_len = i; - }else { -if (i <= ifc32.ifc_len) - ifc32.ifc_len = i; -else - ifc32.ifc_len = i -sizeof (struct ifreq32 ); - } -if (copy_to_user (compat_ptr (arg), &ifc32,sizeof (struct ifconf32 ))) -return -EFAULT ; - -return 0 ; -} - -static int ethtool_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ifreq __user *ifr; -struct ifreq32 __user *ifr32; -u32 data; -void __user *datap; - - ifr =compat_alloc_user_space (sizeof (*ifr)); - ifr32 =compat_ptr (arg); - -if (copy_in_user (&ifr->ifr_name, &ifr32->ifr_name,IFNAMSIZ )) -return -EFAULT ; - -if (get_user (data, &ifr32->ifr_ifru.ifru_data)) -return -EFAULT ; - - datap =compat_ptr (data); -if (put_user (datap, &ifr->ifr_ifru.ifru_data)) -return -EFAULT ; - -return sys_ioctl (fd, cmd, (unsigned long ) ifr); -} - -static int bond_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ifreq kifr; -struct ifreq __user *uifr; -struct ifreq32 __user *ifr32 =compat_ptr (arg); -mm_segment_t old_fs; -int err; -u32 data; -void __user *datap; - -switch (cmd) { -case SIOCBONDENSLAVE : -case SIOCBONDRELEASE : -case SIOCBONDSETHWADDR : -case SIOCBONDCHANGEACTIVE : -if (copy_from_user (&kifr, ifr32,sizeof (struct ifreq32 ))) -return -EFAULT ; - - old_fs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kifr); -set_fs (old_fs); - -return err; -case SIOCBONDSLAVEINFOQUERY : -case SIOCBONDINFOQUERY : - uifr =compat_alloc_user_space (sizeof (*uifr)); -if (copy_in_user (&uifr->ifr_name, &ifr32->ifr_name,IFNAMSIZ )) -return -EFAULT ; - -if (get_user (data, &ifr32->ifr_ifru.ifru_data)) -return -EFAULT ; - - datap =compat_ptr (data); -if (put_user (datap, &uifr->ifr_ifru.ifru_data)) -return -EFAULT ; - -return sys_ioctl (fd, cmd, (unsigned long )uifr); -default : -return -EINVAL ; - }; -} - -int siocdevprivate_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ifreq __user *u_ifreq64; -struct ifreq32 __user *u_ifreq32 =compat_ptr (arg); -char tmp_buf[IFNAMSIZ ]; -void __user *data64; -u32 data32; - -if (copy_from_user (&tmp_buf[0 ], &(u_ifreq32->ifr_ifrn.ifrn_name[0 ]), -IFNAMSIZ )) -return -EFAULT ; -if (__get_user (data32, &u_ifreq32->ifr_ifru.ifru_data)) -return -EFAULT ; - data64 =compat_ptr (data32); - - u_ifreq64 =compat_alloc_user_space (sizeof (*u_ifreq64)); - -/* Don't check these user accesses, just let that get trapped -* in the ioctl handler instead. -*/ -if (copy_to_user (&u_ifreq64->ifr_ifrn.ifrn_name[0 ], &tmp_buf[0 ], -IFNAMSIZ )) -return -EFAULT ; -if (__put_user (data64, &u_ifreq64->ifr_ifru.ifru_data)) -return -EFAULT ; - -return sys_ioctl (fd, cmd, (unsigned long ) u_ifreq64); -} - -static int dev_ifsioc (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ifreq ifr; -struct ifreq32 __user *uifr32; -struct ifmap32 __user *uifmap32; -mm_segment_t old_fs; -int err; - - uifr32 =compat_ptr (arg); - uifmap32 = &uifr32->ifr_ifru.ifru_map; -switch (cmd) { -case SIOCSIFMAP : - err =copy_from_user (&ifr, uifr32,sizeof (ifr.ifr_name)); - err |=__get_user (ifr.ifr_map.mem_start, &uifmap32->mem_start); - err |=__get_user (ifr.ifr_map.mem_end, &uifmap32->mem_end); - err |=__get_user (ifr.ifr_map.base_addr, &uifmap32->base_addr); - err |=__get_user (ifr.ifr_map.irq, &uifmap32->irq); - err |=__get_user (ifr.ifr_map.dma, &uifmap32->dma); - err |=__get_user (ifr.ifr_map.port, &uifmap32->port); -if (err) -return -EFAULT ; -break ; -default : -if (copy_from_user (&ifr, uifr32,sizeof (*uifr32))) -return -EFAULT ; -break ; - } - old_fs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&ifr); -set_fs (old_fs); -if (!err) { -switch (cmd) { -/* TUNSETIFF is defined as _IOW, it should be _IORW -* as the data is copied back to user space, but that -* cannot be fixed without breaking all existing apps. -*/ -case TUNSETIFF : -case SIOCGIFFLAGS : -case SIOCGIFMETRIC : -case SIOCGIFMTU : -case SIOCGIFMEM : -case SIOCGIFHWADDR : -case SIOCGIFINDEX : -case SIOCGIFADDR : -case SIOCGIFBRDADDR : -case SIOCGIFDSTADDR : -case SIOCGIFNETMASK : -case SIOCGIFTXQLEN : -if (copy_to_user (uifr32, &ifr,sizeof (*uifr32))) -return -EFAULT ; -break ; -case SIOCGIFMAP : - err =copy_to_user (uifr32, &ifr,sizeof (ifr.ifr_name)); - err |=__put_user (ifr.ifr_map.mem_start, &uifmap32->mem_start); - err |=__put_user (ifr.ifr_map.mem_end, &uifmap32->mem_end); - err |=__put_user (ifr.ifr_map.base_addr, &uifmap32->base_addr); - err |=__put_user (ifr.ifr_map.irq, &uifmap32->irq); - err |=__put_user (ifr.ifr_map.dma, &uifmap32->dma); - err |=__put_user (ifr.ifr_map.port, &uifmap32->port); -if (err) - err = -EFAULT ; -break ; - } - } -return err; -} - -struct rtentry32 { -u32 rt_pad1; -struct sockaddr rt_dst;/* target address */ -struct sockaddr rt_gateway;/* gateway addr (RTF_GATEWAY) */ -struct sockaddr rt_genmask;/* target network mask (IP) */ -unsigned short rt_flags; -short rt_pad2; -u32 rt_pad3; -unsigned char rt_tos; -unsigned char rt_class; -short rt_pad4; -short rt_metric;/* +1 for binary compatibility! */ -/* char * */ u32 rt_dev;/* forcing the device at add */ -u32 rt_mtu;/* per route MTU/Window */ -u32 rt_window;/* Window clamping */ -unsigned short rt_irtt;/* Initial RTT */ - -}; - -struct in6_rtmsg32 { -struct in6_addr rtmsg_dst; -struct in6_addr rtmsg_src; -struct in6_addr rtmsg_gateway; -u32 rtmsg_type; -u16 rtmsg_dst_len; -u16 rtmsg_src_len; -u32 rtmsg_metric; -u32 rtmsg_info; -u32 rtmsg_flags; -s32 rtmsg_ifindex; -}; - -static int routing_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -int ret; -void *r =NULL ; -struct in6_rtmsg r6; -struct rtentry r4; -char devname[16 ]; -u32 rtdev; -mm_segment_t old_fs =get_fs (); - -struct socket *mysock =sockfd_lookup (fd, &ret); - -if (mysock && mysock->sk && mysock->sk->sk_family ==AF_INET6 ) {/* ipv6 */ -struct in6_rtmsg32 __user *ur6 =compat_ptr (arg); - ret =copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst), -3 *sizeof (struct in6_addr )); - ret |=__get_user (r6.rtmsg_type, &(ur6->rtmsg_type)); - ret |=__get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len)); - ret |=__get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len)); - ret |=__get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric)); - ret |=__get_user (r6.rtmsg_info, &(ur6->rtmsg_info)); - ret |=__get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags)); - ret |=__get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex)); - - r = (void *) &r6; - }else {/* ipv4 */ -struct rtentry32 __user *ur4 =compat_ptr (arg); - ret =copy_from_user (&r4.rt_dst, &(ur4->rt_dst), -3 *sizeof (struct sockaddr )); - ret |=__get_user (r4.rt_flags, &(ur4->rt_flags)); - ret |=__get_user (r4.rt_metric, &(ur4->rt_metric)); - ret |=__get_user (r4.rt_mtu, &(ur4->rt_mtu)); - ret |=__get_user (r4.rt_window, &(ur4->rt_window)); - ret |=__get_user (r4.rt_irtt, &(ur4->rt_irtt)); - ret |=__get_user (rtdev, &(ur4->rt_dev)); -if (rtdev) { - ret |=copy_from_user (devname,compat_ptr (rtdev),15 ); - r4.rt_dev = devname; devname[15 ] =0 ; - }else - r4.rt_dev =NULL ; - - r = (void *) &r4; - } - -if (ret) { - ret = -EFAULT ; - goto out; - } - -set_fs (KERNEL_DS ); - ret =sys_ioctl (fd, cmd, (unsigned long ) r); -set_fs (old_fs); - -out: -if (mysock) -sockfd_put (mysock); - -return ret; -} -#endif -struct hd_geometry32 {unsigned char heads;unsigned char sectors;
@@ -1146,127 +744,6 @@return err; } -struct sock_fprog32 { -unsigned short len; -compat_caddr_t filter; -}; - -#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32) -#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32) - -static int ppp_sock_fprog_ioctl_trans (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct sock_fprog32 __user *u_fprog32 =compat_ptr (arg); -struct sock_fprog __user *u_fprog64 =compat_alloc_user_space (sizeof (struct sock_fprog )); -void __user *fptr64; -u32 fptr32; -u16 flen; - -if (get_user (flen, &u_fprog32->len) || -get_user (fptr32, &u_fprog32->filter)) -return -EFAULT ; - - fptr64 =compat_ptr (fptr32); - -if (put_user (flen, &u_fprog64->len) || -put_user (fptr64, &u_fprog64->filter)) -return -EFAULT ; - -if (cmd ==PPPIOCSPASS32 ) - cmd =PPPIOCSPASS ; -else - cmd =PPPIOCSACTIVE ; - -return sys_ioctl (fd, cmd, (unsigned long ) u_fprog64); -} - -struct ppp_option_data32 { -compat_caddr_t ptr; -u32 length; -compat_int_t transmit; -}; -#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32) - -struct ppp_idle32 { -compat_time_t xmit_idle; -compat_time_t recv_idle; -}; -#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32) - -static int ppp_gidle (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ppp_idle __user *idle; -struct ppp_idle32 __user *idle32; -__kernel_time_t xmit, recv; -int err; - - idle =compat_alloc_user_space (sizeof (*idle)); - idle32 =compat_ptr (arg); - - err =sys_ioctl (fd,PPPIOCGIDLE , (unsigned long ) idle); - -if (!err) { -if (get_user (xmit, &idle->xmit_idle) || -get_user (recv, &idle->recv_idle) || -put_user (xmit, &idle32->xmit_idle) || -put_user (recv, &idle32->recv_idle)) - err = -EFAULT ; - } -return err; -} - -static int ppp_scompress (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ppp_option_data __user *odata; -struct ppp_option_data32 __user *odata32; -__u32 data; -void __user *datap; - - odata =compat_alloc_user_space (sizeof (*odata)); - odata32 =compat_ptr (arg); - -if (get_user (data, &odata32->ptr)) -return -EFAULT ; - - datap =compat_ptr (data); -if (put_user (datap, &odata->ptr)) -return -EFAULT ; - -if (copy_in_user (&odata->length, &odata32->length, -sizeof (__u32) +sizeof (int ))) -return -EFAULT ; - -return sys_ioctl (fd,PPPIOCSCOMPRESS , (unsigned long ) odata); -} - -static int ppp_ioctl_trans (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -int err; - -switch (cmd) { -case PPPIOCGIDLE32 : - err =ppp_gidle (fd, cmd, arg); -break ; - -case PPPIOCSCOMPRESS32 : - err =ppp_scompress (fd, cmd, arg); -break ; - -default : -do { -static int count; -if (++count <=20 ) -printk ("ppp_ioctl: Unknown cmd fd(%d) " -"cmd(%08x) arg(%08x)\n" , - (int )fd, (unsigned int )cmd, (unsigned int )arg); - }while (0 ); - err = -EINVAL ; -break ; - }; - -return err; -} -struct mtget32 {compat_long_t mt_type;
@@ -1664,171 +1141,6 @@return err; } -struct atmif_sioc32 { -compat_int_t number; -compat_int_t length; -compat_caddr_t arg; -}; - -struct atm_iobuf32 { -compat_int_t length; -compat_caddr_t buffer; -}; - -#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32) -#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32) -#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32) -#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32) -#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32) -#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32) -#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32) -#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32) -#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32) -#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32) -#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32) -#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32) -#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32) -#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32) -#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32) -#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32) -#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32) - -static struct { -unsigned int cmd32; -unsigned int cmd; -} atm_ioctl_map[] = { - {ATM_GETLINKRATE32 ,ATM_GETLINKRATE }, - {ATM_GETNAMES32 ,ATM_GETNAMES }, - {ATM_GETTYPE32 ,ATM_GETTYPE }, - {ATM_GETESI32 ,ATM_GETESI }, - {ATM_GETADDR32 ,ATM_GETADDR }, - {ATM_RSTADDR32 ,ATM_RSTADDR }, - {ATM_ADDADDR32 ,ATM_ADDADDR }, - {ATM_DELADDR32 ,ATM_DELADDR }, - {ATM_GETCIRANGE32 ,ATM_GETCIRANGE }, - {ATM_SETCIRANGE32 ,ATM_SETCIRANGE }, - {ATM_SETESI32 ,ATM_SETESI }, - {ATM_SETESIF32 ,ATM_SETESIF }, - {ATM_GETSTAT32 ,ATM_GETSTAT }, - {ATM_GETSTATZ32 ,ATM_GETSTATZ }, - {ATM_GETLOOP32 ,ATM_GETLOOP }, - {ATM_SETLOOP32 ,ATM_SETLOOP }, - {ATM_QUERYLOOP32 ,ATM_QUERYLOOP } -}; - -#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0])) - - -static int do_atm_iobuf (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct atm_iobuf __user *iobuf; -struct atm_iobuf32 __user *iobuf32; -u32 data; -void __user *datap; -int len, err; - - iobuf =compat_alloc_user_space (sizeof (*iobuf)); - iobuf32 =compat_ptr (arg); - -if (get_user (len, &iobuf32->length) || -get_user (data, &iobuf32->buffer)) -return -EFAULT ; - datap =compat_ptr (data); -if (put_user (len, &iobuf->length) || -put_user (datap, &iobuf->buffer)) -return -EFAULT ; - - err =sys_ioctl (fd, cmd, (unsigned long )iobuf); - -if (!err) { -if (copy_in_user (&iobuf32->length, &iobuf->length, -sizeof (int ))) - err = -EFAULT ; - } - -return err; -} - -static int do_atmif_sioc (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct atmif_sioc __user *sioc; -struct atmif_sioc32 __user *sioc32; -u32 data; -void __user *datap; -int err; - - sioc =compat_alloc_user_space (sizeof (*sioc)); - sioc32 =compat_ptr (arg); - -if (copy_in_user (&sioc->number, &sioc32->number,2 *sizeof (int )) || -get_user (data, &sioc32->arg)) -return -EFAULT ; - datap =compat_ptr (data); -if (put_user (datap, &sioc->arg)) -return -EFAULT ; - - err =sys_ioctl (fd, cmd, (unsigned long ) sioc); - -if (!err) { -if (copy_in_user (&sioc32->length, &sioc->length, -sizeof (int ))) - err = -EFAULT ; - } -return err; -} - -static int do_atm_ioctl (unsigned int fd,unsigned int cmd32,unsigned long arg) -{ -int i; -unsigned int cmd =0 ; - -switch (cmd32) { -case SONET_GETSTAT : -case SONET_GETSTATZ : -case SONET_GETDIAG : -case SONET_SETDIAG : -case SONET_CLRDIAG : -case SONET_SETFRAMING : -case SONET_GETFRAMING : -case SONET_GETFRSENSE : -return do_atmif_sioc (fd, cmd32, arg); - } - -for (i =0 ; i <NR_ATM_IOCTL ; i++) { -if (cmd32 == atm_ioctl_map[i].cmd32) { - cmd = atm_ioctl_map[i].cmd; -break ; - } - } -if (i ==NR_ATM_IOCTL ) -return -EINVAL ; - -switch (cmd) { -case ATM_GETNAMES : -return do_atm_iobuf (fd, cmd, arg); - -case ATM_GETLINKRATE : -case ATM_GETTYPE : -case ATM_GETESI : -case ATM_GETADDR : -case ATM_RSTADDR : -case ATM_ADDADDR : -case ATM_DELADDR : -case ATM_GETCIRANGE : -case ATM_SETCIRANGE : -case ATM_SETESI : -case ATM_SETESIF : -case ATM_GETSTAT : -case ATM_GETSTATZ : -case ATM_GETLOOP : -case ATM_SETLOOP : -case ATM_QUERYLOOP : -return do_atmif_sioc (fd, cmd, arg); - } - -return -EINVAL ; -} - static __attribute_used__ intret_einval (unsigned int fd,unsigned int cmd,unsigned long arg) {
@@ -2641,65 +1953,6 @@return sys_ioctl (fd, cmd, (unsigned long )tdata); } -struct compat_iw_point { -compat_caddr_t pointer; -__u16 length; -__u16 flags; -}; - -static int do_wireless_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct iwreq __user *iwr; -struct iwreq __user *iwr_u; -struct iw_point __user *iwp; -struct compat_iw_point __user *iwp_u; -compat_caddr_t pointer; -__u16 length, flags; - - iwr_u =compat_ptr (arg); - iwp_u = (struct compat_iw_point __user *) &iwr_u->u.data; - iwr =compat_alloc_user_space (sizeof (*iwr)); -if (iwr ==NULL ) -return -ENOMEM ; - - iwp = &iwr->u.data; - -if (!access_ok (VERIFY_WRITE , iwr,sizeof (*iwr))) -return -EFAULT ; - -if (__copy_in_user (&iwr->ifr_ifrn.ifrn_name[0 ], - &iwr_u->ifr_ifrn.ifrn_name[0 ], -sizeof (iwr->ifr_ifrn.ifrn_name))) -return -EFAULT ; - -if (__get_user (pointer, &iwp_u->pointer) || -__get_user (length, &iwp_u->length) || -__get_user (flags, &iwp_u->flags)) -return -EFAULT ; - -if (__put_user (compat_ptr (pointer), &iwp->pointer) || -__put_user (length, &iwp->length) || -__put_user (flags, &iwp->flags)) -return -EFAULT ; - -return sys_ioctl (fd, cmd, (unsigned long ) iwr); -} - -/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE -* for some operations; this forces use of the newer bridge-utils that -* use compatiable ioctls -*/ -static int old_bridge_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -u32 tmp; - -if (get_user (tmp, (u32 __user *) arg)) -return -EFAULT ; -if (tmp ==BRCTL_GET_VERSION ) -return BRCTL_VERSION +1 ; -return -EINVAL ; -} - #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) struct ncp_ioctl_request_32 { u32 function;
@@ -2893,59 +2146,6 @@#ifdef DECLARES HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) -#ifdef CONFIG_NET -HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) -HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) -HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc) -HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) -HANDLE_IOCTL (SIOCSIFADDR , dev_ifsioc) - -/* ioctls used by appletalk ddp.c */ -HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCDIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSARP, dev_ifsioc) -HANDLE_IOCTL(SIOCDARP, dev_ifsioc) - -HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) -HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) -HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) -HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) -HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) -HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl) -HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl) -HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl) -HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl) -HANDLE_IOCTL(SIOCADDRT, routing_ioctl) -HANDLE_IOCTL(SIOCDELRT, routing_ioctl) -HANDLE_IOCTL(SIOCBRADDIF, dev_ifsioc) -HANDLE_IOCTL (SIOCBRDELIF , dev_ifsioc) -/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ -HANDLE_IOCTL(SIOCRTMSG, ret_einval) -HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) -#endif HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo) HANDLE_IOCTL(BLKRAGET, w_long)HANDLE_IOCTL (BLKGETSIZE , w_long)
@@ -2973,10 +2173,6 @@ HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans) HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) HANDLE_IOCTL(SG_IO,sg_ioctl_trans) -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) HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)HANDLE_IOCTL (CDROMREADAUDIO , cdrom_ioctl_trans)
@@ -3007,31 +2203,6 @@/* 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) -HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl) -HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl) -HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl) -HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl) -HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) -HANDLE_IOCTL (SONET_GETFRSENSE , do_atm_ioctl) /* block stuff */ HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)HANDLE_IOCTL (BLKBSZSET_32 , do_blkbszset)
@@ -3054,22 +2225,6 @@ HANDLE_IOCTL(I2C_FUNCS, w_long) HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) -/* wireless */ -HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) -HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE )HANDLE_IOCTL (NCP_IOC_NCPREQUEST_32 , do_ncp_ncprequest)
include/linux/compat_ioctl.h +0 -89
107 lines not on this page · raw message
net/compat.c +962 -0
971 lines not on this page · raw message
net/socket.c +4 -3
@@ -107,8 +107,6 @@static int sock_close (struct inode *inode,struct file *file);static unsigned int sock_poll (struct file *file,struct poll_table_struct *wait); -static long sock_ioctl (struct file *file, -unsigned int cmd,unsigned long arg);static int sock_fasync (int fd,struct file *filp,int on);static ssize_t sock_readv (struct file *file,const struct iovec *vector,unsigned long count,loff_t *ppos);
@@ -130,6 +128,9 @@ .aio_write = sock_aio_write, .poll = sock_poll, .unlocked_ioctl = sock_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_sock_ioctl, +#endif .mmap = sock_mmap, .open = sock_no_open, /* special open code to disallow open via /proc */ .release = sock_close,
@@ -834,7 +835,7 @@* what to do with it - that's up to the protocol still. */ -static long sock_ioctl (struct file *file,unsigned cmd,unsigned long arg) +long sock_ioctl (struct file *file,unsigned cmd,unsigned long arg) {struct socket *sock;void __user *argp = (void __user *)arg;
fs/compat.c +7 -13
@@ -27,7 +27,6 @@#include <linux/ioctl32.h> #include <linux/ioctl.h> #include <linux/init.h> -#include <linux/sockios.h> /* for SIOCDEVPRIVATE */ #include <linux/smb.h> #include <linux/smb_mount.h> #include <linux/ncp_mount.h>
@@ -46,8 +45,9 @@#include <linux/rwsem.h> #include <linux/acct.h> #include <linux/mm.h> - -#include <net/sock.h> /* siocdevprivate_ioctl */ +#include <linux/security.h> +#include <linux/highmem.h> +#include <linux/poll.h> #include <asm/uaccess.h> #include <asm/mmu_context.h>
@@ -346,6 +346,7 @@int error = -EBADF ;struct ioctl_trans *t;int fput_needed; +static int count; filp =fget_light (fd, &fput_needed);if (!filp)
@@ -394,16 +395,9 @@ goto found_handler; } -if (S_ISSOCK (filp->f_dentry->d_inode->i_mode) && - cmd >=SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE +15 )) { - error =siocdevprivate_ioctl (fd, cmd, arg); - }else { -static int count; - -if (++count <=50 ) -compat_ioctl_error (filp, fd, cmd, arg); - error = -EINVAL ; - } +if (++count <=50 ) +compat_ioctl_error (filp, fd, cmd, arg); + error = -EINVAL ; goto out_fput;
include/linux/socket.h +4 -0
@@ -299,6 +299,10 @@extern int move_addr_to_kernel (void __user *uaddr,int ulen,void *kaddr);extern int put_cmsg (struct msghdr *,int level,int type,int len,void *data); +struct file ; +extern long sock_ioctl (struct file *file,unsigned int cmd,unsigned long arg); +extern long compat_sock_ioctl (struct file *file,unsigned int cmd,unsigned long arg); +#endif #endif /* not kernel and not glibc */ #endif /* _LINUX_SOCKET_H */
include/net/sock.h +0 -9
@@ -1365,15 +1365,6 @@extern __u32 sysctl_wmem_max;extern __u32 sysctl_rmem_max; -#ifdef CONFIG_NET -int siocdevprivate_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg); -#else -static inline int siocdevprivate_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -return -ENODEV ; -} -#endif -extern void sk_init (void );#ifdef CONFIG_SYSCTL
include/linux/net.h +2 -0
@@ -142,6 +142,8 @@ struct poll_table_struct *wait);int (*ioctl) (struct socket *sock,unsigned int cmd,unsigned long arg); +int (*compat_ioctl)(struct socket *sock,unsigned int cmd, +unsigned long arg);int (*listen) (struct socket *sock,int len);int (*shutdown) (struct socket *sock,int flags); int (*setsockopt)(struct socket *sock, int level,
--
Arnd Bergmann
maintainerPATCH 3/25 net: improve ioctl32 dev_ioctl handling
In reply to Arnd BergmannThis patch tries to be a bit smarter about net device ioctl emulation. In particular, the wireless extensions are treated as a group in order to make the switch list a little shorter.
net/compat.c +58 -87
@@ -854,7 +854,7 @@if (__put_user (data64, &u_ifreq64->ifr_ifru.ifru_data))return -EFAULT ; -return sock_ioctl (file, cmd, (unsigned long ) u_ifreq64); +return dev_ioctl (cmd, u_ifreq64); }static int dev_ifsioc (struct file *file,unsigned int cmd,unsigned long arg)
@@ -1302,13 +1302,14 @@return err; } +#ifdef WIRELESS_EXT struct compat_iw_point {compat_caddr_t pointer;__u16 length;__u16 flags; }; -static int do_wireless_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +static int do_wireless_ioctl (unsigned int cmd,unsigned long arg) {struct iwreq __user *iwr;struct iwreq __user *iwr_u;
@@ -1343,8 +1344,9 @@ __put_user(flags, &iwp->flags))return -EFAULT ; -return sock_ioctl (file, cmd, (unsigned long ) iwr); + return dev_ioctl(cmd, iwr); } +#endif /* WIRELESS_EXT */ /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE * for some operations; this forces use of the newer bridge-utils that
@@ -1363,16 +1365,43 @@long compat_sock_ioctl (struct file *file,unsigned int cmd,unsigned long arg) { -if (cmd >=SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE +15 )) -return siocdevprivate_ioctl (file, cmd, arg); +struct socket *sock; +int ret = -ENOIOCTLCMD ; -switch (cmd) { + sock = file->private_data; +if (cmd >=SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE +15 )) + ret =siocdevprivate_ioctl (file, cmd, arg); +#ifdef WIRELESS_EXT + else if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) + ret =do_wireless_ioctl (cmd, arg); +#endif + else switch (cmd) {#define HANDLE_IOCTL (type, handler) \ - case type: return handler(file, cmd, arg); + case type: ret = handler(file, cmd, arg); break;#define COMPATIBLE_IOCTL (type) \ - case type: return sock_ioctl(file, cmd, arg); + case type: ret = sock_ioctl(file, cmd, arg); break;#define INVAL_IOCTL (type) \ - case type: return -EINVAL; + case type: ret = -EINVAL; break; +/* these are handled in sock_ioctl */ +COMPATIBLE_IOCTL (FIOSETOWN) +COMPATIBLE_IOCTL (SIOCSPGRP ) +COMPATIBLE_IOCTL (FIOGETOWN ) +COMPATIBLE_IOCTL (SIOCGPGRP ) +HANDLE_IOCTL (SIOCSIFBR , old_bridge_ioctl) +HANDLE_IOCTL (SIOCGIFBR , old_bridge_ioctl) +COMPATIBLE_IOCTL (SIOCBRADDBR ) +COMPATIBLE_IOCTL (SIOCBRDELBR ) +COMPATIBLE_IOCTL (SIOCGIFVLAN ) +COMPATIBLE_IOCTL (SIOCSIFVLAN ) +COMPATIBLE_IOCTL (SIOCADDDLCI ) +COMPATIBLE_IOCTL (SIOCDELDLCI ) + default: + if (sock->ops->compat_ioctl) + ret = sock->ops->compat_ioctl (sock, cmd, arg); + } + +if (ret == -ENOIOCTLCMD ) +switch (cmd) { HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)HANDLE_IOCTL (SIOCGIFFLAGS , dev_ifsioc)
@@ -1393,10 +1422,6 @@ HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) -/* ioctls used by appletalk ddp.c */ -HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCDIFADDR, dev_ifsioc) - HANDLE_IOCTL(SIOCSARP, dev_ifsioc)HANDLE_IOCTL (SIOCDARP , dev_ifsioc)
@@ -1456,79 +1481,6 @@ HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) -/* wireless */ -HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) -HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) -HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) -HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) - -COMPATIBLE_IOCTL(FIOSETOWN) -COMPATIBLE_IOCTL(SIOCSPGRP) -COMPATIBLE_IOCTL(FIOGETOWN) -COMPATIBLE_IOCTL(SIOCGPGRP) -COMPATIBLE_IOCTL(SIOCATMARK) -COMPATIBLE_IOCTL(SIOCSIFLINK) -COMPATIBLE_IOCTL(SIOCSIFENCAP) -COMPATIBLE_IOCTL(SIOCGIFENCAP) -COMPATIBLE_IOCTL(SIOCSIFNAME) -//COMPATIBLE_IOCTL(SIOCSARP) -COMPATIBLE_IOCTL(SIOCGARP) -//COMPATIBLE_IOCTL(SIOCDARP) -COMPATIBLE_IOCTL(SIOCSRARP) -COMPATIBLE_IOCTL(SIOCGRARP) -COMPATIBLE_IOCTL(SIOCDRARP) -COMPATIBLE_IOCTL(SIOCADDDLCI) -COMPATIBLE_IOCTL(SIOCDELDLCI) -COMPATIBLE_IOCTL(SIOCGMIIPHY) -COMPATIBLE_IOCTL(SIOCGMIIREG) -COMPATIBLE_IOCTL(SIOCSMIIREG) -COMPATIBLE_IOCTL(SIOCGIFVLAN) -COMPATIBLE_IOCTL(SIOCSIFVLAN) -COMPATIBLE_IOCTL(SIOCBRADDBR) -COMPATIBLE_IOCTL(SIOCBRDELBR) -/* wireless */ -COMPATIBLE_IOCTL(SIOCSIWCOMMIT) -COMPATIBLE_IOCTL(SIOCGIWNAME) -COMPATIBLE_IOCTL(SIOCSIWNWID) -COMPATIBLE_IOCTL(SIOCGIWNWID) -COMPATIBLE_IOCTL(SIOCSIWFREQ) -COMPATIBLE_IOCTL(SIOCGIWFREQ) -COMPATIBLE_IOCTL(SIOCSIWMODE) -COMPATIBLE_IOCTL(SIOCGIWMODE) -COMPATIBLE_IOCTL(SIOCSIWSENS) -COMPATIBLE_IOCTL(SIOCGIWSENS) -COMPATIBLE_IOCTL(SIOCSIWRANGE) -COMPATIBLE_IOCTL(SIOCSIWPRIV) -COMPATIBLE_IOCTL(SIOCGIWPRIV) -COMPATIBLE_IOCTL(SIOCSIWSTATS) -COMPATIBLE_IOCTL(SIOCGIWSTATS) -COMPATIBLE_IOCTL(SIOCSIWAP) -COMPATIBLE_IOCTL(SIOCGIWAP) -COMPATIBLE_IOCTL(SIOCSIWSCAN) -COMPATIBLE_IOCTL(SIOCSIWRATE) -COMPATIBLE_IOCTL(SIOCGIWRATE) -COMPATIBLE_IOCTL(SIOCSIWRTS) -COMPATIBLE_IOCTL(SIOCGIWRTS) -COMPATIBLE_IOCTL(SIOCSIWFRAG) -COMPATIBLE_IOCTL(SIOCGIWFRAG) -COMPATIBLE_IOCTL(SIOCSIWTXPOW) -COMPATIBLE_IOCTL(SIOCGIWTXPOW) -COMPATIBLE_IOCTL(SIOCSIWRETRY) -COMPATIBLE_IOCTL(SIOCGIWRETRY) -COMPATIBLE_IOCTL(SIOCSIWPOWER) -COMPATIBLE_IOCTL(SIOCGIWPOWER) -/* PPP stuff */ COMPATIBLE_IOCTL(PPPIOCGFLAGS) COMPATIBLE_IOCTL(PPPIOCSFLAGS) COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
@@ -1561,6 +1513,25 @@/* PPPOX */ COMPATIBLE_IOCTL(PPPOEIOCSFWD) COMPATIBLE_IOCTL(PPPOEIOCDFWD) + +/* ioctls used by appletalk ddp.c */ +HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCDIFADDR, dev_ifsioc) + +COMPATIBLE_IOCTL(SIOCATMARK) +COMPATIBLE_IOCTL(SIOCSIFLINK) +COMPATIBLE_IOCTL(SIOCSIFENCAP) +COMPATIBLE_IOCTL(SIOCGIFENCAP) +COMPATIBLE_IOCTL(SIOCSIFNAME) +//COMPATIBLE_IOCTL(SIOCSARP) +COMPATIBLE_IOCTL(SIOCGARP) +//COMPATIBLE_IOCTL(SIOCDARP) +COMPATIBLE_IOCTL(SIOCSRARP) +COMPATIBLE_IOCTL(SIOCGRARP) +COMPATIBLE_IOCTL(SIOCDRARP) +COMPATIBLE_IOCTL(SIOCGMIIPHY) +COMPATIBLE_IOCTL(SIOCGMIIREG) +COMPATIBLE_IOCTL(SIOCSMIIREG) } -return -ENOIOCTLCMD ; + return ret; }
--
Arnd Bergmann
maintainerPATCH 4/25 net: move atm ioctl32 to net/atm/ioctl.c
In reply to Arnd BergmannThis moves all the ATM specific compat ioctls to net/atm. The code is still the same as before, but it would probably be a good idea to simplify this by getting rid of using compat_alloc_user_space.
net/atm/common.h +1 -0
@@ -19,6 +19,7 @@ size_t total_len);unsigned int vcc_poll (struct file *file,struct socket *sock,poll_table *wait);int vcc_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg); +int vcc_compat_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int vcc_setsockopt (struct socket *sock,int level,int optname,char __user *optval,int optlen); int vcc_getsockopt(struct socket *sock, int level, int optname,
net/atm/ioctl.c +167 -0
170 lines not on this page · raw message
net/atm/pvc.c +3 -0
@@ -114,6 +114,9 @@ .getname = pvc_getname, .poll = vcc_poll, .ioctl = vcc_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = vcc_compat_ioctl, +#endif .listen = sock_no_listen, .shutdown = pvc_shutdown, .setsockopt = pvc_setsockopt,
net/atm/svc.c +3 -0
@@ -625,6 +625,9 @@ .getname = svc_getname, .poll = vcc_poll, .ioctl = svc_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = vcc_compat_ioctl, +#endif .listen = svc_listen, .shutdown = svc_shutdown, .setsockopt = svc_setsockopt,
net/compat.c +2 -193
219 lines not on this page · raw message
--
Arnd Bergmann
maintainerPATCH 5/25 net: move ppp specific ioctl32 handlers
In reply to Arnd BergmannThis moves all ioctl32 code for ppp close to the
native ioctl implementation.
Index: linux-2.6.14-rc/drivers/net/ppp_generic.c
=================================--- linux-2.6.14-rc.orig/drivers/net/ppp_generic.c 2005-11-05 02:41:10.000000000 +0100
+++ linux-2.6.14-rc/drivers/net/ppp_generic.c 2005-11-05 02:41:29.000000000 +0100
@@ -46,6 +46,8 @@
#include <linux/rwsem.h>
#include <linux/stddef.h>
#include <linux/device.h>
+#include <linux/compat.h>
+
#include <net/slhc_vj.h>
#include <asm/atomic.h>
@@ -837,12 +839,189 @@
return err;
}
+#ifdef CONFIG_COMPAT
+/* FIXME: These could be better integrated into the driver */
+
+struct sock_fprog32 {
+ unsigned short len;
+ compat_caddr_t filter;
+};
+
+#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
+#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
+
+static int ppp_sock_fprog_ioctl_trans(struct file *file, unsigned int cmd, unsigned long arg) +{
+ struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
+ struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
+ void __user *fptr64;
+ u32 fptr32;
+ u16 flen;
+
+ if (get_user(flen, &u_fprog32->len) ||
+ get_user(fptr32, &u_fprog32->filter))
+ return -EFAULT;
+
+ fptr64 = compat_ptr(fptr32);
+
+ if (put_user(flen, &u_fprog64->len) ||
+ put_user(fptr64, &u_fprog64->filter))
+ return -EFAULT;
+
+ if (cmd = PPPIOCSPASS32)
+ cmd = PPPIOCSPASS;
+ else
+ cmd = PPPIOCSACTIVE;
+
+ return ppp_ioctl(file->f_dentry->d_inode, file, cmd,
+ (unsigned long) u_fprog64);
+}
+
+struct ppp_option_data32 {
+ compat_caddr_t ptr;
+ u32 length;
+ compat_int_t transmit;
+};
+#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
+
+struct ppp_idle32 {
+ compat_time_t xmit_idle;
+ compat_time_t recv_idle;
+};
+#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
+
+static int ppp_gidle(struct file *file, unsigned int cmd, unsigned long arg) +{
+ struct ppp_idle __user *idle;
+ struct ppp_idle32 __user *idle32;
+ __kernel_time_t xmit, recv;
+ int err;
+
+ idle = compat_alloc_user_space(sizeof(*idle));
+ idle32 = compat_ptr(arg);
+
+ err = ppp_ioctl(file->f_dentry->d_inode, file, PPPIOCGIDLE, (unsigned long) idle);
+
+ if (!err) {
+ if (get_user(xmit, &idle->xmit_idle) || + get_user(recv, &idle->recv_idle) ||
+ put_user(xmit, &idle32->xmit_idle) ||
+ put_user(recv, &idle32->recv_idle))
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int ppp_scompress(struct file *file, unsigned int cmd, unsigned long arg) +{
+ struct ppp_option_data __user *odata;
+ struct ppp_option_data32 __user *odata32;
+ __u32 data;
+ void __user *datap;
+
+ odata = compat_alloc_user_space(sizeof(*odata));
+ odata32 = compat_ptr(arg);
+
+ if (get_user(data, &odata32->ptr))
+ return -EFAULT;
+
+ datap = compat_ptr(data);
+ if (put_user(datap, &odata->ptr))
+ return -EFAULT;
+
+ if (copy_in_user(&odata->length, &odata32->length,
+ sizeof(__u32) + sizeof(int)))
+ return -EFAULT;
+
+ return ppp_ioctl(file->f_dentry->d_inode, file, PPPIOCSCOMPRESS, (unsigned long) odata);
+}
+
+static int ppp_ioctl_trans(struct file *file, unsigned int cmd, unsigned long arg) +{
+ int err;
+
+ switch (cmd) {
+ case PPPIOCGIDLE32:
+ err = ppp_gidle(file, cmd, arg);
+ break;
+
+ case PPPIOCSCOMPRESS32:
+ err = ppp_scompress(file, cmd, arg);
+ break;
+
+ default:
+ do {
+ static int count;
+ if (++count <= 20)
+ printk("ppp_ioctl: Unknown cmd(%08x) arg(%08x)\n",
+ (unsigned int)cmd, (unsigned int)arg);
+ } while(0);
+ err = -EINVAL;
+ break;
+ };
+
+ return err;
+}
+
+static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{
+ int ret;
+ ret = -ENOIOCTLCMD;
+
+ lock_kernel();
+ switch (cmd) {
+ case PPPIOCGIDLE32:
+ case PPPIOCSCOMPRESS32:
+ ret = ppp_ioctl_trans(file, cmd, arg);
+ break;
+
+ case PPPIOCSPASS32:
+ case PPPIOCSACTIVE32:
+ ret = ppp_sock_fprog_ioctl_trans(file, cmd, arg);
+ break;
+
+ case PPPIOCGFLAGS:
+ case PPPIOCSFLAGS:
+ case PPPIOCGASYNCMAP:
+ case PPPIOCSASYNCMAP:
+ case PPPIOCGUNIT:
+ case PPPIOCGRASYNCMAP:
+ case PPPIOCSRASYNCMAP:
+ case PPPIOCGMRU:
+ case PPPIOCSMRU:
+ case PPPIOCSMAXCID:
+ case PPPIOCGXASYNCMAP:
+ case PPPIOCSXASYNCMAP:
+ case PPPIOCXFERUNIT:
+ case PPPIOCGNPMODE:
+ case PPPIOCSNPMODE:
+ case PPPIOCGDEBUG:
+ case PPPIOCSDEBUG:
+ case PPPIOCNEWUNIT:
+ case PPPIOCATTACH:
+ case PPPIOCDETACH:
+ case PPPIOCSMRRU:
+ case PPPIOCCONNECT:
+ case PPPIOCDISCONN:
+ case PPPIOCATTCHAN:
+ case PPPIOCGCHAN:
+ ret = ppp_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+ break;
+ }
+ unlock_kernel();
+ return ret;
+}
+#endif
+
static struct file_operations ppp_device_fops = {
.owner = THIS_MODULE,
.read = ppp_read,
.write = ppp_write,
.poll = ppp_poll,
.ioctl = ppp_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ppp_compat_ioctl,
+#endif
.open = ppp_open,
.release = ppp_release
};
Index: linux-2.6.14-rc/net/compat.c
=================================--- linux-2.6.14-rc.orig/net/compat.c 2005-11-05 02:41:28.000000000 +0100
+++ linux-2.6.14-rc/net/compat.c 2005-11-05 02:41:29.000000000 +0100
@@ -1016,126 +1016,6 @@
return ret;
}
-struct sock_fprog32 {
- unsigned short len;
- compat_caddr_t filter;
-};
-
-#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
-#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
-
-static int ppp_sock_fprog_ioctl_trans(struct file *file, unsigned int cmd, unsigned long arg) -{
- struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
- struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
- void __user *fptr64;
- u32 fptr32;
- u16 flen;
-
- if (get_user(flen, &u_fprog32->len) ||
- get_user(fptr32, &u_fprog32->filter))
- return -EFAULT;
-
- fptr64 = compat_ptr(fptr32);
-
- if (put_user(flen, &u_fprog64->len) ||
- put_user(fptr64, &u_fprog64->filter))
- return -EFAULT;
-
- if (cmd = PPPIOCSPASS32)
- cmd = PPPIOCSPASS;
- else
- cmd = PPPIOCSACTIVE;
-
- return sock_ioctl(file, cmd, (unsigned long) u_fprog64);
-}
-
-struct ppp_option_data32 {
- compat_caddr_t ptr;
- u32 length;
- compat_int_t transmit;
-};
-#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
-
-struct ppp_idle32 {
- compat_time_t xmit_idle;
- compat_time_t recv_idle;
-};
-#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
-
-static int ppp_gidle(struct file *file, unsigned int cmd, unsigned long arg) -{
- struct ppp_idle __user *idle;
- struct ppp_idle32 __user *idle32;
- __kernel_time_t xmit, recv;
- int err;
-
- idle = compat_alloc_user_space(sizeof(*idle));
- idle32 = compat_ptr(arg);
-
- err = sock_ioctl(file, PPPIOCGIDLE, (unsigned long) idle);
-
- if (!err) {
- if (get_user(xmit, &idle->xmit_idle) || - get_user(recv, &idle->recv_idle) ||
- put_user(xmit, &idle32->xmit_idle) ||
- put_user(recv, &idle32->recv_idle))
- err = -EFAULT;
- }
- return err;
-}
-
-static int ppp_scompress(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct ppp_option_data __user *odata;
- struct ppp_option_data32 __user *odata32;
- __u32 data;
- void __user *datap;
-
- odata = compat_alloc_user_space(sizeof(*odata));
- odata32 = compat_ptr(arg);
-
- if (get_user(data, &odata32->ptr))
- return -EFAULT;
-
- datap = compat_ptr(data);
- if (put_user(datap, &odata->ptr))
- return -EFAULT;
-
- if (copy_in_user(&odata->length, &odata32->length,
- sizeof(__u32) + sizeof(int)))
- return -EFAULT;
-
- return sock_ioctl(file, PPPIOCSCOMPRESS, (unsigned long) odata);
-}
-
-static int ppp_ioctl_trans(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int err;
-
- switch (cmd) {
- case PPPIOCGIDLE32:
- err = ppp_gidle(file, cmd, arg);
- break;
-
- case PPPIOCSCOMPRESS32:
- err = ppp_scompress(file, cmd, arg);
- break;
-
- default:
- do {
- static int count;
- if (++count <= 20)
- printk("ppp_ioctl: Unknown cmd(%08x) arg(%08x)\n",
- (unsigned int)cmd, (unsigned int)arg);
- } while(0);
- err = -EINVAL;
- break;
- };
-
- return err;
-}
-
#ifdef WIRELESS_EXT
struct compat_iw_point {
compat_caddr_t pointer;
@@ -1283,40 +1163,6 @@
/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ INVAL_IOCTL(SIOCRTMSG)
HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
-/* ppp */
-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)
-COMPATIBLE_IOCTL(PPPIOCGFLAGS)
-COMPATIBLE_IOCTL(PPPIOCSFLAGS)
-COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGUNIT)
-COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGMRU)
-COMPATIBLE_IOCTL(PPPIOCSMRU)
-COMPATIBLE_IOCTL(PPPIOCSMAXCID)
-COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
-/* PPPIOCSCOMPRESS is translated */
-COMPATIBLE_IOCTL(PPPIOCGNPMODE)
-COMPATIBLE_IOCTL(PPPIOCSNPMODE)
-COMPATIBLE_IOCTL(PPPIOCGDEBUG)
-COMPATIBLE_IOCTL(PPPIOCSDEBUG)
-/* PPPIOCSPASS is translated */
-/* PPPIOCSACTIVE is translated */
-/* PPPIOCGIDLE is translated */
-COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
-COMPATIBLE_IOCTL(PPPIOCATTACH)
-COMPATIBLE_IOCTL(PPPIOCDETACH)
-COMPATIBLE_IOCTL(PPPIOCSMRRU)
-COMPATIBLE_IOCTL(PPPIOCCONNECT)
-COMPATIBLE_IOCTL(PPPIOCDISCONN)
-COMPATIBLE_IOCTL(PPPIOCATTCHAN)
-COMPATIBLE_IOCTL(PPPIOCGCHAN)
/* PPPOX */
COMPATIBLE_IOCTL(PPPOEIOCSFWD)
COMPATIBLE_IOCTL(PPPOEIOCDFWD)
--
Arnd Bergmann
maintainerPATCH 6/25 mtd: move ioctl32 code to mtdchar.c
In reply to Arnd BergmannThe MTD ioctls are all specific to mtdchar.c, so the compat code for them should be there as well.
Also, some of the ioctl commands used in that driver were previously not marked as compatible.
The conversion handlers could be further simplified by not using compat_alloc_user_space any more.
drivers/mtd/mtdchar.c +91 -3
@@ -6,6 +6,7 @@*/ #include <linux/config.h> +#include <linux/compat.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mtd/mtd.h>
@@ -300,8 +301,7 @@wake_up ((wait_queue_head_t *)instr->priv); } -static int mtd_ioctl (struct inode *inode,struct file *file, -u_int cmd,u_long arg) +static int mtd_do_ioctl (struct file *file,u_int cmd,u_long arg) {struct mtd_info *mtd =TO_MTD (file);void __user *argp = (void __user *)arg;
@@ -626,12 +626,100 @@return ret; }/* memory_ioctl */ +static long mtd_ioctl (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +int ret; +lock_kernel (); + ret =mtd_do_ioctl (file, cmd, arg); +unlock_kernel (); +return ret; +} + +#ifdef CONFIG_COMPAT +struct mtd_oob_buf32 { +u_int32_t start; +u_int32_t length; +compat_caddr_t ptr;/* unsigned char* */ +}; + +#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32) +#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32) + +static int compat_mtd_rw_oob (struct file *file,unsigned int cmd,unsigned long arg) +{ +struct mtd_oob_buf __user *buf =compat_alloc_user_space (sizeof (*buf)); +struct mtd_oob_buf32 __user *buf32 =compat_ptr (arg); +u32 data; +char __user *datap; +unsigned int real_cmd; +int err; + + real_cmd = (cmd ==MEMREADOOB32 ) ? +MEMREADOOB :MEMWRITEOOB ; + +if (copy_in_user (&buf->start, &buf32->start, +2 *sizeof (u32)) || +get_user (data, &buf32->ptr)) +return -EFAULT ; + datap =compat_ptr (data); +if (put_user (datap, &buf->ptr)) +return -EFAULT ; + + err =mtd_do_ioctl (file, real_cmd, (unsigned long ) buf); + +if (!err) { +if (copy_in_user (&buf32->start, &buf->start, +2 *sizeof (u32))) + err = -EFAULT ; + } + +return err; +} + +static long compat_mtd_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +int ret = -ENOIOCTLCMD ; + +lock_kernel (); +switch (cmd) { +case MEMWRITEOOB32 : +case MEMREADOOB32 : + ret =compat_mtd_rw_oob (file, cmd, arg); +break ; + +case MEMGETINFO : +case MEMERASE : +case MEMLOCK : +case MEMUNLOCK : +case MEMGETREGIONCOUNT : +case MEMGETREGIONINFO : +case MEMSETOOBSEL : +case MEMGETOOBSEL : +case MEMGETBADBLOCK : +case MEMSETBADBLOCK : +case OTPSELECT : +case OTPGETREGIONCOUNT : +case OTPGETREGIONINFO : +case OTPLOCK : + ret =mtd_do_ioctl (file, cmd, arg); +break ; + } +unlock_kernel (); + +return ret; +} +#endif +static struct file_operations mtd_fops = { .owner =THIS_MODULE , .llseek = mtd_lseek, .read = mtd_read, .write = mtd_write, - .ioctl = mtd_ioctl, + .unlocked_ioctl = mtd_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_mtd_ioctl, +#endif .open = mtd_open, .release = mtd_close, };
fs/compat_ioctl.c +0 -42
54 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -7
@@ -656,13 +656,6 @@ COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) -/* MTD */ -COMPATIBLE_IOCTL(MEMGETINFO) -COMPATIBLE_IOCTL(MEMERASE) -COMPATIBLE_IOCTL(MEMLOCK) -COMPATIBLE_IOCTL(MEMUNLOCK) -COMPATIBLE_IOCTL(MEMGETREGIONCOUNT) -COMPATIBLE_IOCTL(MEMGETREGIONINFO) /* NBD */ ULONG_IOCTL(NBD_SET_SOCK) ULONG_IOCTL(NBD_SET_BLKSIZE)
--
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 7 lines · Arnd Bergmann
The MTD ioctls are all specific to
mtdchar.c, so the compat code for them should be there as well.Also, some of the ioctl commands used in that driver were previously not marked as compatible.
Quoted 6 lines
The conversion handlers could be further simplified by not using
compat_alloc_user_spaceany more.
Moving crap over to mtdchar.c is a good thing. Complete removal of mtdchar.c might be even better, but at least the crap is relatively self-contained now.
Jörn
Signature · 3 lines
When in doubt, punt. When somebody actually complains, go back and fix it... The 90% solution is a good thing. -- Rob Landley
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 3 lines · Jörn Engel
Moving crap over to
mtdchar.cis a good thing. Complete removal ofmtdchar.cmight be even better, but at least the crap is relatively self-contained now.
Agreed moving the compat_ioctl to mtdchar now that it is possible sounds good.
I can see that argument with respect to mtdblock. But why would removal of mtdchar be a good thing? It is a simple raw access
interface. For those whose flash parts are too small for a filesystem
or when you are doing things that you can't do with a filesystem like making or checking it you need something like mtd char. For embedded folks who don't care you can just compile it out.
Eric
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 9 lines · Eric W. Biederman
Quoted 3 lines · Jörn Engel
Moving crap over to
mtdchar.cis a good thing. Complete removal ofmtdchar.cmight be even better, but at least the crap is relatively self-contained now.Agreed moving the
compat_ioctlto mtdchar now that it is possible sounds good.
Quoted 6 lines
I can see that argument with respect to mtdblock. But why would removal of mtdchar be a good thing? It is a simple raw access
interface. For those whose flash parts are too small for a filesystem
or when you are doing things that you can't do with a filesystem like making or checking it you need something like mtd char. For embedded folks who don't care you can just compile it out.
mtdchar.c is one of the worst drivers inside the kernel. The concept of having a simple char device driver for flash may have its charm, but the actual implementation is horrible. And things like the read-only devices are even unfixable.
mtdblock.c, while being quite a bit more complicated, does not require a ton of ioctls, will not confuse users with minor number 7 actually being device number 3 and magically being read-only despite unix permissions and hardware properties. Plus, it is just a file.
Can you name a few examples, where mtdchar.c makes sense? I've found it to be quite useless.
Jörn
Signature · 3 lines
A quarrel is quickly settled when deserted by one party; there is no battle unless there be two. -- Seneca
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 8 lines · Jörn Engel
Quoted 6 lines · Eric W. Biederman
I can see that argument with respect to mtdblock. But why would removal of mtdchar be a good thing? It is a simple raw access
interface. For those whose flash parts are too small for a filesystem
or when you are doing things that you can't do with a filesystem like making or checking it you need something like mtd char. For embedded folks who don't care you can just compile it out.
Quoted 4 lines
mtdchar.cis one of the worst drivers inside the kernel. The concept of having a simple char device driver for flash may have its charm, but the actual implementation is horrible. And things like the read-only devices are even unfixable.
Sucky implementation isn't a reason for removal. It's a reason to fix sucky implementation.
Quoted 8 lines
mtdblock.c, while being quite a bit more complicated, does not require a ton of ioctls, will not confuse users with minor number 7 actually being device number 3 and magically being read-only despite unix permissions and hardware properties. Plus, it is just a file.Can you name a few examples, where
mtdchar.cmakes sense? I've found it to be quite useless.
It allows users to write an image to a NAND device that has bad blocks and not totally screw it up. This is possible because of those ioctls. The mtdblock stuff knows nothing of this.
I do agree that the read-only devices don't make sense. The code itself probably needs work too. But until someone takes the time to make the mtdblock devices have equivalent functionality, mtdchar needs to stay.
(And mtdblock has it's own set of issues as well. I'd be happy to discuss them, but I think it would be offtopic for this thread.)
josh
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
In reply to Jörn EngelQuoted 2 lines · Jörn Engel
Can you name a few examples, where
mtdchar.cmakes sense? I've found it to be quite useless.
How do you access FLASH specific functionality otherwise ?
case MEMGETINFO:
....
case OTPLOCK:
It may be useless for you, but I doubt that you represent the majority of the MTD user base. Using a RAM simulator is a bit different to the usage of _real_ FLASH.
Look into mtd/utils and figure yourself why it _is_ useful.
The code _is_ ugly and ioctls are out of fashion, but your "remove it" request is just silly as long as you dont provide a reasonable alternative access to those bits.
tglx
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 4 lines · Thomas Gleixner
The code _is_ ugly and ioctls are out of fashion, but your "remove it" request is just silly as long as you dont provide a reasonable alternative access to those bits.
You may have noticed the missing patch and figured that it was not a formal request for removal. Still, I'll be happy when it's gone and am also happy that mtdchar mess is not spread over yet another file anymore. Thanks, Arnd.
Jörn
Signature · 4 lines
Mac is for working, Linux is for Networking, Windows is for Solitaire! -- stolen from dc
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 10 lines · Jörn Engel
Quoted 4 lines · Thomas Gleixner
The code _is_ ugly and ioctls are out of fashion, but your "remove it" request is just silly as long as you dont provide a reasonable alternative access to those bits.
You may have noticed the missing patch and figured that it was not a formal request for removal. Still, I'll be happy when it's gone and am also happy that mtdchar mess is not spread over yet another file anymore. Thanks, Arnd.
I'm deeply impressed by your insight and caring about Linux source code quality. Thanks, Joern.
Complaining about legacy mess is easy blurb. Providing a clean solution is obviously not on your agenda.
tglx
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
In reply to Jörn EngelQuoted 4 lines · Jörn Engel
mtdblock.c, while being quite a bit more complicated, does not require a ton of ioctls, will not confuse users with minor number 7 actually being device number 3 and magically being read-only despite unix permissions and hardware properties.
MAKEDEV and the documentation and udev ought to be perfectly sufficient to deal with the slight inconvenience caused by the use of minor numbers. The protection afforded by the read-only devices has its uses.
Quoted 2 lines
Can you name a few examples, where
mtdchar.cmakes sense? I've found it to be quite useless.
mtdchar allows you to explicitly control erases and per-byte writes. You can't do that with mtdblock. And you might not even want CONFIG_BLK_DEV enabled.
Signature · 1 line
dwmw2
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
In reply to Jörn EngelQuoted 4 lines · Jörn Engel
mtdchar.cis one of the worst drivers inside the kernel. The concept of having a simple char device driver for flash may have its charm, but the actual implementation is horrible. And things like the read-only devices are even unfixable.
This is a confusing statement, you complain that the implementation is horrible and then go on to complain about the interface to the character device.
The implementation appears small and concise. There are a couple of
FIXMEs but they are all about wishing the interface to the flash chips mapped better to a user space interface. I routinely fix things in the kernel whose implementations are much worse than mtdchar.
Quoted 2 lines
Can you name a few examples, where
mtdchar.cmakes sense? I've found it to be quite useless.
I have found just the opposite. It happens to be the only interface
to mtd devices I use. In general when you have flash devices small
enough that you can't use a filesystem without waisting a lot of space (keeping 1 free erase block out of 4 or 8 is a problem). Or when you are doing low-level mucking mtdchar is invaluable.
As for the interface to mtdchar. I agree that the readonly character device is silly, and does weird things to the mtd device minor numbers. I agree that ioctls are not the prettiest interface around, however the raw functionality the ioctls export is needed, and interesting. Some of the functionality would be hard to export even in sysfs the cool ascii replacement for ioctl.
Long term it does look like a sysfs interface to the mtd functionality could suffice.
Eric
Re: [PATCH 06/25] mtd: move ioctl32 code to mtdchar.c
Quoted 10 lines · Eric W. Biederman
Quoted 2 lines · Jörn Engel
Can you name a few examples, where
mtdchar.cmakes sense? I've found it to be quite useless.I have found just the opposite. It happens to be the only interface
to mtd devices I use. In general when you have flash devices small
enough that you can't use a filesystem without waisting a lot of space (keeping 1 free erase block out of 4 or 8 is a problem). Or when you are doing low-level mucking mtdchar is invaluable.
Josh already convinced me with the Bad Block argument. The hardware already used an OOB scheme to define them. Regular unix files without some sort of OOB data access don't map well to NAND.
Quoted 9 lines
As for the interface to mtdchar. I agree that the readonly character device is silly, and does weird things to the mtd device minor numbers. I agree that ioctls are not the prettiest interface around, however the raw functionality the ioctls export is needed, and interesting. Some of the functionality would be hard to export even in sysfs the cool ascii replacement for ioctl.
Long term it does look like a sysfs interface to the mtd functionality could suffice.
It could. Some time ago I starting coding something up, but got quickly distracted. Might be easier to start from scratch again.
Jörn
Signature · 2 lines
Happiness isn't having what you want, it's wanting what you have. -- unknown
Arnd Bergmann
maintainerPATCH 7/25 block: move ioctl32 code to drivers/block/ioctl.c
In reply to Arnd BergmannMany of the conversion handlers in fs/compat_ioctl.c are specific to block devices, so this patch moves them over to compat_blkdev_ioctl.
This hopefully gives us a slightly more efficient code patch for 32 bit block ioctls, and also enables future cleanups by merging native and compat ioctl implementation.
This patch definitely needs some serious testing.
drivers/block/ioctl.c +539 -1
@@ -1,8 +1,12 @@ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/sched.h> /* for capable() */ #include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/backing-dev.h> #include <linux/buffer_head.h> +#include <linux/fd.h> +#include <linux/hdreg.h> #include <linux/smp_lock.h> #include <asm/uaccess.h>
@@ -256,6 +260,438 @@return blkdev_driver_ioctl (inode, file, disk, cmd, arg); } +#ifdef CONFIG_COMPAT +static int w_long (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +mm_segment_t old_fs =get_fs (); +int err; +unsigned long val; + +set_fs (KERNEL_DS ); + err =blkdev_ioctl (inode, file, cmd, (unsigned long )&val); +set_fs (old_fs); +if (!err &&put_user (val, (u32 __user *)compat_ptr (arg))) +return -EFAULT ; +return err; +} + +static int broken_blkgetsize (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +/* The mkswap binary hard codes it to Intel value :-((( */ +return w_long (inode, file,BLKGETSIZE , arg); +} + +struct hd_geometry32 { +unsigned char heads; +unsigned char sectors; +unsigned short cylinders; +u32 start; +}; + +static int compat_hdio_getgeo (struct inode *inode,struct file *file, +unsigned int cmd,struct gendisk *disk,unsigned long arg) +{ +mm_segment_t old_fs =get_fs (); +struct hd_geometry geo; +struct hd_geometry32 __user *ugeo; +int err; + +set_fs (KERNEL_DS ); + err =blkdev_driver_ioctl (inode, file, disk, +HDIO_GETGEO , (unsigned long )&geo); +set_fs (old_fs); + ugeo =compat_ptr (arg); +if (!err) { + err =copy_to_user (ugeo, &geo,4 ); + err |=__put_user (geo.start, &ugeo->start); + } +return err ? -EFAULT :0 ; +} + +static int compat_hdio_ioctl (struct inode *inode,struct file *file, +struct gendisk *disk,unsigned int cmd,unsigned long arg) +{ +mm_segment_t old_fs =get_fs (); +unsigned long kval; +unsigned int __user *uvp; +int error; + +set_fs (KERNEL_DS ); + error =blkdev_driver_ioctl (inode, file, disk, cmd, + (unsigned long )&kval); +set_fs (old_fs); + +if (error ==0 ) { + uvp =compat_ptr (arg); +if (put_user (kval, uvp)) + error = -EFAULT ; + } +return error; +} + +struct blkpg_ioctl_arg32 { +compat_int_t op; +compat_int_t flags; +compat_int_t datalen; +compat_caddr_t data; +}; + +static int compat_blkpg_ioctl (struct block_device *bdev,unsigned int cmd, +unsigned long arg) +{ +struct blkpg_ioctl_arg32 __user *ua32 =compat_ptr (arg); +struct blkpg_ioctl_arg __user *a =compat_alloc_user_space (sizeof (*a)); +compat_caddr_t udata; +compat_int_t n; +int err; + + err =get_user (n, &ua32->op); + err |=put_user (n, &a->op); + err |=get_user (n, &ua32->flags); + err |=put_user (n, &a->flags); + err |=get_user (n, &ua32->datalen); + err |=put_user (n, &a->datalen); + err |=get_user (udata, &ua32->data); + err |=put_user (compat_ptr (udata), &a->data); +if (err) +return err; + +return blkpg_ioctl (bdev, a); +} + +struct floppy_struct32 { +compat_uint_t size; +compat_uint_t sect; +compat_uint_t head; +compat_uint_t track; +compat_uint_t stretch; +unsigned char gap; +unsigned char rate; +unsigned char spec1; +unsigned char fmt_gap; +const compat_caddr_t name; +}; + +struct floppy_drive_params32 { +char cmos; +compat_ulong_t max_dtr; +compat_ulong_t hlt; +compat_ulong_t hut; +compat_ulong_t srt; +compat_ulong_t spinup; +compat_ulong_t spindown; +unsigned char spindown_offset; +unsigned char select_delay; +unsigned char rps; +unsigned char tracks; +compat_ulong_t timeout; +unsigned char interleave_sect; +struct floppy_max_errors max_errors; +char flags; +char read_track; +short autodetect[8 ]; +compat_int_t checkfreq; +compat_int_t native_format; +}; + +struct floppy_drive_struct32 { +signed char flags; +compat_ulong_t spinup_date; +compat_ulong_t select_date; +compat_ulong_t first_read_date; +short probed_format; +short track; +short maxblock; +short maxtrack; +compat_int_t generation; +compat_int_t keep_data; +compat_int_t fd_ref; +compat_int_t fd_device; +compat_int_t last_checked; +compat_caddr_t dmabuf; +compat_int_t bufblocks; +}; + +struct floppy_fdc_state32 { +compat_int_t spec1; +compat_int_t spec2; +compat_int_t dtr; +unsigned char version; +unsigned char dor; +compat_ulong_t address; +unsigned int rawcmd:2 ; +unsigned int reset:1 ; +unsigned int need_configure:1 ; +unsigned int perp_mode:2 ; +unsigned int has_fifo:1 ; +unsigned int driver_version; +unsigned char track[4 ]; +}; + +struct floppy_write_errors32 { +unsigned int write_errors; +compat_ulong_t first_error_sector; +compat_int_t first_error_generation; +compat_ulong_t last_error_sector; +compat_int_t last_error_generation; +compat_uint_t badness; +}; + +#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32) +#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32) +#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32) +#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32) +#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32) +#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32) +#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32) +#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32) +#define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32) + +static struct { +unsigned int cmd32; +unsigned int cmd; +} fd_ioctl_trans_table[] = { + {FDSETPRM32 ,FDSETPRM }, + {FDDEFPRM32 ,FDDEFPRM }, + {FDGETPRM32 ,FDGETPRM }, + {FDSETDRVPRM32 ,FDSETDRVPRM }, + {FDGETDRVPRM32 ,FDGETDRVPRM }, + {FDGETDRVSTAT32 ,FDGETDRVSTAT }, + {FDPOLLDRVSTAT32 ,FDPOLLDRVSTAT }, + {FDGETFDCSTAT32 ,FDGETFDCSTAT }, + {FDWERRORGET32 ,FDWERRORGET } +}; + +#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0])) + +static int compat_fd_ioctl (struct inode *inode,struct file *file, +struct gendisk *disk,unsigned int cmd,unsigned long arg) +{ +mm_segment_t old_fs =get_fs (); +void *karg =NULL ; +unsigned int kcmd =0 ; +int i, err; + +for (i =0 ; i <NR_FD_IOCTL_TRANS ; i++) +if (cmd == fd_ioctl_trans_table[i].cmd32) { + kcmd = fd_ioctl_trans_table[i].cmd; +break ; + } +if (!kcmd) +return -EINVAL ; + +switch (cmd) { +case FDSETPRM32 : +case FDDEFPRM32 : +case FDGETPRM32 : + { +compat_uptr_t name; +struct floppy_struct32 __user *uf; +struct floppy_struct *f; + + uf =compat_ptr (arg); + f = karg =kmalloc (sizeof (struct floppy_struct ),GFP_KERNEL ); +if (!karg) +return -ENOMEM ; +if (cmd ==FDGETPRM32 ) +break ; + err =__get_user (f->size, &uf->size); + err |=__get_user (f->sect, &uf->sect); + err |=__get_user (f->head, &uf->head); + err |=__get_user (f->track, &uf->track); + err |=__get_user (f->stretch, &uf->stretch); + err |=__get_user (f->gap, &uf->gap); + err |=__get_user (f->rate, &uf->rate); + err |=__get_user (f->spec1, &uf->spec1); + err |=__get_user (f->fmt_gap, &uf->fmt_gap); + err |=__get_user (name, &uf->name); + f->name =compat_ptr (name); +if (err) { + err = -EFAULT ; + goto out; + } +break ; + } +case FDSETDRVPRM32 : +case FDGETDRVPRM32 : + { +struct floppy_drive_params32 __user *uf; +struct floppy_drive_params *f; + + uf =compat_ptr (arg); + f = karg =kmalloc (sizeof (struct floppy_drive_params ),GFP_KERNEL ); +if (!karg) +return -ENOMEM ; +if (cmd ==FDGETDRVPRM32 ) +break ; + err =__get_user (f->cmos, &uf->cmos); + err |=__get_user (f->max_dtr, &uf->max_dtr); + err |=__get_user (f->hlt, &uf->hlt); + err |=__get_user (f->hut, &uf->hut); + err |=__get_user (f->srt, &uf->srt); + err |=__get_user (f->spinup, &uf->spinup); + err |=__get_user (f->spindown, &uf->spindown); + err |=__get_user (f->spindown_offset, &uf->spindown_offset); + err |=__get_user (f->select_delay, &uf->select_delay); + err |=__get_user (f->rps, &uf->rps); + err |=__get_user (f->tracks, &uf->tracks); + err |=__get_user (f->timeout, &uf->timeout); + err |=__get_user (f->interleave_sect, &uf->interleave_sect); + err |=__copy_from_user (&f->max_errors, &uf->max_errors,sizeof (f->max_errors)); + err |=__get_user (f->flags, &uf->flags); + err |=__get_user (f->read_track, &uf->read_track); + err |=__copy_from_user (f->autodetect, uf->autodetect,sizeof (f->autodetect)); + err |=__get_user (f->checkfreq, &uf->checkfreq); + err |=__get_user (f->native_format, &uf->native_format); +if (err) { + err = -EFAULT ; + goto out; + } +break ; + } +case FDGETDRVSTAT32 : +case FDPOLLDRVSTAT32 : + karg =kmalloc (sizeof (struct floppy_drive_struct ),GFP_KERNEL ); +if (!karg) +return -ENOMEM ; +break ; +case FDGETFDCSTAT32 : + karg =kmalloc (sizeof (struct floppy_fdc_state ),GFP_KERNEL ); +if (!karg) +return -ENOMEM ; +break ; +case FDWERRORGET32 : + karg =kmalloc (sizeof (struct floppy_write_errors ),GFP_KERNEL ); +if (!karg) +return -ENOMEM ; +break ; +default : +return -EINVAL ; + } +set_fs (KERNEL_DS ); + err =blkdev_driver_ioctl (inode, file, disk, kcmd, (unsigned long )&karg); +set_fs (old_fs); +if (err) + goto out; +switch (cmd) { +case FDGETPRM32 : + { +struct floppy_struct *f = karg; +struct floppy_struct32 __user *uf =compat_ptr (arg); + + err =__put_user (f->size, &uf->size); + err |=__put_user (f->sect, &uf->sect); + err |=__put_user (f->head, &uf->head); + err |=__put_user (f->track, &uf->track); + err |=__put_user (f->stretch, &uf->stretch); + err |=__put_user (f->gap, &uf->gap); + err |=__put_user (f->rate, &uf->rate); + err |=__put_user (f->spec1, &uf->spec1); + err |=__put_user (f->fmt_gap, &uf->fmt_gap); + err |=__put_user ((u64 )f->name, (compat_caddr_t __user *)&uf->name); +break ; + } +case FDGETDRVPRM32 : + { +struct floppy_drive_params32 __user *uf; +struct floppy_drive_params *f = karg; + + uf =compat_ptr (arg); + err =__put_user (f->cmos, &uf->cmos); + err |=__put_user (f->max_dtr, &uf->max_dtr); + err |=__put_user (f->hlt, &uf->hlt); + err |=__put_user (f->hut, &uf->hut); + err |=__put_user (f->srt, &uf->srt); + err |=__put_user (f->spinup, &uf->spinup); + err |=__put_user (f->spindown, &uf->spindown); + err |=__put_user (f->spindown_offset, &uf->spindown_offset); + err |=__put_user (f->select_delay, &uf->select_delay); + err |=__put_user (f->rps, &uf->rps); + err |=__put_user (f->tracks, &uf->tracks); + err |=__put_user (f->timeout, &uf->timeout); + err |=__put_user (f->interleave_sect, &uf->interleave_sect); + err |=__copy_to_user (&uf->max_errors, &f->max_errors,sizeof (f->max_errors)); + err |=__put_user (f->flags, &uf->flags); + err |=__put_user (f->read_track, &uf->read_track); + err |=__copy_to_user (uf->autodetect, f->autodetect,sizeof (f->autodetect)); + err |=__put_user (f->checkfreq, &uf->checkfreq); + err |=__put_user (f->native_format, &uf->native_format); +break ; + } +case FDGETDRVSTAT32 : +case FDPOLLDRVSTAT32 : + { +struct floppy_drive_struct32 __user *uf; +struct floppy_drive_struct *f = karg; + + uf =compat_ptr (arg); + err =__put_user (f->flags, &uf->flags); + err |=__put_user (f->spinup_date, &uf->spinup_date); + err |=__put_user (f->select_date, &uf->select_date); + err |=__put_user (f->first_read_date, &uf->first_read_date); + err |=__put_user (f->probed_format, &uf->probed_format); + err |=__put_user (f->track, &uf->track); + err |=__put_user (f->maxblock, &uf->maxblock); + err |=__put_user (f->maxtrack, &uf->maxtrack); + err |=__put_user (f->generation, &uf->generation); + err |=__put_user (f->keep_data, &uf->keep_data); + err |=__put_user (f->fd_ref, &uf->fd_ref); + err |=__put_user (f->fd_device, &uf->fd_device); + err |=__put_user (f->last_checked, &uf->last_checked); + err |=__put_user ((u64 )f->dmabuf, &uf->dmabuf); + err |=__put_user ((u64 )f->bufblocks, &uf->bufblocks); +break ; + } +case FDGETFDCSTAT32 : + { +struct floppy_fdc_state32 __user *uf; +struct floppy_fdc_state *f = karg; + + uf =compat_ptr (arg); + err =__put_user (f->spec1, &uf->spec1); + err |=__put_user (f->spec2, &uf->spec2); + err |=__put_user (f->dtr, &uf->dtr); + err |=__put_user (f->version, &uf->version); + err |=__put_user (f->dor, &uf->dor); + err |=__put_user (f->address, &uf->address); + err |=__copy_to_user ((char __user *)&uf->address +sizeof (uf->address), + (char *)&f->address +sizeof (f->address),sizeof (int )); + err |=__put_user (f->driver_version, &uf->driver_version); + err |=__copy_to_user (uf->track, f->track,sizeof (f->track)); +break ; + } +case FDWERRORGET32 : + { +struct floppy_write_errors32 __user *uf; +struct floppy_write_errors *f = karg; + + uf =compat_ptr (arg); + err =__put_user (f->write_errors, &uf->write_errors); + err |=__put_user (f->first_error_sector, &uf->first_error_sector); + err |=__put_user (f->first_error_generation, &uf->first_error_generation); + err |=__put_user (f->last_error_sector, &uf->last_error_sector); + err |=__put_user (f->last_error_generation, &uf->last_error_generation); + err |=__put_user (f->badness, &uf->badness); +break ; + } +default : +break ; + } +if (err) + err = -EFAULT ; + +out:if (karg)kfree (karg); +return err; +} + + +/* Fix sizeof(sizeof()) breakage */ +#define BLKBSZGET_32 _IOR(0x12,112,int) +#define BLKBSZSET_32 _IOW(0x12,113,int) +#define BLKGETSIZE64_32 _IOR(0x12,114,int) +/* Most of the generic ioctls are handled in the normal fallback path. This assumes the blkdev's low level compat_ioctl always returns ENOIOCTLCMD for unknown ioctls. */
@@ -263,13 +699,115 @@ {struct block_device *bdev = file->f_dentry->d_inode->i_bdev;struct gendisk *disk = bdev->bd_disk; +struct inode *inode = file->f_mapping->host;int ret = -ENOIOCTLCMD ; -if (disk->fops->compat_ioctl) { + +switch (cmd) { +case BLKRAGET : +case BLKGETSIZE : +case BLKFRAGET : +case BLKSECTGET : + ret =w_long (inode, file, cmd, arg); +break ; +case 0x1260 : + ret =broken_blkgetsize (inode, file, cmd, arg); +break ; +case BLKBSZGET_32 : +lock_kernel (); + ret =blkdev_locked_ioctl (file, bdev,BLKBSZGET , + (unsigned long )compat_ptr (arg)); +unlock_kernel (); +break ; +case BLKBSZSET_32 : +lock_kernel (); + ret =blkdev_locked_ioctl (file, bdev,BLKBSZSET , + (unsigned long )compat_ptr (arg)); +unlock_kernel (); +break ; +case BLKGETSIZE64_32 : +lock_kernel (); + ret =blkdev_locked_ioctl (file, bdev,BLKGETSIZE64 , + (unsigned long )compat_ptr (arg)); +unlock_kernel (); +break ; +case BLKROSET : +case BLKROGET : +case BLKRRPART : +case BLKFLSBUF : +case BLKSECTSET : +case BLKSSZGET : +case BLKRASET : +case BLKFRASET : + ret =blkdev_ioctl (inode, file, cmd, arg); +break ; +case BLKPG : +lock_kernel (); + ret =compat_blkpg_ioctl (bdev, cmd, arg); +unlock_kernel (); +break ; +case HDIO_GETGEO : + ret =compat_hdio_getgeo (inode, file, cmd, disk, arg); +break ; +case HDIO_GET_KEEPSETTINGS : +case HDIO_GET_UNMASKINTR : +case HDIO_GET_DMA : +case HDIO_GET_32BIT : +case HDIO_GET_MULTCOUNT : +case HDIO_GET_NOWERR : +case HDIO_GET_NICE : + ret =compat_hdio_ioctl (inode, file, disk, cmd, arg); +break ; +case HDIO_GET_IDENTITY : +case HDIO_SET_DMA : +case HDIO_SET_UNMASKINTR : +case HDIO_SET_NOWERR : +case HDIO_SET_32BIT : +case HDIO_SET_MULTCOUNT : +case HDIO_DRIVE_CMD : +case HDIO_DRIVE_TASK : +case HDIO_SET_PIO_MODE : +case HDIO_SET_NICE : + ret =blkdev_driver_ioctl (inode, file, disk, cmd, arg); +break ; +case FDSETPRM32 : +case FDDEFPRM32 : +case FDGETPRM32 : +case FDSETDRVPRM32 : +case FDGETDRVPRM32 : +case FDGETDRVSTAT32 : +case FDPOLLDRVSTAT32 : +case FDGETFDCSTAT32 : +case FDWERRORGET32 : + ret =compat_fd_ioctl (inode, file, disk, cmd, arg); +break ; +case FDMSGON : +case FDMSGOFF : +case FDSETEMSGTRESH : +case FDFLUSH : +case FDWERRORCLR : +case FDSETMAXERRS : +case FDGETMAXERRS : +case FDGETDRVTYP : +case FDEJECT : +case FDCLRPRM : +case FDFMTBEG : +case FDFMTEND : +case FDRESET : +case FDTWADDLE : +case FDFMTTRK : +case FDRAWCMD : + ret =blkdev_driver_ioctl (inode, file, disk, cmd, arg); +break ; + } + +if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl) {lock_kernel (); ret = disk->fops->compat_ioctl (file, cmd, arg);unlock_kernel (); } +return ret; } +#endif EXPORT_SYMBOL_GPL (blkdev_ioctl);
fs/compat_ioctl.c +0 -452
496 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -39
@@ -68,45 +68,6 @@/* 0x00 */ COMPATIBLE_IOCTL(FIBMAP) COMPATIBLE_IOCTL(FIGETBSZ) -/* 0x03 -- HD/IDE ioctl's used by hdparm and friends. - * Some need translations, these do not. - */ -COMPATIBLE_IOCTL(HDIO_GET_IDENTITY) -COMPATIBLE_IOCTL(HDIO_SET_DMA) -COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR) -COMPATIBLE_IOCTL(HDIO_SET_NOWERR) -COMPATIBLE_IOCTL(HDIO_SET_32BIT) -COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT) -COMPATIBLE_IOCTL(HDIO_DRIVE_CMD) -COMPATIBLE_IOCTL(HDIO_DRIVE_TASK) -COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE) -COMPATIBLE_IOCTL(HDIO_SET_NICE) -/* 0x02 -- Floppy ioctls */ -COMPATIBLE_IOCTL(FDMSGON) -COMPATIBLE_IOCTL(FDMSGOFF) -COMPATIBLE_IOCTL(FDSETEMSGTRESH) -COMPATIBLE_IOCTL(FDFLUSH) -COMPATIBLE_IOCTL(FDWERRORCLR) -COMPATIBLE_IOCTL(FDSETMAXERRS) -COMPATIBLE_IOCTL(FDGETMAXERRS) -COMPATIBLE_IOCTL(FDGETDRVTYP) -COMPATIBLE_IOCTL(FDEJECT) -COMPATIBLE_IOCTL(FDCLRPRM) -COMPATIBLE_IOCTL(FDFMTBEG) -COMPATIBLE_IOCTL(FDFMTEND) -COMPATIBLE_IOCTL(FDRESET) -COMPATIBLE_IOCTL(FDTWADDLE) -COMPATIBLE_IOCTL(FDFMTTRK) -COMPATIBLE_IOCTL(FDRAWCMD) -/* 0x12 */ -COMPATIBLE_IOCTL(BLKROSET) -COMPATIBLE_IOCTL(BLKROGET) -COMPATIBLE_IOCTL(BLKRRPART) -COMPATIBLE_IOCTL(BLKFLSBUF) -COMPATIBLE_IOCTL(BLKSECTSET) -COMPATIBLE_IOCTL(BLKSSZGET) -ULONG_IOCTL(BLKRASET) -ULONG_IOCTL(BLKFRASET) /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION) COMPATIBLE_IOCTL(GET_ARRAY_INFO)
--
Arnd Bergmann
maintainerPATCH 8/25 tty: move ioctl32 code over to vt_ioctl.c and tty_io.c
In reply to Arnd BergmannThis patch introduces line discipline specific and tty device specific compat_ioctl callbacks as well as moving over all generic tty ioctl and vt ioctl conversion handlers over to the local files that are already responsible for the native ioctls.
drivers/char/vt.c +3 -0
@@ -2614,6 +2614,9 @@ .flush_chars = con_flush_chars, .chars_in_buffer = con_chars_in_buffer, .ioctl = vt_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = vt_compat_ioctl, +#endif .stop = con_stop, .start = con_start, .throttle = con_throttle,
drivers/char/vt_ioctl.c +195 -0
204 lines not on this page · raw message
fs/compat_ioctl.c +0 -147
159 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -79
104 lines not on this page · raw message
include/linux/tty.h +2 -0
@@ -404,6 +404,8 @@extern int vt_ioctl (struct tty_struct *tty,struct file * file,unsigned int cmd,unsigned long arg); +extern int vt_compat_ioctl (struct tty_struct *tty,struct file * file, +unsigned int cmd,unsigned long arg);static inline dev_t tty_devnum (struct tty_struct *tty) {
include/linux/tty_driver.h +4 -0
@@ -132,6 +132,8 @@int (*chars_in_buffer)(struct tty_struct *tty);int (*ioctl)(struct tty_struct *tty,struct file * file,unsigned int cmd,unsigned long arg); +int (*compat_ioctl)(struct tty_struct *tty,struct file * file, +unsigned int cmd,unsigned long arg);void (*set_termios)(struct tty_struct *tty,struct termios * old);void (*throttle)(struct tty_struct * tty);void (*unthrottle)(struct tty_struct * tty);
@@ -194,6 +196,8 @@int (*chars_in_buffer)(struct tty_struct *tty);int (*ioctl)(struct tty_struct *tty,struct file * file,unsigned int cmd,unsigned long arg); +int (*compat_ioctl)(struct tty_struct *tty,struct file * file, +unsigned int cmd,unsigned long arg);void (*set_termios)(struct tty_struct *tty,struct termios * old);void (*throttle)(struct tty_struct * tty);void (*unthrottle)(struct tty_struct * tty);
drivers/char/tty_io.c +108 -2
164 lines not on this page · raw message
include/linux/tty_ldisc.h +2 -0
@@ -126,6 +126,8 @@ const unsigned char * buf, size_t nr);int (*ioctl)(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg); +int (*compat_ioctl)(struct tty_struct * tty,struct file * file, +unsigned int cmd,unsigned long arg);void (*set_termios)(struct tty_struct *tty,struct termios * old);unsigned int (*poll)(struct tty_struct *,struct file *,struct poll_table_struct *);
drivers/char/n_tty.c +1 -0
@@ -1549,6 +1549,7 @@ read_chan,/* read */ write_chan,/* write */ n_tty_ioctl,/* ioctl */ +NULL ,/* compat_ioctl */ n_tty_set_termios,/* set_termios */ normal_poll,/* poll */ NULL, /* hangup */
--
Arnd Bergmann
maintainerPATCH 9/25 v4l: move ioctl32 handlers to drivers/media/
In reply to Arnd BergmannThis moves the 32 bit ioctl compatibility handlers for Video4Linux into a new file and adds explicit calls to them to each v4l device driver.
Unfortunately, there does not seem to be any code handling the v4l2 ioctls, so quite often the code goes through two separate conversions, first from 32 bit v4l to 64 bit v4l, and from there to 64 bit v4l2. My patch does not change that, so there is still much room for improvement.
Also, some drivers have additional ioctl numbers, for which the conversion should be handled internally to that driver.
drivers/media/radio/miropcm20-radio.c +1 -0
@@ -220,6 +220,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = pcm20_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-aimslab.c +1 -0
@@ -299,6 +299,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = rt_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-aztech.c +1 -0
@@ -256,6 +256,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = az_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-cadet.c +1 -0
@@ -490,6 +490,7 @@ .release = cadet_release, .read = cadet_read, .ioctl = cadet_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-gemtek-pci.c +1 -0
@@ -301,6 +301,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = gemtek_pci_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-gemtek.c +1 -0
@@ -233,6 +233,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = gemtek_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-maestro.c +1 -0
@@ -72,6 +72,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = radio_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-maxiradio.c +1 -0
@@ -80,6 +80,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = radio_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, }; static struct video_device maxiradio_radio =
drivers/media/radio/radio-rtrack2.c +1 -0
@@ -199,6 +199,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = rt_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-sf16fmi.c +1 -0
@@ -225,6 +225,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = fmi_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-sf16fmr2.c +1 -0
@@ -356,6 +356,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = fmr2_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-terratec.c +1 -0
@@ -276,6 +276,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = tt_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-trust.c +1 -0
@@ -255,6 +255,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = tr_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-typhoon.c +1 -0
@@ -261,6 +261,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = typhoon_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/radio/radio-zoltrix.c +1 -0
@@ -313,6 +313,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = zol_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/video/Makefile +1 -1
@@ -9,7 +9,7 @@ zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o
drivers/media/video/arv.c +1 -0
@@ -750,6 +750,7 @@ .release = video_exclusive_release, .read = ar_read, .ioctl = ar_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/video/bttv-driver.c +1 -0
@@ -3083,6 +3083,7 @@ .open = bttv_open, .release = bttv_release, .ioctl = bttv_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, .read = bttv_read, .mmap = bttv_mmap,
drivers/media/video/bw-qcam.c +1 -0
@@ -875,6 +875,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, + .compat_ioctl = v4l_compat_ioctl, .read = qcam_read, .llseek = no_llseek, };
drivers/media/video/c-qcam.c +1 -0
@@ -687,6 +687,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, + .compat_ioctl = v4l_compat_ioctl, .read = qcam_read, .llseek = no_llseek, };
drivers/media/video/compat_ioctl.c new file +318 -0
318 lines not on this page · raw message
drivers/media/video/cpia.c +1 -0
@@ -3807,6 +3807,7 @@ .read = cpia_read, .mmap = cpia_mmap, .ioctl = cpia_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/video/cx88/cx88-video.c +2 -0
@@ -1736,6 +1736,7 @@ .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
@@ -1763,6 +1764,7 @@ .open = video_open, .release = video_release, .ioctl = radio_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/video/meye.c +1 -0
@@ -1754,6 +1754,7 @@ .release = meye_release, .mmap = meye_mmap, .ioctl = meye_ioctl, + .compat_ioctl = v4l_compat_ioctl, .poll = meye_poll, .llseek = no_llseek, };
drivers/media/video/pms.c +1 -0
@@ -883,6 +883,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = pms_ioctl, + .compat_ioctl = v4l_compat_ioctl, .read = pms_read, .llseek = no_llseek, };
drivers/media/video/saa7134/saa7134-video.c +2 -0
@@ -2214,6 +2214,7 @@ .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
@@ -2223,6 +2224,7 @@ .open = video_open, .release = video_release, .ioctl = radio_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/media/video/stradis.c +1 -0
@@ -1974,6 +1974,7 @@ .open = saa_open, .release = saa_release, .ioctl = saa_ioctl, + .compat_ioctl = v4l_compat_ioctl, .read = saa_read, .llseek = no_llseek, .write = saa_write,
drivers/media/video/w9966.c +1 -0
@@ -187,6 +187,7 @@ .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = w9966_v4l_ioctl, + .compat_ioctl = v4l_compat_ioctl, .read = w9966_v4l_read, .llseek = no_llseek, };
drivers/media/video/zoran_driver.c +1 -0
@@ -4678,6 +4678,7 @@ .open = zoran_open, .release = zoran_close, .ioctl = zoran_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, .read = zoran_read, .write = zoran_write,
drivers/media/video/zr36120.c +1 -0
@@ -1490,6 +1490,7 @@ .write = zoran_write, .poll = zoran_poll, .ioctl = zoran_ioctl, + .compat_ioctl = v4l_compat_ioctl, .mmap = zoran_mmap, .minor = -1, };
drivers/usb/media/dsbr100.c +1 -0
@@ -127,6 +127,7 @@ .open = usb_dsbr100_open, .release = usb_dsbr100_close, .ioctl = usb_dsbr100_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/usb/media/ov511.c +1 -0
@@ -4774,6 +4774,7 @@ .read = ov51x_v4l1_read, .mmap = ov51x_v4l1_mmap, .ioctl = ov51x_v4l1_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/usb/media/pwc/pwc-if.c +1 -0
@@ -154,6 +154,7 @@ .poll = pwc_video_poll, .mmap = pwc_video_mmap, .ioctl = pwc_video_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };static struct video_device pwc_template = {
drivers/usb/media/se401.c +1 -0
@@ -1193,6 +1193,7 @@ .read = se401_read, .mmap = se401_mmap, .ioctl = se401_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };static struct video_device se401_template = {
drivers/usb/media/stv680.c +1 -0
@@ -1343,6 +1343,7 @@ .read = stv680_read, .mmap = stv680_mmap, .ioctl = stv680_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };static struct video_device stv680_template = {
drivers/usb/media/usbvideo.c +1 -0
@@ -953,6 +953,7 @@ .read = usbvideo_v4l_read, .mmap = usbvideo_v4l_mmap, .ioctl = usbvideo_v4l_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };static struct video_device usbvideo_template = {
drivers/usb/media/vicam.c +1 -0
@@ -1236,6 +1236,7 @@ .read = vicam_read, .mmap = vicam_mmap, .ioctl = vicam_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
drivers/usb/media/w9968cf.c +1 -0
@@ -3491,6 +3491,7 @@ .release = w9968cf_release, .read = w9968cf_read, .ioctl = w9968cf_ioctl, + .compat_ioctl = v4l_compat_ioctl, .mmap = w9968cf_mmap, .llseek = no_llseek, };
drivers/media/video/saa5249.c +1 -0
@@ -709,6 +709,7 @@ .open = saa5249_open, .release = saa5249_release, .ioctl = saa5249_ioctl, + .compat_ioctl = v4l_compat_ioctl, .llseek = no_llseek, };
fs/compat_ioctl.c +0 -246
258 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -26
@@ -100,32 +100,6 @@ COMPATIBLE_IOCTL(TUNSETDEBUG) COMPATIBLE_IOCTL(TUNSETPERSIST) COMPATIBLE_IOCTL(TUNSETOWNER) -/* Little v */ -/* Little v, the video4linux ioctls (conflict?) */ -COMPATIBLE_IOCTL(VIDIOCGCAP) -COMPATIBLE_IOCTL(VIDIOCGCHAN) -COMPATIBLE_IOCTL(VIDIOCSCHAN) -COMPATIBLE_IOCTL(VIDIOCGPICT) -COMPATIBLE_IOCTL(VIDIOCSPICT) -COMPATIBLE_IOCTL(VIDIOCCAPTURE) -COMPATIBLE_IOCTL(VIDIOCKEY) -COMPATIBLE_IOCTL(VIDIOCGAUDIO) -COMPATIBLE_IOCTL(VIDIOCSAUDIO) -COMPATIBLE_IOCTL(VIDIOCSYNC) -COMPATIBLE_IOCTL(VIDIOCMCAPTURE) -COMPATIBLE_IOCTL(VIDIOCGMBUF) -COMPATIBLE_IOCTL(VIDIOCGUNIT) -COMPATIBLE_IOCTL(VIDIOCGCAPTURE) -COMPATIBLE_IOCTL(VIDIOCSCAPTURE) -/* BTTV specific... */ -COMPATIBLE_IOCTL(_IOW('v', BASE_VIDIOCPRIVATE+0, char [256])) -COMPATIBLE_IOCTL(_IOR('v', BASE_VIDIOCPRIVATE+1, char [256])) -COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)) -COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */ -COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int)) -COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)) -COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)) -COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)) /* Little p (/dev/rtc, /dev/envctrl, etc.) */ COMPATIBLE_IOCTL(RTC_AIE_ON) COMPATIBLE_IOCTL(RTC_AIE_OFF)
include/linux/videodev.h +2 -0
@@ -90,6 +90,8 @@ unsigned int cmd, unsigned long arg, int (*func)(struct inode *inode, struct file *file, unsigned int cmd, void *arg)); +extern long v4l_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg);#endif /* __KERNEL__ */ #define VID_TYPE_CAPTURE 1/* Can capture */
--
Re: [PATCH 09/25] v4l: move ioctl32 handlers to drivers/media/
Arnd,
Em Sáb, 2005-11-05 às 17:26 +0100, Arnd Bergmann escreveu:
Quoted 4 lines
anexo Documento somente texto (compat_vidio.diff) This moves the 32 bit ioctl compatibility handlers for Video4Linux into a new file and adds explicit calls to them to each v4l device driver.
Thanks for your patch, but IMHO, it should't be applied on mainstream.
It would be better if we apply it on V4L tree and do some work on it to improve handling the compat stuff.
Quoted 6 lines
Unfortunately, there does not seem to be any code handling the v4l2 ioctls, so quite often the code goes through two separate conversions, first from 32 bit v4l to 64 bit v4l, and from there to 64 bit v4l2. My patch does not change that, so there is still much room for improvement.
As you mentioned, some changes would be required to make it more
robust. Also, we are introducing some newer devices that would require also conversion (already on -mm tree).
On the other hand, compat_ioctl.c is not a good name, since there isv4l1-compat.c, meant to handle compat ioctl between the old API and the newer one.
Quoted 4 lines
Also, some drivers have additional ioctl numbers, for which the conversion should be handled internally to that driver.
This is an interesting question: current version only handles V4L1
ioctls:
+#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
+#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
+#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
+#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
+#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
+#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
+#define VIDIOCGFREQ32 _IOR('v',14, u32)
+#define VIDIOCSFREQ32 _IOW('v',15, u32)+
The intention is to depreciate V4L1 old api (from 2.4 series), in favor
of V4L2 API. The old API have several issues and doesn't support some video standards variations used on several countries.
Newer drivers (em28xx, cx88, saa7134), used by the modern boards don't
directly implement the old API anymore. All calls are directed to v4l1-compat, that translates into V4L2 calls. We are also testing some patches to use this way also for bttv drivers. The intention is to make v4l1 obsolete and remove from kernel, maybe for 2.6.18 or 2.6.20.
We should seriously check this patch, to see if it does make sense with
current implemented ioctls.
Quoted 4 lines
Cheers,
Mauro.
Arnd Bergmann
maintainerRe: [PATCH 09/25] v4l: move ioctl32 handlers to drivers/media/
Quoted 9 lines · Mauro Carvalho Chehab
Em Sáb, 2005-11-05 às 17:26 +0100, Arnd Bergmann escreveu:
Quoted 4 lines
anexo Documento somente texto (compat_vidio.diff) This moves the 32 bit ioctl compatibility handlers for Video4Linux into a new file and adds explicit calls to them to each v4l device driver.
Thanks for your patch, but IMHO, it should't be applied on mainstream.
It would be better if we apply it on V4L tree and do some work on it to improve handling the compat stuff.
Sure, that sounds reasonable.
Quoted 11 lines
Quoted 5 lines
Unfortunately, there does not seem to be any code handling the v4l2 ioctls, so quite often the code goes through two separate conversions, first from 32 bit v4l to 64 bit v4l, and from there to 64 bit v4l2. My patch does not change that, so there is still much room for improvement.
As you mentioned, some changes would be required to make it more
robust. Also, we are introducing some newer devices that would require also conversion (already on -mm tree).
On the other hand,compat_ioctl.cis not a good name, since there isv4l1-compat.c, meant to handle compat ioctl between the old API and the newer one.
Yes, I noticed that. The problem is that compat_ioctl is the conventional name for 32 bit compatibility ioctl handlers in many other places, so is was already confusing before my patch.
Maybe it makes sense to name the new file ioctl32 instead, as that is also used in other places.
Quoted 16 lines
Quoted 3 lines
Also, some drivers have additional ioctl numbers, for which the conversion should be handled internally to that driver.
This is an interesting question: current version only handles V4L1
ioctls:drivers/media/video/compat_ioctl.c new file +9
-0+#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) +#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) +#define VIDIOCGWIN32 _IOR('v',9, struct video_window32) +#define VIDIOCSWIN32 _IOW('v',10, struct video_window32) +#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) +#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) +#define VIDIOCGFREQ32 _IOR('v',14, u32) +#define VIDIOCSFREQ32 _IOW('v',15, u32) +
Quoted 3 lines
The intention is to depreciate V4L1 old api (from 2.4 series), in favor
of V4L2 API. The old API have several issues and doesn't support some video standards variations used on several countries.
You should really do that only after the V4L2 ioctl32 conversion has been added. I'm personally watching TV going through both ioctl conversion layers (xawtv finds 32 bit V4L2 is not implemented, falls back to 32 bit V4L1, that is converted in the kernel to 64 bit V4L1 and then to 64 bit V4L2 when it reaches the driver).
Quoted 8 lines
Newer drivers (em28xx, cx88, saa7134), used by the modern boards don't
directly implement the old API anymore. All calls are directed to v4l1-compat, that translates into V4L2 calls. We are also testing some patches to use this way also for bttv drivers. The intention is to make v4l1 obsolete and remove from kernel, maybe for 2.6.18 or 2.6.20.We should seriously check this patch, to see if it does make sense with
current implemented ioctls.
Note that my patch does not change any behavior relative to 2.6.14 vanilla, it just moves the conversion handlers to a different place.
Arnd <><
Re: [PATCH 09/25] v4l: move ioctl32 handlers to drivers/media/
Arnd,
We've applied on V4L CVS. There are some fixes for it to work as
expected. We are currently working on it. I intend to submit all stuff after the fixes.
Cheers,
Mauro.
Em Seg, 2005-11-07 às 11:17 +0100, Arnd Bergmann escreveu:
Quoted 13 lines · Mauro Carvalho Chehab
Quoted 9 lines
Em Sáb, 2005-11-05 às 17:26 +0100, Arnd Bergmann escreveu:
Quoted 4 lines
anexo Documento somente texto (compat_vidio.diff) This moves the 32 bit ioctl compatibility handlers for Video4Linux into a new file and adds explicit calls to them to each v4l device driver.
Thanks for your patch, but IMHO, it should't be applied on mainstream.
It would be better if we apply it on V4L tree and do some work on it to improve handling the compat stuff.Sure, that sounds reasonable.
Arnd Bergmann
maintainerPATCH 10/25 fs: move ext2 ioctl32 handlers into file systems
In reply to Arnd BergmannThe same ioctls (originally from ext2) are used on ext2, ext3, hfsplus, cifs, reiserfs and xfs. Since they are really compatible between 32 and 64 bit except for the ioctl number, the conversion handler is trivial and I copy it to each of these file systems in order to eventually get rid of fs/compat_ioctl.c completely.
Ext3 and reiserfs actually have some more ioctl numbers that have the same problem as the others, so I'm adding the conversion for those in the same place.
XFS already handled these ioctl numbers in its existing ioctl32 code, but appeared to get it wrong.
fs/compat_ioctl.c +0 -22
@@ -126,12 +126,6 @@#ifdef CODE -/* Aiee. Someone does not find a difference between int and long */ -#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) -#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) -#define EXT2_IOC32_GETVERSION _IOR('v', 1, int) -#define EXT2_IOC32_SETVERSION _IOW('v', 2, int) -static int w_long (unsigned int fd,unsigned int cmd,unsigned long arg) {mm_segment_t old_fs =get_fs ();
@@ -163,18 +157,6 @@return err; } -static int do_ext2_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -/* These are just misnamed, they actually get/put from/to user an int */ -switch (cmd) { -case EXT2_IOC32_GETFLAGS : cmd =EXT2_IOC_GETFLAGS ;break ; -case EXT2_IOC32_SETFLAGS : cmd =EXT2_IOC_SETFLAGS ;break ; -case EXT2_IOC32_GETVERSION : cmd =EXT2_IOC_GETVERSION ;break ; -case EXT2_IOC32_SETVERSION : cmd =EXT2_IOC_SETVERSION ;break ; - } -return sys_ioctl (fd, cmd, (unsigned long )compat_ptr (arg)); -} -struct fb_fix_screeninfo32 {char id[16 ];compat_caddr_t smem_start;
@@ -1313,10 +1295,6 @@ HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)HANDLE_IOCTL (AUTOFS_IOC_SETTIMEOUT32 , ioc_settimeout) -HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) -HANDLE_IOCTL (EXT2_IOC32_SETVERSION , do_ext2_ioctl) /* 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)
fs/ext2/ioctl.c +31 -0
@@ -10,6 +10,7 @@#include "ext2.h" #include <linux/time.h> #include <linux/sched.h> +#include <linux/compat.h> #include <asm/current.h> #include <asm/uaccess.h>
@@ -79,3 +80,33 @@return -ENOTTY ; } } + +#ifdef CONFIG_COMPAT +long ext2_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +int ret; + +/* These are just misnamed, they actually get/put from/to user an int */ +switch (cmd) { +case EXT2_IOC32_GETFLAGS : + cmd =EXT2_IOC_GETFLAGS ; +break ; +case EXT2_IOC32_SETFLAGS : + cmd =EXT2_IOC_SETFLAGS ; +break ; +case EXT2_IOC32_GETVERSION : + cmd =EXT2_IOC_GETVERSION ; +break ; +case EXT2_IOC32_SETVERSION : + cmd =EXT2_IOC_SETVERSION ; +break ; +default : +return -ENOIOCTLCMD ; + } +lock_kernel (); + ret =ext2_ioctl (inode, file, cmd, (unsigned long )compat_ptr (arg)); +unlock_kernel (); +return ret; +} +#endif
fs/ext3/ioctl.c +65 -1
77 lines not on this page · raw message
fs/ext2/dir.c +3 -0
@@ -669,5 +669,8 @@ .read = generic_read_dir, .readdir = ext2_readdir, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .fsync = ext2_sync_file, };
fs/ext2/file.c +6 -0
@@ -46,6 +46,9 @@ .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .mmap = generic_file_mmap, .open = generic_file_open, .release = ext2_release_file,
@@ -61,6 +64,9 @@ .read = xip_file_read, .write = xip_file_write, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .mmap = xip_file_mmap, .open = generic_file_open, .release = ext2_release_file,
fs/ext3/dir.c +3 -0
@@ -44,6 +44,9 @@ .read = generic_read_dir, .readdir = ext3_readdir, /* we take BKL. needed?*/ .ioctl = ext3_ioctl,/* BKL held */ +#ifdef CONFIG_COMPAT + .compat_ioctl = ext3_compat_ioctl, +#endif .fsync = ext3_sync_file,/* BKL held */ #ifdef CONFIG_EXT3_INDEX .release = ext3_release_dir,
fs/ext3/file.c +3 -0
@@ -114,6 +114,9 @@ .readv = generic_file_readv, .writev = generic_file_writev, .ioctl = ext3_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext3_compat_ioctl, +#endif .mmap = generic_file_mmap, .open = generic_file_open, .release = ext3_release_file,
fs/xfs/linux-2.6/xfs_ioctl32.c +12 -3
@@ -34,6 +34,11 @@#define _NATIVE_IOC (cmd, type) \ _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) +/* broken ext2 ioctl numbers */ +#define XFS_IOC_GETVERSION32 _IOR('v', 1, int) +#define XFS_IOC_GETXFLAGS32 _IOR('f', 1, int) +#define XFS_IOC_SETXFLAGS32 _IOW('f', 2, int) +#if defined(CONFIG_IA64 ) || defined(CONFIG_X86_64 )#define BROKEN_X86_ALIGNMENT /* on ia32 l_start is on a 32-bit boundary */
@@ -115,12 +120,16 @@vnode_t *vp =LINVFS_GET_VP (inode);switch (cmd) { +/* these take an int as their argument, not a long */ +case XFS_IOC_GETVERSION32 : +case XFS_IOC_GETXFLAGS32 : +case XFS_IOC_SETXFLAGS32 : + cmd =_NATIVE_IOC (cmd, long); +break ; +case XFS_IOC_DIOINFO :case XFS_IOC_FSGEOMETRY_V1 :case XFS_IOC_FSGEOMETRY : -case XFS_IOC_GETVERSION : -case XFS_IOC_GETXFLAGS : -case XFS_IOC_SETXFLAGS :case XFS_IOC_FSGETXATTR :case XFS_IOC_FSSETXATTR :case XFS_IOC_FSGETXATTRA :
fs/cifs/ioctl.c +28 -1
@@ -21,6 +21,8 @@* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/fs.h> #include <linux/ext2_fs.h> #include "cifspdu.h"
@@ -109,4 +111,29 @@FreeXid (xid);return rc; -} +} + +#ifdef CONFIG_COMPAT +long cifs_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +int ret; + +/* These are just misnamed, they actually get/put from/to user an int */ +switch (cmd) { +case EXT2_IOC32_GETFLAGS : + cmd =EXT2_IOC_GETFLAGS ; +break ; +case EXT2_IOC32_SETFLAGS : + cmd =EXT2_IOC_SETFLAGS ; +break ; +default : +return -ENOIOCTLCMD ; + } +lock_kernel (); + ret =cifs_ioctl (inode, file, cmd, (unsigned long )compat_ptr (arg)); +unlock_kernel (); +return ret; +} + +#endif
fs/hfsplus/dir.c +4 -0
@@ -8,6 +8,7 @@* Handling of directories */ +#include <linux/config.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/sched.h>
@@ -479,6 +480,9 @@ .read = generic_read_dir, .readdir = hfsplus_readdir, .ioctl = hfsplus_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = hfsplus_compat_ioctl, +#endif .llseek = generic_file_llseek, .release = hfsplus_dir_release, };
fs/hfsplus/hfsplus_fs.h +4 -0
@@ -249,6 +249,8 @@* chattr/lsattr */ #define HFSPLUS_IOC_EXT2_GETFLAGS _IOR('f', 1, long)#define HFSPLUS_IOC_EXT2_SETFLAGS _IOW('f', 2, long) +#define HFSPLUS_IOC_EXT2_GETFLAGS32 _IOR('f', 1, int) +#define HFSPLUS_IOC_EXT2_SETFLAGS32 _IOW('f', 2, int)#define EXT2_FLAG_IMMUTABLE 0x00000010/* Immutable file */ #define EXT2_FLAG_APPEND 0x00000020/* writes to file may only append */
@@ -336,6 +338,8 @@/* ioctl.c */ int hfsplus_ioctl (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg); +long hfsplus_compat_ioctl (struct file *filp,unsigned int cmd, +unsigned long arg);int hfsplus_setxattr (struct dentry *dentry,const char *name,const void *value,size_t size,int flags); ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
fs/hfsplus/inode.c +4 -0
@@ -8,6 +8,7 @@* Inode handling routines */ +#include <linux/config.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/pagemap.h>
@@ -310,6 +311,9 @@ .open = hfsplus_file_open, .release = hfsplus_file_release, .ioctl = hfsplus_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = hfsplus_compat_ioctl, +#endif };struct inode *hfsplus_new_inode (struct super_block *sb,int mode)
fs/hfsplus/ioctl.c +29 -0
@@ -12,6 +12,8 @@* hfsplus ioctls */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/fs.h> #include <linux/sched.h> #include <linux/xattr.h>
@@ -82,6 +84,33 @@ } } +#ifdef CONFIG_COMPAT +long hfsplus_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +int ret; + +switch (cmd) { +case HFSPLUS_IOC_EXT2_GETFLAGS32 : + cmd =HFSPLUS_IOC_EXT2_GETFLAGS ; +break ; +case HFSPLUS_IOC_EXT2_SETFLAGS32 : + cmd =HFSPLUS_IOC_EXT2_SETFLAGS ; +break ; +default : +return -ENOIOCTLCMD ; + } + + arg = (unsigned long )compat_ptr (arg); +lock_kernel (); + ret =hfsplus_ioctl (inode, file, cmd, arg); +unlock_kernel (); + +return ret; +} +#endif +int hfsplus_setxattr (struct dentry *dentry,const char *name,const void *value,size_t size,int flags) {
fs/reiserfs/dir.c +3 -0
@@ -23,6 +23,9 @@ .readdir = reiserfs_readdir, .fsync = reiserfs_dir_fsync, .ioctl = reiserfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = reiserfs_compat_ioctl, +#endif }; static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
fs/reiserfs/file.c +4 -0
@@ -2,6 +2,7 @@* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ +#include <linux/config.h> #include <linux/time.h> #include <linux/reiserfs_fs.h> #include <linux/reiserfs_acl.h>
@@ -1551,6 +1552,9 @@ .read = generic_file_read, .write = reiserfs_file_write, .ioctl = reiserfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = reiserfs_compat_ioctl, +#endif .mmap = generic_file_mmap, .release = reiserfs_file_release, .fsync = reiserfs_sync_file,
fs/reiserfs/ioctl.c +36 -0
@@ -2,6 +2,8 @@* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/fs.h> #include <linux/reiserfs_fs.h> #include <linux/time.h>
@@ -93,6 +95,40 @@ } } +#ifdef CONFIG_COMPAT +long reiserfs_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +int ret; + +/* These are just misnamed, they actually get/put from/to user an int */ +switch (cmd) { +case REISERFS_IOC32_UNPACK : + cmd =REISERFS_IOC_UNPACK ; +break ; +case REISERFS_IOC32_GETFLAGS : + cmd =REISERFS_IOC_GETFLAGS ; +break ; +case REISERFS_IOC32_SETFLAGS : + cmd =REISERFS_IOC_SETFLAGS ; +break ; +case REISERFS_IOC32_GETVERSION : + cmd =REISERFS_IOC_GETVERSION ; +break ; +case REISERFS_IOC32_SETVERSION : + cmd =REISERFS_IOC_SETVERSION ; +break ; +default : +return -ENOIOCTLCMD ; + } +lock_kernel (); + ret =reiserfs_ioctl (inode, file, cmd, (unsigned long )compat_ptr (arg)); +unlock_kernel (); +return ret; +} +#endif +/* ** reiserfs_unpack ** Function try to convert tail from direct item into indirect.
include/linux/ext2_fs.h +7 -0
@@ -204,6 +204,13 @@#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)#define EXT2_IOC_GETVERSION _IOR('v', 1, long)#define EXT2_IOC_SETVERSION _IOW('v', 2, long) +/* +* ioctl commands in 32 bit emulation +*/ +#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) +#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) +#define EXT2_IOC32_GETVERSION _IOR('v', 1, int) +#define EXT2_IOC32_SETVERSION _IOW('v', 2, int)/* * Structure of an inode on the disk
include/linux/reiserfs_fs.h +9 -0
@@ -2180,6 +2180,8 @@/* prototypes from ioctl.c */ int reiserfs_ioctl (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg); +long reiserfs_compat_ioctl (struct file *filp, +unsigned int cmd,unsigned long arg);/* ioctl's command */ #define REISERFS_IOC_UNPACK _IOW(0xCD,1,long)
@@ -2190,6 +2192,13 @@#define REISERFS_IOC_GETVERSION EXT2_IOC_GETVERSION#define REISERFS_IOC_SETVERSION EXT2_IOC_SETVERSION +/* the 32 bit compat definitions with int argument */ +#define REISERFS_IOC32_UNPACK _IOW(0xCD, 1, int) +#define REISERFS_IOC32_GETFLAGS EXT2_IOC32_GETFLAGS +#define REISERFS_IOC32_SETFLAGS EXT2_IOC32_SETFLAGS +#define REISERFS_IOC32_GETVERSION EXT2_IOC32_GETVERSION +#define REISERFS_IOC32_SETVERSION EXT2_IOC32_SETVERSION +/* Locking primitives */ /* Right now we are still falling back to (un)lock_kernel, but eventually that would evolve into real per-fs locks */
fs/cifs/cifsfs.c +10 -0
@@ -23,6 +23,7 @@/* Note that BB means BUGBUG (ie something to fix eventually) */ +#include <linux/config.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/mount.h>
@@ -600,6 +601,9 @@ .sendfile = generic_file_sendfile,#ifdef CONFIG_CIFS_POSIX .ioctl = cifs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = cifs_compat_ioctl, +#endif /* CONFIG_COMPAT */ #endif /* CONFIG_CIFS_POSIX */ #ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -624,6 +628,9 @@ .sendfile = generic_file_sendfile, /* BB removeme BB */#ifdef CONFIG_CIFS_POSIX .ioctl = cifs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = cifs_compat_ioctl, +#endif /* CONFIG_COMPAT */ #endif /* CONFIG_CIFS_POSIX */ #ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -639,6 +646,9 @@ .dir_notify = cifs_dir_notify,#endif /* CONFIG_CIFS_EXPERIMENTAL */ .ioctl = cifs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = cifs_compat_ioctl, +#endif /* CONFIG_COMPAT */ }; static void
fs/cifs/cifsfs.h +2 -0
@@ -97,5 +97,7 @@extern ssize_t cifs_listxattr (struct dentry *,char *,size_t );extern int cifs_ioctl (struct inode * inode,struct file * filep,unsigned int command,unsigned long arg); +extern long cifs_compat_ioctl (struct file * filep,unsigned int command, +unsigned long arg);#define CIFS_VERSION "1.39"#endif /* _CIFSFS_H */
fs/ext2/ext2.h +1 -0
@@ -137,6 +137,7 @@/* ioctl.c */ extern int ext2_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +extern long ext2_compat_ioctl (struct file *,unsigned int ,unsigned long );/* super.c */ extern void ext2_error (struct super_block *,const char *,const char *, ...)
include/linux/ext3_fs.h +1 -0
@@ -792,6 +792,7 @@/* ioctl.c */ extern int ext3_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +extern long ext3_compat_ioctl (struct file *,unsigned int ,unsigned long );/* namei.c */ extern int ext3_orphan_add (handle_t *,struct inode *);
--
Re: [PATCH 10/25] fs: move ext2 ioctl32 handlers into file systems
Quoted 5 lines · Arnd Bergmann
The same ioctls (originally from ext2) are used on ext2, ext3, hfsplus, cifs, reiserfs and xfs. Since they are really compatible between 32 and 64 bit except for the ioctl number, the conversion handler is trivial and I copy it to each of these file systems in order to eventually get rid of
fs/compat_ioctl.ccompletely.
NACK, this is completely idiotic. Duplicating handlers is the very last thing we want. I actually have patches to move handling some of those ioctls into generic code, but that's a different story.
Arnd Bergmann
maintainerRe: [PATCH 10/25] fs: move ext2 ioctl32 handlers into file systems
Quoted 3 lines · Christoph Hellwig
NACK, this is completely idiotic. Duplicating handlers is the very last thing we want. I actually have patches to move handling some of those ioctls into generic code, but that's a different story.
Ok, I'll drop this patch then, except for the ext3 parts that fix an actual problem of missing conversion handlers.
What is your opinion on the xfs bit. The current code is somewhat broken, since XFS_IOC_{GET,SET}{VERSION,XFLAGS} are not really compatible. Should those three lines simply be removed?
Arnd <><
fs/xfs/linux-2.6/xfs_ioctl32.c 2005-11-05 02:45:35.000000000 +0100 renamed from fs/xfs/linux-2.6/xfs_ioctl32.c 2005-11-05 02:44:55.000000000 +0100 +12 -3
@@ -34,6 +34,11 @@ #define _NATIVE_IOC(cmd, type) \ _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) +/* broken ext2 ioctl numbers */ +#define XFS_IOC_GETVERSION32 _IOR('v', 1, int) +#define XFS_IOC_GETXFLAGS32 _IOR('f', 1, int) +#define XFS_IOC_SETXFLAGS32 _IOW('f', 2, int) + #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) #define BROKEN_X86_ALIGNMENT /* on ia32 l_start is on a 32-bit boundary */
@@ -115,12 +120,16 @@ vnode_t *vp = LINVFS_GET_VP(inode); switch (cmd) { + /* these take an int as their argument, not a long */ + case XFS_IOC_GETVERSION32: + case XFS_IOC_GETXFLAGS32: + case XFS_IOC_SETXFLAGS32: + cmd = _NATIVE_IOC(cmd, long); + break; + case XFS_IOC_DIOINFO: case XFS_IOC_FSGEOMETRY_V1: case XFS_IOC_FSGEOMETRY: - case XFS_IOC_GETVERSION: - case XFS_IOC_GETXFLAGS: - case XFS_IOC_SETXFLAGS: case XFS_IOC_FSGETXATTR: case XFS_IOC_FSSETXATTR: case XFS_IOC_FSGETXATTRA:
Arnd Bergmann
maintainerPATCH 11/25 framebuffer: move ioctl32 code to fbmem.c
In reply to Arnd BergmannThe frame buffer layer already had some code dealing with compat ioctls, this patch moves over the remaining code from fs/compat_ioctl.c
drivers/video/fbmem.c +142 -5
@@ -14,6 +14,7 @@#include <linux/config.h> #include <linux/module.h> +#include <linux/compat.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/sched.h>
@@ -829,18 +830,154 @@ }#ifdef CONFIG_COMPAT +struct fb_fix_screeninfo32 { +char id[16 ]; +compat_caddr_t smem_start; +u32 smem_len; +u32 type; +u32 type_aux; +u32 visual; +u16 xpanstep; +u16 ypanstep; +u16 ywrapstep; +u32 line_length; +compat_caddr_t mmio_start; +u32 mmio_len; +u32 accel; +u16 reserved[3 ]; +}; + +struct fb_cmap32 { +u32 start; +u32 len; +compat_caddr_t red; +compat_caddr_t green; +compat_caddr_t blue; +compat_caddr_t transp; +}; + +static int fb_getput_cmap (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +struct fb_cmap_user __user *cmap; +struct fb_cmap32 __user *cmap32; +__u32 data; +int err; + + cmap =compat_alloc_user_space (sizeof (*cmap)); + cmap32 =compat_ptr (arg); + +if (copy_in_user (&cmap->start, &cmap32->start,2 *sizeof (__u32))) +return -EFAULT ; + +if (get_user (data, &cmap32->red) || +put_user (compat_ptr (data), &cmap->red) || +get_user (data, &cmap32->green) || +put_user (compat_ptr (data), &cmap->green) || +get_user (data, &cmap32->blue) || +put_user (compat_ptr (data), &cmap->blue) || +get_user (data, &cmap32->transp) || +put_user (compat_ptr (data), &cmap->transp)) +return -EFAULT ; + + err =fb_ioctl (inode, file, cmd, (unsigned long ) cmap); + +if (!err) { +if (copy_in_user (&cmap32->start, + &cmap->start, +2 *sizeof (__u32))) + err = -EFAULT ; + } +return err; +} + +static int do_fscreeninfo_to_user (struct fb_fix_screeninfo *fix, +struct fb_fix_screeninfo32 __user *fix32) +{ +__u32 data; +int err; + + err =copy_to_user (&fix32->id, &fix->id,sizeof (fix32->id)); + + data = (__u32 ) (unsigned long ) fix->smem_start; + err |=put_user (data, &fix32->smem_start); + + err |=put_user (fix->smem_len, &fix32->smem_len); + err |=put_user (fix->type, &fix32->type); + err |=put_user (fix->type_aux, &fix32->type_aux); + err |=put_user (fix->visual, &fix32->visual); + err |=put_user (fix->xpanstep, &fix32->xpanstep); + err |=put_user (fix->ypanstep, &fix32->ypanstep); + err |=put_user (fix->ywrapstep, &fix32->ywrapstep); + err |=put_user (fix->line_length, &fix32->line_length); + + data = (__u32 ) (unsigned long ) fix->mmio_start; + err |=put_user (data, &fix32->mmio_start); + + err |=put_user (fix->mmio_len, &fix32->mmio_len); + err |=put_user (fix->accel, &fix32->accel); + err |=copy_to_user (fix32->reserved, fix->reserved, +sizeof (fix->reserved)); + +return err; +} + +static int fb_get_fscreeninfo (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +mm_segment_t old_fs; +struct fb_fix_screeninfo fix; +struct fb_fix_screeninfo32 __user *fix32; +int err; + + fix32 =compat_ptr (arg); + + old_fs =get_fs (); +set_fs (KERNEL_DS ); + err =fb_ioctl (inode, file, cmd, (unsigned long ) &fix); +set_fs (old_fs); + +if (!err) + err =do_fscreeninfo_to_user (&fix, fix32); + +return err; +} +static long fb_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) { -int fbidx =iminor (file->f_dentry->d_inode); +struct inode *inode = file->f_dentry->d_inode; +int fbidx =iminor (inode);struct fb_info *info = registered_fb[fbidx];struct fb_ops *fb = info->fbops; -long ret; +long ret = -ENOIOCTLCMD ; -if (fb->fb_compat_ioctl ==NULL ) -return -ENOIOCTLCMD ;lock_kernel (); - ret = fb->fb_compat_ioctl (file, cmd, arg, info); +switch (cmd) { +case FBIOGET_VSCREENINFO : +case FBIOPUT_VSCREENINFO : +case FBIOPAN_DISPLAY : +case FBIOGET_CON2FBMAP : +case FBIOPUT_CON2FBMAP : + arg = (unsigned long )compat_ptr (arg); +case FBIOBLANK : + ret =fb_ioctl (inode, file, cmd, arg); +break ; + +case FBIOGET_FSCREENINFO : + ret =fb_get_fscreeninfo (inode, file, cmd, arg); +break ; + +case FBIOGETCMAP : +case FBIOPUTCMAP : + ret =fb_getput_cmap (inode, file, cmd, arg); +break ; + +default : +if (fb->fb_compat_ioctl) + ret = fb->fb_compat_ioctl (file, cmd, arg, info); +break ; + }unlock_kernel ();return ret; }
fs/compat_ioctl.c +0 -143
155 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -7
@@ -10,13 +10,6 @@#define ULONG_IOCTL (cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)#endif -/* Big F */ -COMPATIBLE_IOCTL(FBIOBLANK) -COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO) -COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO) -COMPATIBLE_IOCTL(FBIOPAN_DISPLAY) -COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP) -COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)/* Little f */ COMPATIBLE_IOCTL (FIOCLEX)COMPATIBLE_IOCTL (FIONCLEX)
--
Re: [PATCH 11/25] framebuffer: move ioctl32 code to fbmem.c
Quoted 3 lines · Arnd Bergmann
The frame buffer layer already had some code dealing with compat ioctls, this patch moves over the remaining code from
fs/compat_ioctl.c
This is fine with me.
Tony
Arnd Bergmann
maintainerPATCH 12/25 scsi: move SG_IO ioctl32 code to sg.c
In reply to Arnd BergmannThe sg driver already has a compat_ioctl function, so the conversion handler for SG_IO can easily be moved in there as well. It still uses compat_alloc_user_space, so it can probably be simplified by using merging the conversion handler with the native method.
drivers/scsi/sg.c +154 -0
@@ -31,6 +31,7 @@#include <linux/config.h> #include <linux/module.h> +#include <linux/compat.h> #include <linux/fs.h> #include <linux/kernel.h> #include <linux/sched.h>
@@ -1087,6 +1088,156 @@ }#ifdef CONFIG_COMPAT + +typedef struct sg_io_hdr32 { +compat_int_t interface_id;/* [i] 'S' for SCSI generic (required) */ +compat_int_t dxfer_direction;/* [i] data transfer direction */ +unsigned char cmd_len;/* [i] SCSI command length ( <= 16 bytes) */ +unsigned char mx_sb_len;/* [i] max length to write to sbp */ +unsigned short iovec_count;/* [i] 0 implies no scatter gather */ +compat_uint_t dxfer_len;/* [i] byte count of data transfer */ +compat_uint_t dxferp;/* [i], [*io] points to data transfer memory +or scatter gather list */ +compat_uptr_t cmdp;/* [i], [*i] points to command to perform */ +compat_uptr_t sbp;/* [i], [*o] points to sense_buffer memory */ +compat_uint_t timeout;/* [i] MAX_UINT->no timeout (unit: millisec) */ +compat_uint_t flags;/* [i] 0 -> default, see SG_FLAG... */ +compat_int_t pack_id;/* [i->o] unused internally (normally) */ +compat_uptr_t usr_ptr;/* [i->o] unused internally */ +unsigned char status;/* [o] scsi status */ +unsigned char masked_status;/* [o] shifted, masked scsi status */ +unsigned char msg_status;/* [o] messaging level data (optional) */ +unsigned char sb_len_wr;/* [o] byte count actually written to sbp */ +unsigned short host_status;/* [o] errors from host adapter */ +unsigned short driver_status;/* [o] errors from software driver */ +compat_int_t resid;/* [o] dxfer_len - actual_transferred */ +compat_uint_t duration;/* [o] time taken by cmd (unit: millisec) */ +compat_uint_t info;/* [o] auxiliary information */ +}sg_io_hdr32_t ;/* 64 bytes long (on sparc32) */ + +typedef struct sg_iovec32 { +compat_uint_t iov_base; +compat_uint_t iov_len; +}sg_iovec32_t ; + +static int sg_build_iovec (sg_io_hdr_t __user *sgio,void __user *dxferp,u16 iovec_count) +{ +sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio +1 ); +sg_iovec32_t __user *iov32 = dxferp; +int i; + +for (i =0 ; i < iovec_count; i++) { +u32 base, len; + +if (get_user (base, &iov32[i].iov_base) || +get_user (len, &iov32[i].iov_len) || +put_user (compat_ptr (base), &iov[i].iov_base) || +put_user (len, &iov[i].iov_len)) +return -EFAULT ; + } + +if (put_user (iov, &sgio->dxferp)) +return -EFAULT ; +return 0 ; +} + +static int sg_ioctl_trans (struct file *file,unsigned int cmd,unsigned long arg) +{ +sg_io_hdr_t __user *sgio; +sg_io_hdr32_t __user *sgio32; +u16 iovec_count; +u32 data; +void __user *dxferp; +int err; + + sgio32 =compat_ptr (arg); +if (get_user (iovec_count, &sgio32->iovec_count)) +return -EFAULT ; + + { +void __user *top =compat_alloc_user_space (0 ); +void __user *new =compat_alloc_user_space (sizeof (sg_io_hdr_t) + + (iovec_count *sizeof (sg_iovec_t))); +if (new > top) +return -EINVAL ; + + sgio = new; + } + +/* Ok, now construct. */ +if (copy_in_user (&sgio->interface_id, &sgio32->interface_id, + (2 *sizeof (int )) + + (2 *sizeof (unsigned char )) + + (1 *sizeof (unsigned short )) + + (1 *sizeof (unsigned int )))) +return -EFAULT ; + +if (get_user (data, &sgio32->dxferp)) +return -EFAULT ; + dxferp =compat_ptr (data); +if (iovec_count) { +if (sg_build_iovec (sgio, dxferp, iovec_count)) +return -EFAULT ; + }else { +if (put_user (dxferp, &sgio->dxferp)) +return -EFAULT ; + } + + { +unsigned char __user *cmdp; +unsigned char __user *sbp; + +if (get_user (data, &sgio32->cmdp)) +return -EFAULT ; + cmdp =compat_ptr (data); + +if (get_user (data, &sgio32->sbp)) +return -EFAULT ; + sbp =compat_ptr (data); + +if (put_user (cmdp, &sgio->cmdp) || +put_user (sbp, &sgio->sbp)) +return -EFAULT ; + } + +if (copy_in_user (&sgio->timeout, &sgio32->timeout, +3 *sizeof (int ))) +return -EFAULT ; + +if (get_user (data, &sgio32->usr_ptr)) +return -EFAULT ; +if (put_user (compat_ptr (data), &sgio->usr_ptr)) +return -EFAULT ; + +if (copy_in_user (&sgio->status, &sgio32->status, + (4 *sizeof (unsigned char )) + + (2 *sizeof (unsigned (short ))) + + (3 *sizeof (int )))) +return -EFAULT ; + +lock_kernel (); + err =sg_ioctl (file->f_dentry->d_inode, file, + cmd, (unsigned long ) sgio); +unlock_kernel (); + +if (err >=0 ) { +void __user *datap; + +if (copy_in_user (&sgio32->pack_id, &sgio->pack_id, +sizeof (int )) || +get_user (datap, &sgio->usr_ptr) || +put_user ((u32 )(unsigned long )datap, + &sgio32->usr_ptr) || +copy_in_user (&sgio32->status, &sgio->status, + (4 *sizeof (unsigned char )) + + (2 *sizeof (unsigned short )) + + (3 *sizeof (int )))) + err = -EFAULT ; + } + +return err; +} +static long sg_compat_ioctl (struct file *filp,unsigned int cmd_in,unsigned long arg) {Sg_device *sdp;
@@ -1096,6 +1247,9 @@if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))return -ENXIO ; +if (cmd_in ==SG_IO ) +return sg_ioctl_trans (filp, cmd_in, arg); + sdev = sdp->device;if (sdev->host->hostt->compat_ioctl) {int ret;
fs/compat_ioctl.c +0 -147
159 lines not on this page · raw message
--
Re: [PATCH 12/25] scsi: move SG_IO ioctl32 code to sg.c
Quoted 6 lines · Arnd Bergmann
plain text document attachment (sg-ioctl.diff) The sg driver already has a
compat_ioctlfunction, so the conversion handler forSG_IOcan easily be moved in there as well. It still usescompat_alloc_user_space, so it can probably be simplified by using merging the conversion handler with the native method.
This is the wrong place, isn't it? SG_IO is also in drivers/block/scsi_ioctl.c which isn't modular, so shouldn't this be in there?
James
Arnd Bergmann
maintainerRe: [PATCH 12/25] scsi: move SG_IO ioctl32 code to sg.c
Quoted 4 lines · James Bottomley
This is the wrong place, isn't it? SG_IO is also in
drivers/block/scsi_ioctl.cwhich isn't modular, so shouldn't this be in there?
Yes, you're right. That patch broke compat SG_IO for the other scsi drivers. I'll do a new one.
Arnd <><
Arnd Bergmann
maintainerPATCH 13/25 loop: move ioctl32 code to loop.c
In reply to Arnd BergmannThe loop device driver is the only user of its ioctl commands, so we can move the conversion handlers for 32 bit emulation into the driver itself.
This patch just moves over the function, it would probably be a good idea to get rid of get_fs/set_fs calls here by integrating better with the driver.
drivers/block/loop.c +76 -0
@@ -51,6 +51,7 @@*/ #include <linux/config.h> +#include <linux/compat.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/sched.h>
@@ -1164,6 +1165,78 @@return err; } +#ifdef CONFIG_COMPAT +struct loop_info32 { +compat_int_t lo_number;/* ioctl r/o */ +compat_dev_t lo_device;/* ioctl r/o */ +compat_ulong_t lo_inode;/* ioctl r/o */ +compat_dev_t lo_rdevice;/* ioctl r/o */ +compat_int_t lo_offset; +compat_int_t lo_encrypt_type; +compat_int_t lo_encrypt_key_size;/* ioctl w/o */ +compat_int_t lo_flags;/* ioctl r/o */ +char lo_name[LO_NAME_SIZE ]; +unsigned char lo_encrypt_key[LO_KEY_SIZE ];/* ioctl w/o */ +compat_ulong_t lo_init[2 ]; +char reserved[4 ]; +}; + +static long lo_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +mm_segment_t old_fs =get_fs (); +struct loop_info l; +struct loop_info32 __user *ul; +int err = -ENOIOCTLCMD ; + + ul =compat_ptr (arg); + +lock_kernel (); +switch (cmd) { +case LOOP_SET_STATUS : + err =get_user (l.lo_number, &ul->lo_number); + err |=__get_user (l.lo_device, &ul->lo_device); + err |=__get_user (l.lo_inode, &ul->lo_inode); + err |=__get_user (l.lo_rdevice, &ul->lo_rdevice); + err |=__copy_from_user (&l.lo_offset, &ul->lo_offset, +8 + (unsigned long )l.lo_init - (unsigned long )&l.lo_offset); +if (err) { + err = -EFAULT ; + }else { +set_fs (KERNEL_DS ); + err =lo_ioctl (inode, file, cmd, (unsigned long )&l); +set_fs (old_fs); + } +break ; +case LOOP_GET_STATUS : +set_fs (KERNEL_DS ); + err =lo_ioctl (inode, file, cmd, (unsigned long )&l); +set_fs (old_fs); +if (!err) { + err =put_user (l.lo_number, &ul->lo_number); + err |=__put_user (l.lo_device, &ul->lo_device); + err |=__put_user (l.lo_inode, &ul->lo_inode); + err |=__put_user (l.lo_rdevice, &ul->lo_rdevice); + err |=__copy_to_user (&ul->lo_offset, &l.lo_offset, + (unsigned long )l.lo_init - (unsigned long )&l.lo_offset); +if (err) + err = -EFAULT ; + } +break ; +case LOOP_CLR_FD : +case LOOP_GET_STATUS64 : +case LOOP_SET_STATUS64 : + arg = (unsigned long )compat_ptr (arg); +case LOOP_SET_FD : +case LOOP_CHANGE_FD : + err =lo_ioctl (inode, file, cmd, arg); +break ; + } +unlock_kernel (); +return err; +} +#endif +static int lo_open (struct inode *inode,struct file *file) {struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1191,6 +1264,9 @@ .open = lo_open, .release = lo_release, .ioctl = lo_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = lo_compat_ioctl, +#endif };/*
fs/compat_ioctl.c +0 -67
79 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -6
@@ -204,12 +204,6 @@COMPATIBLE_IOCTL (DVD_AUTH)/* pktcdvd */ COMPATIBLE_IOCTL (PACKET_CTRL_CMD) -/* Big L */ -ULONG_IOCTL(LOOP_SET_FD) -ULONG_IOCTL(LOOP_CHANGE_FD) -COMPATIBLE_IOCTL(LOOP_CLR_FD) -COMPATIBLE_IOCTL(LOOP_GET_STATUS64) -COMPATIBLE_IOCTL(LOOP_SET_STATUS64)/* Big A */ /* sparc only */ /* Big Q for sound/OSS */
--
Re: [PATCH 13/25] loop: move ioctl32 code to loop.c
Quoted 7 lines · Arnd Bergmann
The loop device driver is the only user of its ioctl commands, so we can move the conversion handlers for 32 bit emulation into the driver itself.
This patch just moves over the function, it would probably be a good idea to get rid of get_fs/set_fs calls here by integrating better with the driver.
Yes. just moving over is pointless. for things like loop where there's just one driver implementing the api moving it there does make sense, but please bring the compat layer up to standards first.
Arnd Bergmann
maintainerPATCH 14/25 smbfs: simplify compat_ioctl handling
In reply to Arnd Bergmannsmbfs already handles SMB_IOC_GETMOUNTUID with both 16 and 32 bit arguments, so the compatibility wrapper is not needed any more. The only other ioctl used in smbfs is SMB_IOC_NEWCONN, which is compatible as well.
This simply introduces a new compat_ioctl function that calls the regular smb_ioctl function.
fs/compat_ioctl.c +0 -21
@@ -331,24 +331,6 @@return err; } -static int do_smb_getmountuid (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -__kernel_uid_t kuid; -int err; - - cmd =SMB_IOC_GETMOUNTUID ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kuid); -set_fs (old_fs); - -if (err >=0 ) - err =put_user (kuid, (compat_uid_t __user *)compat_ptr (arg)); - -return err; -} - static __attribute_used__ intret_einval (unsigned int fd,unsigned int cmd,unsigned long arg) {
@@ -938,9 +920,6 @@ HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)#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) /* vfat */ HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)HANDLE_IOCTL (VFAT_IOCTL_READDIR_SHORT32 , vfat_ioctl32)
fs/smbfs/ioctl.c +16 -0
@@ -7,6 +7,8 @@* Please add a note about your changes to smbfs in the ChangeLog file. */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/ioctl.h>
@@ -65,3 +67,17 @@return result; } + +#ifdef CONFIG_COMPAT +/* All three ioctl numbers above are compatible */ +long +smb_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +int result; +lock_kernel (); + arg = (unsigned long )compat_ptr (arg); + result =smb_ioctl (file->f_dentry->d_inode, file, cmd, arg); +unlock_kernel (); +return result; +} +#endif
include/linux/compat_ioctl.h +0 -2
@@ -379,8 +379,6 @@/* Raw devices */ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) -/* SMB ioctls which do not need any translations */ -COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) /* NCP ioctls which do not need any translations */ COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
fs/smbfs/file.c +4 -0
@@ -7,6 +7,7 @@* Please add a note about your changes to smbfs in the ChangeLog file. */ +#include <linux/config.h> #include <linux/time.h> #include <linux/kernel.h> #include <linux/errno.h>
@@ -408,6 +409,9 @@ .read = smb_file_read, .write = smb_file_write, .ioctl = smb_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = smb_compat_ioctl, +#endif .mmap = smb_file_mmap, .open = smb_file_open, .release = smb_file_release,
fs/smbfs/proto.h +1 -0
@@ -68,6 +68,7 @@extern struct inode_operations smb_file_inode_operations;/* ioctl.c */ extern int smb_ioctl (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg); +extern long smb_compat_ioctl (struct file *filp,unsigned int cmd,unsigned long arg);/* smbiod.c */ extern void smbiod_wake_up (void );extern int smbiod_register_server (struct smb_sb_info *server);
fs/smbfs/dir.c +4 -0
@@ -7,6 +7,7 @@* Please add a note about your changes to smbfs in the ChangeLog file. */ +#include <linux/config.h> #include <linux/time.h> #include <linux/errno.h> #include <linux/kernel.h>
@@ -39,6 +40,9 @@ .read = generic_read_dir, .readdir = smb_readdir, .ioctl = smb_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = smb_compat_ioctl, +#endif .open = smb_dir_open, };
--
Arnd Bergmann
maintainerPATCH 15/25 autofs: move ioctl32 to autofs{,4}/root.c
In reply to Arnd BergmannAll autofs ioctl calls are simple to convert for 32 bit compatibility. This just moves the handler into the file system code.
fs/autofs/root.c +35 -0
@@ -10,6 +10,8 @@* * ------------------------------------------------------------------------- */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/errno.h> #include <linux/stat.h> #include <linux/param.h>
@@ -24,11 +26,15 @@static int autofs_root_rmdir (struct inode *,struct dentry *);static int autofs_root_mkdir (struct inode *,struct dentry *,int );static int autofs_root_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +static long autofs_root_compat_ioctl (struct file *,unsigned int ,unsigned long );struct file_operations autofs_root_operations = { .read = generic_read_dir, .readdir = autofs_root_readdir, .ioctl = autofs_root_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = autofs_root_compat_ioctl, +#endif };struct inode_operations autofs_root_inode_operations = {
@@ -562,3 +568,32 @@return -ENOSYS ; } } + +#ifdef CONFIG_COMPAT +/* AUTOFS */ +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) + +static long autofs_root_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +int ret; + +switch (cmd) { +case AUTOFS_IOC_SETTIMEOUT32 : + cmd =AUTOFS_IOC_SETTIMEOUT ; +case AUTOFS_IOC_CATATONIC : +case AUTOFS_IOC_PROTOVER : +case AUTOFS_IOC_EXPIRE : + arg = (unsigned long )compat_ptr (arg); +case AUTOFS_IOC_READY : +case AUTOFS_IOC_FAIL : +lock_kernel (); + ret =autofs_root_ioctl (file->f_dentry->d_inode, file, cmd, arg); +unlock_kernel (); +break ; +default : + ret = -ENOIOCTLCMD ; + } +return ret; +} +#endif
fs/autofs4/root.c +41 -0
62 lines not on this page · raw message
fs/compat_ioctl.c +0 -7
@@ -337,11 +337,6 @@return -EINVAL ; } -static int ioc_settimeout (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -return rw_long (fd,AUTOFS_IOC_SETTIMEOUT , arg); -} -/* Bluetooth ioctls */ #define HCIUARTSETPROTO _IOW('U', 200, int)#define HCIUARTGETPROTO _IOR('U', 201, int)
@@ -918,8 +913,6 @@ HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)HANDLE_IOCTL (CDROM_SEND_PACKET , cdrom_ioctl_trans) -#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) -HANDLE_IOCTL (AUTOFS_IOC_SETTIMEOUT32 , ioc_settimeout) /* vfat */ HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)HANDLE_IOCTL (VFAT_IOCTL_READDIR_SHORT32 , vfat_ioctl32)
include/linux/compat_ioctl.h +0 -11
@@ -360,17 +360,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) COMPATIBLE_IOCTL(OSS_GETVERSION) -/* AUTOFS */ -ULONG_IOCTL(AUTOFS_IOC_READY) -ULONG_IOCTL(AUTOFS_IOC_FAIL) -COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER) -COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST) -COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST) -COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT) /* DEVFS */ COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV) COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
--
Ian Kent
maintainerRe: [PATCH 15/25] autofs: move ioctl32 to autofs{,4}/root.c
Quoted 3 lines · Arnd Bergmann
All autofs ioctl calls are simple to convert for 32 bit compatibility. This just moves the handler into the file system code.
I have a couple of concerns with these patches.
I'm not sure if I like conditional compilation in the code proper but I'll leave it to you to make the final decision since your running with the change. Is there a reason the definitions can't simply be left in place?
Its been a while since I trawled through the compat ioctl code (please point me to the right place) but with this change I think that the AUTOFS_IOC_SETTIMEOUT32 is redundant. Consider a conditional define for AUTOFS_IOC_SETTIMEOUT in include/linux/auto_fs.h instead. Both autofs and autofs4 use that definition.
The lock_kernel()/unlock_kernel() in the autofs4 patch is ineffective as the BKL is not used for syncronisation anywhere else in autofs4. If removing it causes problems I need to know about'em so I can fix'em (hopefully).
Can't see any other obvious issues.
Ian
Quoted 2 lines
Quoted 191 lines
Signed-off-by Arnd Bergmann <[email protected]>Index:
linux-cg/fs/autofs/root.c
===================================================================fs/autofs/root.c +35
-0@@ -10,6 +10,8 @@* * ------------------------------------------------------------------------- */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/errno.h> #include <linux/stat.h> #include <linux/param.h> @@ -24,11 +26,15 @@static int autofs_root_rmdir (struct inode *,struct dentry *);static int autofs_root_mkdir (struct inode *,struct dentry *,int );static int autofs_root_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +static long autofs_root_compat_ioctl (struct file *,unsigned int ,unsigned long );struct file_operations autofs_root_operations = { .read = generic_read_dir, .readdir = autofs_root_readdir, .ioctl = autofs_root_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = autofs_root_compat_ioctl, +#endif };struct inode_operations autofs_root_inode_operations = {@@ -562,3 +568,32 @@return -ENOSYS ; } } + +#ifdef CONFIG_COMPAT +/* AUTOFS */ +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) + +static long autofs_root_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +int ret; + +switch (cmd) { +case AUTOFS_IOC_SETTIMEOUT32 : + cmd =AUTOFS_IOC_SETTIMEOUT ; +case AUTOFS_IOC_CATATONIC : +case AUTOFS_IOC_PROTOVER : +case AUTOFS_IOC_EXPIRE : + arg = (unsigned long )compat_ptr (arg); +case AUTOFS_IOC_READY : +case AUTOFS_IOC_FAIL : +lock_kernel (); + ret =autofs_root_ioctl (file->f_dentry->d_inode, file, cmd, arg); +unlock_kernel (); +break ; +default : + ret = -ENOIOCTLCMD ; + } +return ret; +} +#endif Index:
linux-cg/fs/autofs4/root.c
===================================================================fs/autofs4/root.c +41
-0@@ -12,6 +12,8 @@* * ------------------------------------------------------------------------- */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/errno.h> #include <linux/stat.h> #include <linux/param.h> @@ -24,6 +26,7 @@static int autofs4_dir_rmdir (struct inode *,struct dentry *);static int autofs4_dir_mkdir (struct inode *,struct dentry *,int );static int autofs4_root_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +static long autofs4_root_compat_ioctl (struct file *,unsigned int ,unsigned long );static int autofs4_dir_open (struct inode *inode,struct file *file);static int autofs4_dir_close (struct inode *inode,struct file *file);static int autofs4_dir_readdir (struct file * filp,void * dirent,filldir_t filldir);@@ -37,6 +40,9 @@ .read = generic_read_dir, .readdir = autofs4_root_readdir, .ioctl = autofs4_root_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = autofs4_root_compat_ioctl, +#endif };struct file_operations autofs4_dir_operations = {@@ -817,3 +823,38 @@return -ENOSYS ; } } + +#ifdef CONFIG_COMPAT +/* AUTOFS */ +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) + +static long autofs4_root_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +int ret; + +switch (cmd) { +case AUTOFS_IOC_SETTIMEOUT32 : + cmd =AUTOFS_IOC_SETTIMEOUT ; +case AUTOFS_IOC_CATATONIC : +case AUTOFS_IOC_PROTOVER : +case AUTOFS_IOC_EXPIRE : +case AUTOFS_IOC_EXPIRE_MULTI : +case AUTOFS_IOC_PROTOSUBVER : +case AUTOFS_IOC_ASKREGHOST : +case AUTOFS_IOC_TOGGLEREGHOST : +case AUTOFS_IOC_ASKUMOUNT : + arg = (unsigned long )compat_ptr (arg); +case AUTOFS_IOC_READY : +case AUTOFS_IOC_FAIL : +lock_kernel (); + ret =autofs4_root_ioctl (file->f_dentry->d_inode, + file, cmd, arg); +unlock_kernel (); +break ; +default : + ret = -ENOIOCTLCMD ; + } +return ret; +} +#endif Index:
linux-cg/fs/compat_ioctl.c
===================================================================fs/compat_ioctl.c +0
-7@@ -337,11 +337,6 @@return -EINVAL ; } -static int ioc_settimeout (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -return rw_long (fd,AUTOFS_IOC_SETTIMEOUT , arg); -} -/* Bluetooth ioctls */ #define HCIUARTSETPROTO _IOW('U', 200, int)#define HCIUARTGETPROTO _IOR('U', 201, int)@@ -918,8 +913,6 @@ HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)HANDLE_IOCTL (CDROM_SEND_PACKET , cdrom_ioctl_trans) -#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) -HANDLE_IOCTL (AUTOFS_IOC_SETTIMEOUT32 , ioc_settimeout) /* vfat */ HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)HANDLE_IOCTL (VFAT_IOCTL_READDIR_SHORT32 , vfat_ioctl32)Index:
linux-cg/include/linux/compat_ioctl.h
===================================================================include/linux/compat_ioctl.h +0
-13@@ -360,17 +360,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) COMPATIBLE_IOCTL(OSS_GETVERSION) -/* AUTOFS */ -ULONG_IOCTL(AUTOFS_IOC_READY) -ULONG_IOCTL(AUTOFS_IOC_FAIL) -COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER) -COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST) -COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST) -COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT) /* DEVFS */ COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV) COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK) -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Arnd Bergmann
maintainerRe: [PATCH 15/25] autofs: move ioctl32 to autofs{,4}/root.c
Quoted 5 lines · Ian Kent
On Sat, 5 Nov 2005, Arnd Bergmann wrote:
I'm not sure if I like conditional compilation in the code proper but I'll leave it to you to make the final decision since your running with the change. Is there a reason the definitions can't simply be left in place?
I think the compat_ptr() macro is not defined on architectures that don't have 32 bit compat code, but we could change that.
Quoted 5 lines
Its been a while since I trawled through the compat ioctl code (please point me to the right place) but with this change I think that the
AUTOFS_IOC_SETTIMEOUT32is redundant. Consider a conditional define forAUTOFS_IOC_SETTIMEOUTininclude/linux/auto_fs.hinstead. Both autofs and autofs4 use that definition.
The point here is that the two are different on 64 bit platforms, since sizeof (int) != sizeof (long). You also can't do
switch (cmd) {
case AUTOFS_IOC_SETTIMEOUT32:
case AUTOFS_IOC_SETTIMEOUT:
return do_stuff(); }
because then gcc would complain about duplicate case targets on 32 bit targets.
Quoted 4 lines
The lock_kernel()/unlock_kernel() in the autofs4 patch is ineffective as the BKL is not used for syncronisation anywhere else in autofs4. If removing it causes problems I need to know about'em so I can fix'em (hopefully).
I used the BKL here in order to maintain the current semantics, because ioctl is always called with BKL held, and compat_ioctl is called without it.
If you are sure you don't need the BKL, then you should also replace ".ioctl = ..." with ".unlocked_ioctl = ...".
Arnd <><
Ian Kent
maintainerRe: [PATCH 15/25] autofs: move ioctl32 to autofs{,4}/root.c
Quoted 19 lines · Arnd Bergmann
Quoted 5 lines · Ian Kent
On Sat, 5 Nov 2005, Arnd Bergmann wrote:
I'm not sure if I like conditional compilation in the code proper but I'll leave it to you to make the final decision since your running with the change. Is there a reason the definitions can't simply be left in place?
I think the
compat_ptr()macro is not defined on architectures that don't have 32 bit compat code, but we could change that.Quoted 5 lines
Its been a while since I trawled through the compat ioctl code (please point me to the right place) but with this change I think that the
AUTOFS_IOC_SETTIMEOUT32is redundant. Consider a conditional define forAUTOFS_IOC_SETTIMEOUTininclude/linux/auto_fs.hinstead. Both autofs and autofs4 use that definition.The point here is that the two are different on 64 bit platforms, since sizeof (int) != sizeof (long). You also can't do
Quoted 8 lines
switch (cmd) {
caseAUTOFS_IOC_SETTIMEOUT32:
caseAUTOFS_IOC_SETTIMEOUT:return do_stuff(); }because then gcc would complain about duplicate case targets on 32 bit targets.
I was thinking that if the module was compiled for 64bit then the 64bit definition would prevail and visa versa.
eg. In the include file.
#ifdef COMPAT_IOCTL
#define AUTOFS_IOC_SETTIMEOUT(..., unsigned int)
#else
#define AUTOFS_IOC_SETTIMEOUT(...,unsigned long)
#endif
I think I'm going to have to investigate further following the implementation.
Quoted 9 lines
Quoted 5 lines
The lock_kernel()/unlock_kernel() in the autofs4 patch is ineffective as the BKL is not used for syncronisation anywhere else in autofs4. If removing it causes problems I need to know about'em so I can fix'em (hopefully).
I used the BKL here in order to maintain the current semantics, because ioctl is always called with BKL held, and
compat_ioctlis called without it.
Of course a sensible approach.
Quoted 3 lines
If you are sure you don't need the BKL, then you should also replace ".ioctl = ..." with ".unlocked_ioctl = ...".
Yep. I'll check and amend it later.
After all it will be part of the module then.
Thanks
Ian
Ian Kent
maintainerRe: [PATCH 15/25] autofs: move ioctl32 to autofs{,4}/root.c
Quoted 24 lines · Ian Kent
Quoted 10 lines
Quoted 6 lines
Its been a while since I trawled through the compat ioctl code (please point me to the right place) but with this change I think that the
AUTOFS_IOC_SETTIMEOUT32is redundant. Consider a conditional define forAUTOFS_IOC_SETTIMEOUTininclude/linux/auto_fs.hinstead. Both autofs and autofs4 use that definition.The point here is that the two are different on 64 bit platforms, since sizeof (int) != sizeof (long). You also can't do
Quoted 8 lines
switch (cmd) {
caseAUTOFS_IOC_SETTIMEOUT32:
caseAUTOFS_IOC_SETTIMEOUT:return do_stuff(); }because then gcc would complain about duplicate case targets on 32 bit targets.
I was thinking that if the module was compiled for 64bit then the 64bit definition would prevail and visa versa.
eg. In the include file.
Quoted 8 lines
#ifdef
COMPAT_IOCTL
#defineAUTOFS_IOC_SETTIMEOUT(..., unsigned int)
#else
#defineAUTOFS_IOC_SETTIMEOUT(...,unsigned long)
#endifI think I'm going to have to investigate further following the implementation.
Yes. I see now, stupid suggestion.
Quoted 7 lines
Quoted 4 lines
If you are sure you don't need the BKL, then you should also replace ".ioctl = ..." with ".unlocked_ioctl = ...".
Yep. I'll check and amend it later.
After all it will be part of the module then.
Yep. I'll do that.
Ian
Arnd Bergmann
maintainerPATCH 16/25 ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
In reply to Arnd BergmannThe ncp specific compat ioctls are clearly local to one file system, so the code can better live there.
This could be further improved by getting rid of get_fs/set_fs in the future.
fs/compat_ioctl.c +0 -197
@@ -718,193 +718,6 @@ return sys_ioctl(fd, cmd, (unsigned long)tdata); } -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -struct ncp_ioctl_request_32 { -u32 function; -u32 size; -compat_caddr_t data; -}; - -struct ncp_fs_info_v2_32 { -s32 version; -u32 mounted_uid; -u32 connection; -u32 buffer_size; - -u32 volume_number; -u32 directory_id; - -u32 dummy1; -u32 dummy2; -u32 dummy3; -}; - -struct ncp_objectname_ioctl_32 -{ -s32 auth_type; -u32 object_name_len; -compat_caddr_t object_name;/* an userspace data, in most cases user name */ -}; - -struct ncp_privatedata_ioctl_32 -{ -u32 len; -compat_caddr_t data;/* ~1000 for NDS */ -}; - -#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32) -#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32) -#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32) -#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32) -#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32) - -static int do_ncp_ncprequest (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_ioctl_request_32 n32; -struct ncp_ioctl_request __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32)) || -put_user (n32.function, &p->function) || -put_user (n32.size, &p->size) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_NCPREQUEST , (unsigned long )p); -} - -static int do_ncp_getmountuid2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -__kernel_uid_t kuid; -int err; - - cmd =NCP_IOC_GETMOUNTUID2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kuid); -set_fs (old_fs); - -if (!err) - err =put_user (kuid, - (unsigned int __user *)compat_ptr (arg)); - -return err; -} - -static int do_ncp_getfsinfo2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -struct ncp_fs_info_v2_32 n32; -struct ncp_fs_info_v2 n; -int err; - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32))) -return -EFAULT ; -if (n32.version !=NCP_GET_FS_INFO_VERSION_V2 ) -return -EINVAL ; - n.version =NCP_GET_FS_INFO_VERSION_V2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd,NCP_IOC_GET_FS_INFO_V2 , (unsigned long )&n); -set_fs (old_fs); - -if (!err) { - n32.version = n.version; - n32.mounted_uid = n.mounted_uid; - n32.connection = n.connection; - n32.buffer_size = n.buffer_size; - n32.volume_number = n.volume_number; - n32.directory_id = n.directory_id; - n32.dummy1 = n.dummy1; - n32.dummy2 = n.dummy2; - n32.dummy3 = n.dummy3; - err =copy_to_user (compat_ptr (arg), &n32,sizeof (n32)) ? -EFAULT :0 ; - } -return err; -} - -static int do_ncp_getobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); -s32 auth_type; -u32 name_len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETOBJECTNAME , (unsigned long )p); -if (err) -return err; - -if (get_user (auth_type, &p->auth_type) || -put_user (auth_type, &p32->auth_type) || -get_user (name_len, &p->object_name_len) || -put_user (name_len, &p32->object_name_len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.auth_type, &p->auth_type) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETOBJECTNAME , (unsigned long )p); -} - -static int do_ncp_getprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); -u32 len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETPRIVATEDATA , (unsigned long )p); -if (err) -return err; - -if (get_user (len, &p->len) || -put_user (len, &p32->len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32; -struct ncp_privatedata_ioctl_32 __user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETPRIVATEDATA , (unsigned long )p); -} -#endif -#undef CODE#endif
@@ -937,15 +750,5 @@ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) -HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) -HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) -HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) -HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) -HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) -HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) -#endif -#undef DECLARES#endif
fs/ncpfs/dir.c +3 -0
@@ -54,6 +54,9 @@ .read = generic_read_dir, .readdir = ncp_readdir, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif }; struct inode_operations ncp_dir_inode_operations =
fs/ncpfs/file.c +4 -0
@@ -9,6 +9,7 @@#include <asm/uaccess.h> #include <asm/system.h> +#include <linux/config.h> #include <linux/time.h> #include <linux/kernel.h> #include <linux/errno.h>
@@ -289,6 +290,9 @@ .read = ncp_file_read, .write = ncp_file_write, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif .mmap = ncp_mmap, .release = ncp_release, .fsync = ncp_fsync,
fs/ncpfs/ioctl.c +239 -2
256 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -12
@@ -368,18 +368,6 @@/* Raw devices */ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) -/* NCP ioctls which do not need any translations */ -COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK) -COMPATIBLE_IOCTL(NCP_IOC_GETROOT) -COMPATIBLE_IOCTL(NCP_IOC_SETROOT) -COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL) -COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL) /* Little a */ COMPATIBLE_IOCTL(ATMSIGD_CTRL) COMPATIBLE_IOCTL(ATMARPD_CTRL)
include/linux/ncp_fs.h +1 -0
@@ -244,6 +244,7 @@/* linux/fs/ncpfs/ioctl.c */ int ncp_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +long ncp_compat_ioctl (struct file *,unsigned int ,unsigned long );/* linux/fs/ncpfs/sock.c */ int ncp_request2(struct ncp_server *server, int function,
--
Arnd Bergmann
maintainerPATCH 17/25 vfat: move ioctl32 code to fs/fat/dir.c
In reply to Arnd BergmannThe vfat compat ioctls are clearly local to a single file system, so the code can better be part of that file system.
This can be further improved in the future by getting rid of get_fs/set_fs calls.
fs/compat_ioctl.c +0 -48
@@ -356,51 +356,6 @@#define HIDPGETCONNLIST _IOR('H', 210, int)#define HIDPGETCONNINFO _IOR('H', 211, int) -#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) -#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) - -static long -put_dirent32 (struct dirent *d,struct compat_dirent __user *d32) -{ -if (!access_ok (VERIFY_WRITE , d32,sizeof (struct compat_dirent ))) -return -EFAULT ; - -__put_user (d->d_ino, &d32->d_ino); -__put_user (d->d_off, &d32->d_off); -__put_user (d->d_reclen, &d32->d_reclen); -if (__copy_to_user (d32->d_name, d->d_name, d->d_reclen)) -return -EFAULT ; - -return 0 ; -} - -static int vfat_ioctl32 (unsigned fd,unsigned cmd,unsigned long arg) -{ -struct compat_dirent __user *p =compat_ptr (arg); -int ret; -mm_segment_t oldfs =get_fs (); -struct dirent d[2 ]; - -switch (cmd) - { -case VFAT_IOCTL_READDIR_BOTH32 : - cmd =VFAT_IOCTL_READDIR_BOTH ; -break ; -case VFAT_IOCTL_READDIR_SHORT32 : - cmd =VFAT_IOCTL_READDIR_SHORT ; -break ; - } - -set_fs (KERNEL_DS ); - ret =sys_ioctl (fd,cmd,(unsigned long )&d); -set_fs (oldfs); -if (ret >=0 ) { - ret |=put_dirent32 (&d[0 ], p); - ret |=put_dirent32 (&d[1 ], p +1 ); - } -return ret; -} -#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)static int reiserfs_ioctl32 (unsigned fd,unsigned cmd,unsigned long ptr)
@@ -726,9 +681,6 @@ HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans) HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans) -/* vfat */ -HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32) -HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)HANDLE_IOCTL (REISERFS_IOC_UNPACK32 , reiserfs_ioctl32) /* Raw devices */HANDLE_IOCTL (RAW_SETBIND , raw_ioctl)
fs/fat/dir.c +54 -0
70 lines not on this page · raw message
--
OGAWA Hirofumi
maintainerRe: [PATCH 17/25] vfat: move ioctl32 code to fs/fat/dir.c
fs/fat/dir.c line 777
Quoted 4 lines · Arnd Bergmann
fs/fat/dir.c +4
-0+#ifdef CONFIG_COMPAT +/* vfat */ +#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) +#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
^^^^^^
Please use a SPACE after #define, and kill a useless "/* vfat */".
fs/fat/dir.c line 789
Quoted 11 lines
fs/fat/dir.c +11
-0+static long +put_dirent32 (struct dirent *d,struct compat_dirent __user * d32) +{ +if (!access_ok (VERIFY_WRITE , d32,sizeof (struct compat_dirent ))) +return -EFAULT ; + +__put_user (d->d_ino, &d32->d_ino); +__put_user (d->d_off, &d32->d_off); +__put_user (d->d_reclen, &d32->d_reclen); +if (__copy_to_user (d32->d_name, d->d_name, d->d_reclen)) +return -EFAULT ;
Why don't we need to check the return value of __put_user()?
fs/fat/dir.c line 817
Quoted 6 lines
fs/fat/dir.c +6
-0+set_fs (KERNEL_DS ); + ret =fat_dir_ioctl (file->f_dentry->d_inode, file, cmd, (unsigned long ) &d); +set_fs (oldfs); +if (ret >=0 ) { + ret |=put_dirent32 (&d[0 ], p); + ret |=put_dirent32 (&d[1 ], p +1 );
If "ret" is not 0, we can't use "|=" here?
This patch seems to have bugs, although original one too.
Signature · 1 line
OGAWA Hirofumi <[email protected]>
Arnd Bergmann
maintainerRe: [PATCH 17/25] vfat: move ioctl32 code to fs/fat/dir.c
Quoted 9 lines · OGAWA Hirofumi
fs/fat/dir.c line 777
Quoted 4 lines · Arnd Bergmann
fs/fat/dir.c +4
-0+#ifdef CONFIG_COMPAT +/* vfat */ +#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) +#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])^^^^^^Please use a SPACE after #define, and kill a useless "/* vfat */".
ok.
Quoted 5 lines
Quoted 5 lines
fs/fat/dir.c +5
-0+static long +put_dirent32 (struct dirent *d,struct compat_dirent __user * d32) +{ +if (!access_ok (VERIFY_WRITE , d32,sizeof (struct compat_dirent ))) +return -EFAULT ;
Quoted 8 lines
fs/fat/dir.c line 789
Quoted 6 lines
fs/fat/dir.c +6
-0+ +__put_user (d->d_ino, &d32->d_ino); +__put_user (d->d_off, &d32->d_off); +__put_user (d->d_reclen, &d32->d_reclen); +if (__copy_to_user (d32->d_name, d->d_name, d->d_reclen)) +return -EFAULT ;Why don't we need to check the return value of
__put_user()?
This is a bug in the code that I copied over, and it needs to be fixed, thanks.
Quoted 10 lines
fs/fat/dir.c line 817
Quoted 6 lines
fs/fat/dir.c +6
-0+set_fs (KERNEL_DS ); + ret =fat_dir_ioctl (file->f_dentry->d_inode, file, cmd, (unsigned long ) &d); +set_fs (oldfs); +if (ret >=0 ) { + ret |=put_dirent32 (&d[0 ], p); + ret |=put_dirent32 (&d[1 ], p +1 );If "ret" is not 0, we can't use "|=" here?
This patch seems to have bugs, although original one too.
Right. In my patches I tried to change as little as possible to avoid introducing new bugs, but this one is already so broken, that it's better to do a clean implementation from scratch.
Arnd <><
Re: [PATCH 17/25] vfat: move ioctl32 code to fs/fat/dir.c
In reply to Arnd Bergmannfs/fat/dir.c line 777
Quoted 4 lines
fs/fat/dir.c +4
-0+#ifdef CONFIG_COMPAT +/* vfat */ +#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) +#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
these should be moved close to the original VFAT ioctl defintions. And there's no need to put them under ifdef.
fs/fat/dir.c line 787
Quoted 9 lines
fs/fat/dir.c +9
-0+static long +put_dirent32 (struct dirent *d,struct compat_dirent __user * d32) +{ +if (!access_ok (VERIFY_WRITE , d32,sizeof (struct compat_dirent ))) +return -EFAULT ; + +__put_user (d->d_ino, &d32->d_ino); +__put_user (d->d_off, &d32->d_off); +__put_user (d->d_reclen, &d32->d_reclen);
missing error checks.
fs/fat/dir.c line 799
Quoted 6 lines
fs/fat/dir.c +6
-0+static long fat_dir_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +struct compat_dirent __user *p =compat_ptr (arg); +int ret; +mm_segment_t oldfs =get_fs (); +struct dirent d[2 ];
please use proper compat_alloc_user_space here.
Quoted 4 lines
fs/fat/dir.c +4
-0+switch (cmd) { +case VFAT_IOCTL_READDIR_BOTH32 : + cmd =VFAT_IOCTL_READDIR_BOTH ; +break ;
fs/fat/dir.c line 814
Quoted 10 lines
fs/fat/dir.c +10
-0+case VFAT_IOCTL_READDIR_SHORT32 : + cmd =VFAT_IOCTL_READDIR_SHORT ; +break ; +default : +return -ENOIOCTLCMD ; + } + +set_fs (KERNEL_DS ); + ret =fat_dir_ioctl (file->f_dentry->d_inode, file, cmd, (unsigned long ) &d); +set_fs (oldfs);
In fact there's even a much better way to implement this, let the ioctls call __fat_readdir directly with a filldir callback that directly works in compat_dirent structures.
Arnd Bergmann
maintainerRe: [PATCH 17/25] vfat: move ioctl32 code to fs/fat/dir.c
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines
+ set_fs(KERNEL_DS);
+ ret =fat_dir_ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long) &d); + set_fs(oldfs);In fact there's even a much better way to implement this, let the ioctls call
__fat_readdirdirectly with a filldir callback that directly works incompat_direntstructures.
Yes, I'll do that.
Arnd <><
Arnd Bergmann
maintainerPATCH 18/25 raw: move ioctl32 code to raw.c
In reply to Arnd BergmannThe two ioctl commands for the raw driver are not used anywhere outside of raw.c, so move the compat handler there as well.
Since they were previously registered both as compatible and with a conversion handler, it is not clear if this ever worked before.
Forwarding ioctl commands to the underlying block device needs adaptations here as well because of the earlier block device compat ioctl patch.
drivers/char/raw.c +91 -0
@@ -8,6 +8,8 @@* device are used to bind the other minor numbers to block devices. */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/devfs_fs_kernel.h>
@@ -125,6 +127,16 @@return blkdev_ioctl (bdev->bd_inode,NULL , command, arg); } +#ifdef CONFIG_COMPAT +static long +raw_compat_ioctl (struct file *filp,unsigned int command,unsigned long arg) +{ +struct block_device *bdev = filp->private_data; + +return compat_blkdev_ioctl (bdev->bd_inode,NULL , command, arg); +} +#endif +static void bind_device (struct raw_config_request *rq) {class_device_destroy (raw_class,MKDEV (RAW_MAJOR , rq->raw_minor));
@@ -238,6 +250,79 @@return err; } +#ifdef CONFIG_COMPAT +/* Raw devices */ +struct raw32_config_request { +compat_int_t raw_minor; +__u64 block_major; +__u64 block_minor; +} __attribute__ ((packed)); + +static int get_raw32_request (struct raw_config_request *req, +struct raw32_config_request __user * user_req) +{ +int ret; + +if (!access_ok + (VERIFY_READ , user_req,sizeof (struct raw32_config_request ))) +return -EFAULT ; + + ret =__get_user (req->raw_minor, &user_req->raw_minor); + ret |=__get_user (req->block_major, &user_req->block_major); + ret |=__get_user (req->block_minor, &user_req->block_minor); + +return ret ? -EFAULT :0 ; +} + +static int set_raw32_request (struct raw_config_request *req, +struct raw32_config_request __user * user_req) +{ +int ret; + +if (!access_ok + (VERIFY_WRITE , user_req,sizeof (struct raw32_config_request ))) +return -EFAULT ; + + ret =__put_user (req->raw_minor, &user_req->raw_minor); + ret |=__put_user (req->block_major, &user_req->block_major); + ret |=__put_user (req->block_minor, &user_req->block_minor); + +return ret ? -EFAULT :0 ; +} + +static long raw_ctl_compat_ioctl (struct file *file,unsigned cmd, +unsigned long arg) +{ +int ret = -ENOIOCTLCMD ; + +switch (cmd) { +case RAW_SETBIND : +case RAW_GETBIND :{ +struct raw_config_request req; +struct raw32_config_request __user *user_req = +compat_ptr (arg); +mm_segment_t oldfs =get_fs (); + +if ((ret =get_raw32_request (&req, user_req))) +return ret; + +set_fs (KERNEL_DS ); +lock_kernel (); + ret =raw_ctl_ioctl (file->f_dentry->d_inode, file, + cmd, (unsigned long ) &req); +unlock_kernel (); +set_fs (oldfs); + +if ((!ret) && (cmd ==RAW_GETBIND )) { + ret =set_raw32_request (&req, user_req); + } +break ; + } + } +return ret; +} +#endif +static ssize_t raw_file_write (struct file *file,const char __user *buf,size_t count,loff_t *ppos) {
@@ -269,6 +354,9 @@ .open = raw_open, .release= raw_release, .ioctl = raw_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = raw_compat_ioctl, +#endif .readv = generic_file_readv, .writev = generic_file_writev, .owner = THIS_MODULE,
@@ -276,6 +364,9 @@static struct file_operations raw_ctl_fops = { .ioctl = raw_ctl_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = raw_ctl_compat_ioctl, +#endif .open = raw_open, .owner =THIS_MODULE , };
fs/compat_ioctl.c +0 -68
80 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -3
@@ -365,9 +365,6 @@ COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK) COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE) COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK) -/* Raw devices */ -COMPATIBLE_IOCTL(RAW_SETBIND) -COMPATIBLE_IOCTL(RAW_GETBIND) /* Little a */ COMPATIBLE_IOCTL(ATMSIGD_CTRL) COMPATIBLE_IOCTL(ATMARPD_CTRL)
include/linux/fs.h +2 -1
@@ -1321,7 +1321,8 @@extern struct file_operations def_fifo_fops;extern int ioctl_by_bdev (struct block_device *,unsigned ,unsigned long );extern int blkdev_ioctl (struct inode *,struct file *,unsigned ,unsigned long ); -extern long compat_blkdev_ioctl (struct file *,unsigned ,unsigned long ); +extern long compat_blkdev_ioctl (struct inode *,struct file *, +unsigned ,unsigned long );extern int blkdev_get (struct block_device *,mode_t ,unsigned );extern int blkdev_put (struct block_device *);extern int bd_claim (struct block_device *,void *);
drivers/block/ioctl.c +4 -5
@@ -259,6 +259,7 @@return blkdev_driver_ioctl (inode, file, disk, cmd, arg); } +EXPORT_SYMBOL_GPL (blkdev_ioctl);#ifdef CONFIG_COMPAT static int w_long(struct inode *inode, struct file *file,
@@ -695,11 +696,10 @@/* Most of the generic ioctls are handled in the normal fallback path. This assumes the blkdev's low level compat_ioctl always returns ENOIOCTLCMD for unknown ioctls. */ -long compat_blkdev_ioctl (struct file *file,unsigned cmd,unsigned long arg) +long compat_blkdev_ioctl (struct inode *inode,struct file *file,unsigned cmd,unsigned long arg) { -struct block_device *bdev = file->f_dentry->d_inode->i_bdev; +struct block_device *bdev = inode->i_bdev;struct gendisk *disk = bdev->bd_disk; -struct inode *inode = file->f_mapping->host;int ret = -ENOIOCTLCMD ;switch (cmd) {
@@ -808,6 +808,5 @@ return ret; } +EXPORT_SYMBOL_GPL (compat_blkdev_ioctl);#endif - -EXPORT_SYMBOL_GPL (blkdev_ioctl);
fs/block_dev.c +9 -1
@@ -782,6 +782,14 @@return blkdev_ioctl (file->f_mapping->host, file, cmd, arg); } +#ifdef CONFIG_COMPAT +static long block_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +return compat_blkdev_ioctl (file->f_mapping->host, file, cmd, arg); +} +#endif +struct address_space_operations def_blk_aops = { .readpage = blkdev_readpage, .writepage = blkdev_writepage,
@@ -804,7 +812,7 @@ .fsync = block_fsync, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = compat_blkdev_ioctl, + .compat_ioctl = block_compat_ioctl, #endif .readv = generic_file_readv, .writev = generic_file_write_nolock,
--
Re: [PATCH 18/25] raw: move ioctl32 code to raw.c
Quoted 4 lines · Arnd Bergmann
The two ioctl commands for the raw driver are not used anywhere outside of
raw.c, so move the compat handler there as well.
...
Please leave this alone, the raw driver will be removed in 2.6.16.
cu
Adrian
Signature · 4 lines
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon SeedArnd Bergmann
maintainerRe: [PATCH 18/25] raw: move ioctl32 code to raw.c
Quoted 8 lines · Adrian Bunk
Quoted 4 lines · Arnd Bergmann
The two ioctl commands for the raw driver are not used anywhere outside of
raw.c, so move the compat handler there as well.
...Please leave this alone, the raw driver will be removed in 2.6.16.
Ok, good point.
Arnd <><
Arnd Bergmann
maintainerPATCH 19/25 usbdevfs: move ioctl32 into devio.c
In reply to Arnd Bergmannusbdevfs already has support for some compat ioctl code by handling it directly in its ioctl function and marking the numbers as compatible.
This patch moves over all remaining conversion handlers to the same file into a new compat_ioctl function. It should be further unified with the existing ioctl implementation in the future.
drivers/usb/core/devio.c +137 -2
@@ -1392,7 +1392,7 @@ }#ifdef CONFIG_COMPAT -static int proc_ioctl_compat (struct dev_state *ps,void __user *arg) +static int proc_ioctl_compat (struct dev_state *ps,unsigned long arg) {struct usbdevfs_ioctl32 __user *uioc;struct usbdevfs_ioctl ctrl;
@@ -1511,7 +1511,7 @@case USBDEVFS_IOCTL32 :snoop (&dev->dev,"%s: IOCTL\n" , __FUNCTION__); - ret =proc_ioctl_compat (ps, p); + ret =proc_ioctl_compat (ps, arg);break ;#endif
@@ -1556,6 +1556,138 @@return ret; } +#ifdef CONFIG_COMPAT +/* FIXME: put the conversion handlers into usbdev_ioctl() */ + +struct usbdevfs_ctrltransfer32 { +u8 bRequestType; +u8 bRequest; +u16 wValue; +u16 wIndex; +u16 wLength; +u32 timeout;/* in milliseconds */ +compat_caddr_t data; +}; + +#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) + +static int do_usbdevfs_control (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +struct usbdevfs_ctrltransfer32 __user *p32 =compat_ptr (arg); +struct usbdevfs_ctrltransfer __user *p; +__u32 udata; + p =compat_alloc_user_space (sizeof (*p)); +if (copy_in_user (p, p32, (sizeof (*p32) -sizeof (compat_caddr_t))) + ||get_user (udata, &p32->data) + ||put_user (compat_ptr (udata), &p->data)) +return -EFAULT ; +return usbdev_ioctl (inode, file,USBDEVFS_CONTROL , (unsigned long ) p); +} + +struct usbdevfs_bulktransfer32 { +compat_uint_t ep; +compat_uint_t len; +compat_uint_t timeout;/* in milliseconds */ +compat_caddr_t data; +}; + +#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32) + +static int do_usbdevfs_bulk (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +struct usbdevfs_bulktransfer32 __user *p32 =compat_ptr (arg); +struct usbdevfs_bulktransfer __user *p; +compat_uint_t n; +compat_caddr_t addr; + + p =compat_alloc_user_space (sizeof (*p)); + +if (get_user (n, &p32->ep) ||put_user (n, &p->ep) || +get_user (n, &p32->len) ||put_user (n, &p->len) || +get_user (n, &p32->timeout) ||put_user (n, &p->timeout) || +get_user (addr, &p32->data) + ||put_user (compat_ptr (addr), &p->data)) +return -EFAULT ; + +return usbdev_ioctl (inode, file,USBDEVFS_BULK , (unsigned long ) p); +} + +struct usbdevfs_disconnectsignal32 { +compat_int_t signr; +compat_caddr_t context; +}; + +#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32) + +static int do_usbdevfs_discsignal (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +struct usbdevfs_disconnectsignal kdis; +struct usbdevfs_disconnectsignal32 __user *udis; +mm_segment_t old_fs; +u32 uctx; +int err; + + udis =compat_ptr (arg); + +if (get_user (kdis.signr, &udis->signr) || +__get_user (uctx, &udis->context)) +return -EFAULT ; + + kdis.context =compat_ptr (uctx); + + old_fs =get_fs (); +set_fs (KERNEL_DS ); + err =usbdev_ioctl (inode, file,USBDEVFS_DISCSIGNAL , (unsigned long ) &kdis); +set_fs (old_fs); + +return err; +} + +static long +usbdev_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +int ret = -ENOIOCTLCMD ; + +lock_kernel (); +switch (cmd) { +case USBDEVFS_CONTROL32 : + ret =do_usbdevfs_control (inode, file, cmd, arg); +break ; +case USBDEVFS_BULK32 : + ret =do_usbdevfs_bulk (inode, file, cmd, arg); +break ; +case USBDEVFS_DISCSIGNAL32 : + ret =do_usbdevfs_discsignal (inode, file, cmd, arg); +break ; +case USBDEVFS_RESETEP : +case USBDEVFS_SETINTERFACE : +case USBDEVFS_SETCONFIGURATION : +case USBDEVFS_GETDRIVER : +case USBDEVFS_DISCARDURB : +case USBDEVFS_CLAIMINTERFACE : +case USBDEVFS_RELEASEINTERFACE : +case USBDEVFS_CONNECTINFO : +case USBDEVFS_HUB_PORTINFO : +case USBDEVFS_RESET : +case USBDEVFS_SUBMITURB32 : +case USBDEVFS_REAPURB32 : +case USBDEVFS_REAPURBNDELAY32 : +case USBDEVFS_IOCTL32 : +case USBDEVFS_CLEAR_HALT : + arg = (unsigned long )compat_ptr (arg); + ret =usbdev_ioctl (inode, file, cmd, arg); +break ; + } +unlock_kernel (); +return ret; +} +#endif + +/* No kernel lock - fine */ static unsigned int usbdev_poll (struct file *file,struct poll_table_struct *wait) {
@@ -1575,6 +1707,9 @@ .read = usbdev_read, .poll = usbdev_poll, .ioctl = usbdev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = usbdev_compat_ioctl, +#endif .open = usbdev_open, .release = usbdev_release, };
fs/compat_ioctl.c +0 -95
107 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -15
@@ -456,21 +456,6 @@ COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) -/* USB */ -COMPATIBLE_IOCTL(USBDEVFS_RESETEP) -COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE) -COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION) -COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER) -COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB) -COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE) -COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE) -COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO) -COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO) -COMPATIBLE_IOCTL(USBDEVFS_RESET) -COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32) -COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) -COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) -COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) /* NBD */ ULONG_IOCTL(NBD_SET_SOCK) ULONG_IOCTL(NBD_SET_BLKSIZE)
--
Arnd Bergmann
maintainerPATCH 20/25 i2c: move ioctl32 code to i2c-dev.c
In reply to Arnd BergmannThe conversion functions for i2c ioctl commands are all related to code in i2cdev_ioctl, so introduce move the conversion to a new i2cdev_compat_ioctl function in the same file.
These can probably be improved by not usingcompat_alloc_user_space.
In order to support I2C_SREAD, it might be necessary to introduce a compat_algo_control method for i2c devices.
drivers/i2c/i2c-dev.c +141 -0
@@ -26,6 +26,8 @@/* The I2C_RDWR ioctl code is written by Kolja Waschk <[email protected]> */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h>
@@ -358,6 +360,142 @@return 0 ; } +#ifdef CONFIG_COMPAT +struct i2c_msg32 { +u16 addr; +u16 flags; +u16 len; +compat_caddr_t buf; +}; + +struct i2c_rdwr_ioctl_data32 { +compat_caddr_t msgs;/* struct i2c_msg __user *msgs */ +u32 nmsgs; +}; + +struct i2c_smbus_ioctl_data32 { +u8 read_write; +u8 command; +u32 size; +compat_caddr_t data;/* union i2c_smbus_data *data */ +}; + +struct i2c_rdwr_aligned { +struct i2c_rdwr_ioctl_data cmd; +struct i2c_msg msgs[0 ]; +}; + +static int do_i2c_w_long (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +mm_segment_t old_fs =get_fs (); +int err; +unsigned long val; + +set_fs (KERNEL_DS ); + err =i2cdev_ioctl (inode, file, cmd, (unsigned long )&val); +set_fs (old_fs); +if (!err &&put_user (val, (u32 __user *)compat_ptr (arg))) +return -EFAULT ; +return err; +} + +static int do_i2c_rdwr_ioctl (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +struct i2c_rdwr_ioctl_data32 __user *udata =compat_ptr (arg); +struct i2c_rdwr_aligned __user *tdata; +struct i2c_msg __user *tmsgs; +struct i2c_msg32 __user *umsgs; +compat_caddr_t datap; +int nmsgs, i; + +if (get_user (nmsgs, &udata->nmsgs)) +return -EFAULT ; +if (nmsgs >I2C_RDRW_IOCTL_MAX_MSGS ) +return -EINVAL ; + +if (get_user (datap, &udata->msgs)) +return -EFAULT ; + umsgs =compat_ptr (datap); + + tdata =compat_alloc_user_space (sizeof (*tdata) + + nmsgs *sizeof (struct i2c_msg )); + tmsgs = &tdata->msgs[0 ]; + +if (put_user (nmsgs, &tdata->cmd.nmsgs) || +put_user (tmsgs, &tdata->cmd.msgs)) +return -EFAULT ; + +for (i =0 ; i < nmsgs; i++) { +if (copy_in_user (&tmsgs[i].addr, &umsgs[i].addr,3 *sizeof (u16))) +return -EFAULT ; +if (get_user (datap, &umsgs[i].buf) || +put_user (compat_ptr (datap), &tmsgs[i].buf)) +return -EFAULT ; + } +return i2cdev_ioctl (inode, file, cmd, (unsigned long )tdata); +} + +static int do_i2c_smbus_ioctl (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg) +{ +struct i2c_smbus_ioctl_data __user *tdata; +struct i2c_smbus_ioctl_data32 __user *udata; +compat_caddr_t datap; + + tdata =compat_alloc_user_space (sizeof (*tdata)); +if (tdata ==NULL ) +return -ENOMEM ; +if (!access_ok (VERIFY_WRITE , tdata,sizeof (*tdata))) +return -EFAULT ; + + udata =compat_ptr (arg); +if (!access_ok (VERIFY_READ , udata,sizeof (*udata))) +return -EFAULT ; + +if (__copy_in_user (&tdata->read_write, &udata->read_write,2 *sizeof (u8))) +return -EFAULT ; +if (__copy_in_user (&tdata->size, &udata->size,2 *sizeof (u32))) +return -EFAULT ; +if (__get_user (datap, &udata->data) || +__put_user (compat_ptr (datap), &tdata->data)) +return -EFAULT ; + +return i2cdev_ioctl (inode, file, cmd, (unsigned long )tdata); +} + +static long i2cdev_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +struct inode *inode = file->f_dentry->d_inode; +int ret = -ENOIOCTLCMD ; + +lock_kernel (); +switch (cmd) { +case I2C_FUNCS : + ret =do_i2c_w_long (inode, file, cmd, arg); +break ; +case I2C_RDWR : + ret =do_i2c_rdwr_ioctl (inode, file, cmd, arg); +break ; +case I2C_SMBUS : + ret =do_i2c_smbus_ioctl (inode, file, cmd, arg); +break ; +case I2C_SLAVE : +case I2C_SLAVE_FORCE : +case I2C_TENBIT : +case I2C_PEC : +case I2C_RETRIES : +case I2C_TIMEOUT : + arg = (unsigned long )compat_ptr (arg); + ret =i2cdev_ioctl (inode, file, cmd, arg); + } +unlock_kernel (); +return ret; +} +#endif +static int i2cdev_open (struct inode *inode,struct file *file) {unsigned int minor =iminor (inode);
@@ -404,6 +542,9 @@ .read = i2cdev_read, .write = i2cdev_write, .ioctl = i2cdev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = i2cdev_compat_ioctl, +#endif .open = i2cdev_open, .release = i2cdev_release, };
fs/compat_ioctl.c +0 -95
107 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -7
@@ -466,13 +466,6 @@ COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) ULONG_IOCTL(NBD_SET_SIZE_BLOCKS) COMPATIBLE_IOCTL(NBD_DISCONNECT) -/* i2c */ -COMPATIBLE_IOCTL(I2C_SLAVE) -COMPATIBLE_IOCTL(I2C_SLAVE_FORCE) -COMPATIBLE_IOCTL(I2C_TENBIT) -COMPATIBLE_IOCTL(I2C_PEC) -COMPATIBLE_IOCTL(I2C_RETRIES) -COMPATIBLE_IOCTL(I2C_TIMEOUT) /* hiddev */ COMPATIBLE_IOCTL(HIDIOCGVERSION) COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
--
Arnd Bergmann
maintainerPATCH 21/25 reiserfs: remove ioctl conversion code
In reply to Arnd BergmannAn earlier patch in this series already adds a handler for this in reiserfs itself, so the code in compat_ioctl.c is no longer needed.
fs/compat_ioctl.c +0 -11
@@ -356,16 +356,6 @@#define HIDPGETCONNLIST _IOR('H', 210, int)#define HIDPGETCONNINFO _IOR('H', 211, int) -#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int) - -static int reiserfs_ioctl32 (unsigned fd,unsigned cmd,unsigned long ptr) -{ -if (cmd ==REISERFS_IOC_UNPACK32 ) - cmd =REISERFS_IOC_UNPACK ; - -return sys_ioctl (fd,cmd,ptr); -} -struct serial_struct32 {compat_int_t type;compat_int_t line;
@@ -435,7 +425,6 @@ HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)HANDLE_IOCTL (CDROM_SEND_PACKET , cdrom_ioctl_trans) -HANDLE_IOCTL (REISERFS_IOC_UNPACK32 , reiserfs_ioctl32) /* Serial */ HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)HANDLE_IOCTL (TIOCSSERIAL , serial_struct_ioctl)
--
Arnd Bergmann
maintainerPATCH 22/25 serial: move ioctl32 code to tty_io.c
In reply to Arnd BergmannAll driver implementing TIOCGSERIAL are tty drivers, so the conversion handler can be part of tty_compat_ioctl.
In a perfect world, this would live in serial_core.c, but there are still a number of drivers that are not moved over to use that yet. If it were in serial_core, it could also live without the get_fs/set_fs hacks.
drivers/char/tty_io.c +78 -3
@@ -104,7 +104,6 @@#include <linux/vt_kern.h> #include <linux/selection.h> #include <linux/devfs_fs_kernel.h> -#include <linux/kmod.h> #undef TTY_DEBUG_HANGUP
@@ -153,7 +152,7 @@static int tty_release (struct inode *,struct file *);int tty_ioctl (struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg); -long tty_compat_ioctl (struct file * file,unsigned int cmd,unsigned long arg); +static long tty_compat_ioctl (struct file * file,unsigned int cmd,unsigned long arg);static int tty_fasync (int fd,struct file * filp,int on);static void release_mem (struct tty_struct *tty,int idx);
@@ -2437,7 +2436,75 @@#ifdef CONFIG_COMPAT -long tty_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +#include <linux/serial.h> + +struct serial_struct32 { +compat_int_t type; +compat_int_t line; +compat_uint_t port; +compat_int_t irq; +compat_int_t flags; +compat_int_t xmit_fifo_size; +compat_int_t custom_divisor; +compat_int_t baud_base; +unsigned short close_delay; +char io_type; +char reserved_char[1 ]; +compat_int_t hub6; +unsigned short closing_wait;/* time to wait before closing */ +unsigned short closing_wait2;/* no longer used... */ +compat_uint_t iomem_base; +unsigned short iomem_reg_shift; +unsigned int port_high; +/* compat_ulong_t iomap_base FIXME */ +compat_int_t reserved[1 ]; +}; + +static int serial_struct_ioctl (struct inode *inode,struct file *file, +unsigned cmd,unsigned long arg) +{ +typedef struct serial_struct SS ; +typedef struct serial_struct32 SS32 ; +struct serial_struct32 __user *ss32 =compat_ptr (arg); +int err; +struct serial_struct ss; +mm_segment_t oldseg =get_fs (); +__u32 udata; + +if (cmd ==TIOCSSERIAL ) { +if (!access_ok (VERIFY_READ , ss32,sizeof (SS32 ))) +return -EFAULT ; +if (__copy_from_user + (&ss, ss32, offsetof(SS32 , iomem_base))) +return -EFAULT ; +__get_user (udata, &ss32->iomem_base); + ss.iomem_base =compat_ptr (udata); +__get_user (ss.iomem_reg_shift, &ss32->iomem_reg_shift); +__get_user (ss.port_high, &ss32->port_high); + ss.iomap_base =0UL ; + } +set_fs (KERNEL_DS ); +lock_kernel (); + err =tty_ioctl (inode, file, cmd, (unsigned long ) (&ss)); +unlock_kernel (); +set_fs (oldseg); +if (cmd ==TIOCGSERIAL && err >=0 ) { +if (!access_ok (VERIFY_WRITE , ss32,sizeof (SS32 ))) +return -EFAULT ; +if (__copy_to_user (ss32, &ss, offsetof(SS32 , iomem_base))) +return -EFAULT ; +__put_user ((unsigned long ) ss.iomem_base >>32 ? +0xffffffff : (unsigned ) (unsigned long ) ss. + iomem_base, &ss32->iomem_base); +__put_user (ss.iomem_reg_shift, &ss32->iomem_reg_shift); +__put_user (ss.port_high, &ss32->port_high); + + } +return err; +} + +static long tty_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) {struct inode *inode = file->f_dentry->d_inode;struct tty_struct *tty;
@@ -2499,6 +2566,14 @@/* enter the native code path for those numbers known * to be compatible */ switch (cmd) { +case TIOCGSERIAL : +case TIOCSSERIAL : + ret =serial_struct_ioctl (inode, file, cmd, arg); +break ; +#ifdef TIOCGLTC +case TIOCGLTC : +case TIOCSLTC : +#endif case TCFLSH :case TCGETA :case TCGETS :
fs/compat_ioctl.c +0 -69
80 lines not on this page · raw message
--
Arnd Bergmann
maintainerPATCH 23/25 cdrom: move ioctl32 code to drivers/cdrom/compat.c
In reply to Arnd BergmannAll cdrom drivers use a subset of the same ioctl numbers, so the 32 bit conversion handlers can be moved to a common place.
This patch simply uses the global cdrom_compat_ioctl function as the .compat_ioctl block device operation for each of them.
Since I'm already touching pktcdvd, make that use its own ctl compat_ioctl function as well.
drivers/block/paride/pcd.c +1 -0
@@ -253,6 +253,7 @@ .open = pcd_block_open, .release = pcd_block_release, .ioctl = pcd_block_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = pcd_block_media_changed, };
drivers/block/paride/pd.c +1 -0
@@ -815,6 +815,7 @@ .open = pd_open, .release = pd_release, .ioctl = pd_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = pd_check_media, .revalidate_disk= pd_revalidate };
drivers/block/pktcdvd.c +17 -3
@@ -47,6 +47,7 @@#include <linux/pktcdvd.h> #include <linux/config.h> +#include <linux/compat.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h>
@@ -2465,6 +2466,7 @@ .open = pkt_open, .release = pkt_close, .ioctl = pkt_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = pkt_media_changed, };
@@ -2595,7 +2597,7 @@ ctrl_cmd->num_devices =MAX_WRITERS ; } -static int pkt_ctl_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) +static int pkt_ctl_locked_ioctl (struct file *file,unsigned int cmd,unsigned long arg) {void __user *argp = (void __user *)arg;struct pkt_ctrl_command ctrl_cmd;
@@ -2636,10 +2638,22 @@return ret; } +static long pkt_ctl_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +int ret; + +lock_kernel (); + arg = (unsigned long )compat_ptr (arg); + ret =pkt_ctl_locked_ioctl (file, cmd, arg); +unlock_kernel (); + +return ret; +}static struct file_operations pkt_ctl_fops = { - .ioctl = pkt_ctl_ioctl, - .owner =THIS_MODULE , + .unlocked_ioctl = pkt_ctl_ioctl, + .compat_ioctl = pkt_ctl_ioctl, + .owner =THIS_MODULE , };static struct miscdevice pkt_misc = {
drivers/cdrom/Makefile +2 -0
@@ -21,3 +21,5 @@ obj-$(CONFIG_SJCD) += sjcd.o obj-$(CONFIG_CDU535) += sonycd535.o obj-$(CONFIG_VIOCD) += viocd.o cdrom.o + +obj-y += compat.o
drivers/cdrom/aztcd.c +1 -0
@@ -339,6 +339,7 @@ .open = aztcd_open, .release = aztcd_release, .ioctl = aztcd_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = check_aztcd_media_change, };
drivers/cdrom/cdu31a.c +1 -0
@@ -2953,6 +2953,7 @@ .open = scd_block_open, .release = scd_block_release, .ioctl = scd_block_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = scd_block_media_changed, };
drivers/cdrom/cm206.c +1 -0
@@ -1364,6 +1364,7 @@ .open = cm206_block_open, .release = cm206_block_release, .ioctl = cm206_block_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = cm206_block_media_changed, };
drivers/cdrom/compat.c new file +163 -0
163 lines not on this page · raw message
drivers/cdrom/gscd.c +1 -0
@@ -155,6 +155,7 @@ .open = gscd_open, .release = gscd_release, .ioctl = gscd_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = check_gscd_med_chg, };
drivers/cdrom/mcdx.c +1 -0
@@ -243,6 +243,7 @@ .open = mcdx_block_open, .release = mcdx_block_release, .ioctl = mcdx_block_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = mcdx_block_media_changed, };
drivers/cdrom/optcd.c +1 -0
@@ -1993,6 +1993,7 @@ .open = opt_open, .release = opt_release, .ioctl = opt_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = opt_media_change, };
drivers/cdrom/sbpcd.c +1 -0
@@ -5385,6 +5385,7 @@ .open = sbpcd_block_open, .release = sbpcd_block_release, .ioctl = sbpcd_block_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = sbpcd_block_media_changed, };/*==========================================================================*/
drivers/cdrom/sjcd.c +1 -0
@@ -1646,6 +1646,7 @@ .open = sjcd_open, .release = sjcd_release, .ioctl = sjcd_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = sjcd_disk_change, };
drivers/cdrom/sonycd535.c +2 -0
@@ -1,4 +1,5 @@/* +.compat_ioctl = cdrom_compat_ioctl, * Sony CDU-535 interface device driver * * This is a modified version of the CDU-31A device driver (see below).
@@ -1433,6 +1434,7 @@ .open = cdu_open, .release = cdu_release, .ioctl = cdu_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = cdu535_check_media_change, };
drivers/ide/ide-cd.c +1 -0
@@ -3421,6 +3421,7 @@ .open = idecd_open, .release = idecd_release, .ioctl = idecd_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = idecd_media_changed, .revalidate_disk= idecd_revalidate_disk };
drivers/ide/ide-floppy.c +1 -0
@@ -2122,6 +2122,7 @@ .open = idefloppy_open, .release = idefloppy_release, .ioctl = idefloppy_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = idefloppy_media_changed, .revalidate_disk= idefloppy_revalidate_disk };
drivers/scsi/sr.c +1 -0
@@ -510,6 +510,7 @@ .open = sr_block_open, .release = sr_block_release, .ioctl = sr_block_ioctl, + .compat_ioctl = cdrom_compat_ioctl, .media_changed = sr_block_media_changed,/* * No compat_ioctl for now because sr_block_ioctl never
fs/compat_ioctl.c +0 -105
116 lines not on this page · raw message
include/linux/cdrom.h +2 -0
@@ -991,6 +991,8 @@extern int cdrom_release (struct cdrom_device_info *cdi,struct file *fp);extern int cdrom_ioctl (struct file *file,struct cdrom_device_info *cdi,struct inode *ip,unsigned int cmd,unsigned long arg); +extern long cdrom_compat_ioctl (struct file *file,unsigned int cmd, +unsigned long arg);extern int cdrom_media_changed (struct cdrom_device_info *);extern int register_cdrom (struct cdrom_device_info *cdi);
include/linux/compat_ioctl.h +0 -46
52 lines not on this page · raw message
--
Arnd Bergmann
maintainerPATCH 24/25 tape: move mtio ioctl32 code to driver/char/compat_mtio.c
In reply to Arnd BergmannThere are currently seven drivers in linux that implement MTIO ioctl methods. This patch introduces a new file doing the conversion for compat_ioctl for all of them.
They then can all use the new compat_mtio_ioctl function as their compat_ioctl handler.
fs/compat_ioctl.c +0 -72
@@ -158,76 +158,6 @@ } -struct mtget32 { -compat_long_t mt_type; -compat_long_t mt_resid; -compat_long_t mt_dsreg; -compat_long_t mt_gstat; -compat_long_t mt_erreg; -compat_daddr_t mt_fileno; -compat_daddr_t mt_blkno; -}; -#define MTIOCGET32 _IOR('m', 2, struct mtget32) - -struct mtpos32 { -compat_long_t mt_blkno; -}; -#define MTIOCPOS32 _IOR('m', 3, struct mtpos32) - -static int mt_ioctl_trans (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -struct mtget get; -struct mtget32 __user *umget32; -struct mtpos pos; -struct mtpos32 __user *upos32; -unsigned long kcmd; -void *karg; -int err =0 ; - -switch (cmd) { -case MTIOCPOS32 : - kcmd =MTIOCPOS ; - karg = &pos; -break ; -case MTIOCGET32 : - kcmd =MTIOCGET ; - karg = &get; -break ; -default : -do { -static int count; -if (++count <=20 ) -printk ("mt_ioctl: Unknown cmd fd(%d) " -"cmd(%08x) arg(%08x)\n" , - (int )fd, (unsigned int )cmd, (unsigned int )arg); - }while (0 ); -return -EINVAL ; - } -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, kcmd, (unsigned long )karg); -set_fs (old_fs); -if (err) -return err; -switch (cmd) { -case MTIOCPOS32 : - upos32 =compat_ptr (arg); - err =__put_user (pos.mt_blkno, &upos32->mt_blkno); -break ; -case MTIOCGET32 : - umget32 =compat_ptr (arg); - err =__put_user (get.mt_type, &umget32->mt_type); - err |=__put_user (get.mt_resid, &umget32->mt_resid); - err |=__put_user (get.mt_dsreg, &umget32->mt_dsreg); - err |=__put_user (get.mt_gstat, &umget32->mt_gstat); - err |=__put_user (get.mt_erreg, &umget32->mt_erreg); - err |=__put_user (get.mt_fileno, &umget32->mt_fileno); - err |=__put_user (get.mt_blkno, &umget32->mt_blkno); -break ; - } -return err ? -EFAULT :0 ; -} - static __attribute_used__ intret_einval (unsigned int fd,unsigned int cmd,unsigned long arg) {
@@ -257,7 +187,5 @@#endif #ifdef DECLARES -HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) -HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)#undef DECLARES#endif
drivers/block/paride/pt.c +1 -0
@@ -238,6 +238,7 @@ .read = pt_read, .write = pt_write, .ioctl = pt_ioctl, + .compat_ioctl = compat_mtio_ioctl, .open = pt_open, .release = pt_release, };
drivers/char/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o +obj-$(CONFIG_COMPAT) += compat_mtio.o obj-$(CONFIG_LEGACY_PTYS) += pty.o obj-$(CONFIG_UNIX98_PTYS) += pty.o obj-y += misc.o
drivers/char/compat_mtio.c new file +81 -0
81 lines not on this page · raw message
drivers/char/ftape/zftape/zftape-init.c +1 -0
@@ -94,6 +94,7 @@ .read = zft_read, .write = zft_write, .ioctl = zft_ioctl, + .compat_ioctl = compat_mtio_ioctl, .mmap = zft_mmap, .open = zft_open, .release = zft_close,
drivers/char/viotape.c +1 -0
@@ -881,6 +881,7 @@ read: viotap_read, write: viotap_write, ioctl: viotap_ioctl, + .compat_ioctl = compat_mtio_ioctl, open: viotap_open, release: viotap_release, };
drivers/ide/ide-tape.c +1 -0
@@ -4773,6 +4773,7 @@ .read = idetape_chrdev_read, .write = idetape_chrdev_write, .ioctl = idetape_chrdev_ioctl, + .compat_ioctl = compat_mtio_ioctl, .open = idetape_chrdev_open, .release = idetape_chrdev_release, };
drivers/s390/char/tape_char.c +1 -0
@@ -44,6 +44,7 @@ .read = tapechar_read, .write = tapechar_write, .ioctl = tapechar_ioctl, + .compat_ioctl = compat_mtio_ioctl, .open = tapechar_open, .release = tapechar_release, };
drivers/scsi/osst.c +2 -0
@@ -5135,6 +5135,8 @@ ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); } +if (ret == -ENOIOCTLCMD ) + ret =compat_mtio_ioctl (file, cmd_in, arg);return ret; }#endif
drivers/scsi/st.c +2 -0
@@ -3566,6 +3566,8 @@ ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg); } +if (ret == -ENOIOCTLCMD ) + ret =compat_mtio_ioctl (file, cmd, arg);return ret; }#endif
include/linux/mtio.h +12 -0
@@ -348,4 +348,16 @@/* The offset for the arguments for the special HP changer load command. */ #define MT_ST_HPLOADER_OFFSET 10000 +/* ioctl command conversion for 32 bit emulation */ +#ifdef __KERNEL__ +#include <linux/config.h> +#ifdef CONFIG_COMPAT +struct file ; +extern long compat_mtio_ioctl (struct file *file,unsigned int cmd, +unsigned long arg); +#else +#define compat_mtio_ioctl NULL +#endif +#endif +#endif /* _LINUX_MTIO_H */
include/linux/compat_ioctl.h +0 -2
@@ -108,8 +108,6 @@ COMPATIBLE_IOCTL(RTC_SET_TIME) COMPATIBLE_IOCTL(RTC_WKALM_SET) COMPATIBLE_IOCTL(RTC_WKALM_RD) -/* Little m */ -COMPATIBLE_IOCTL(MTIOCTOP) /* SG stuff */ COMPATIBLE_IOCTL(SG_SET_TIMEOUT) COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
--
Arnd Bergmann
maintainerPATCH 25/25 bluetooth: integrate ioctl32 handling
In reply to Arnd BergmannAll bluetooth ioctl numbers are compatible for 32 bit, but some of them are not defined under include/linux, so we needed some hacks to make it work with compat_ioctl.
This patch moves the compat_ioctl code into the respective bluetooth device drivers for simplification.
drivers/bluetooth/hci_ldisc.c +22 -0
@@ -507,6 +507,25 @@return err; } +#ifdef CONFIG_COMPAT +static long hci_uart_tty_compat_ioctl (struct tty_struct *tty, +struct file *file,unsigned int cmd,unsigned long arg) +{ +int ret; +switch (cmd) { +case HCIUARTSETPROTO : +case HCIUARTGETPROTO : +lock_kernel (); + ret =hci_uart_tty_ioctl (tty, file, cmd, arg); +unlock_kernel (); +break ; +default : + ret = -ENOIOCTLCMD ; + } +return ret; +} +#endif +/* * We don't provide read/write/poll interface for user space. */
@@ -545,6 +564,9 @@ hci_uart_ldisc.read = hci_uart_tty_read; hci_uart_ldisc.write = hci_uart_tty_write; hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; +#ifdef CONFIG_COMPAT + hci_uart_ldisc.compat_ioctl = hci_uart_tty_compat_ioctl; +#endif hci_uart_ldisc.poll = hci_uart_tty_poll; hci_uart_ldisc.receive_room = hci_uart_tty_room; hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
fs/compat_ioctl.c +0 -19
@@ -164,25 +164,6 @@ return -EINVAL; } -/* Bluetooth ioctls */ -#define HCIUARTSETPROTO _IOW('U', 200, int) -#define HCIUARTGETPROTO _IOR('U', 201, int) - -#define BNEPCONNADD _IOW('B', 200, int) -#define BNEPCONNDEL _IOW('B', 201, int) -#define BNEPGETCONNLIST _IOR('B', 210, int) -#define BNEPGETCONNINFO _IOR('B', 211, int) - -#define CMTPCONNADD _IOW('C', 200, int) -#define CMTPCONNDEL _IOW('C', 201, int) -#define CMTPGETCONNLIST _IOR('C', 210, int) -#define CMTPGETCONNINFO _IOR('C', 211, int) - -#define HIDPCONNADD _IOW('H', 200, int) -#define HIDPCONNDEL _IOW('H', 201, int) -#define HIDPGETCONNLIST _IOR('H', 210, int) -#define HIDPGETCONNINFO _IOR('H', 211, int) -#undef CODE#endif
include/linux/compat_ioctl.h +0 -36
@@ -350,43 +350,7 @@ COMPATIBLE_IOCTL(RNDZAPENTCNT) COMPATIBLE_IOCTL(RNDCLEARPOOL) /* Bluetooth */ -COMPATIBLE_IOCTL(HCIDEVUP) -COMPATIBLE_IOCTL(HCIDEVDOWN) -COMPATIBLE_IOCTL(HCIDEVRESET) -COMPATIBLE_IOCTL(HCIDEVRESTAT) -COMPATIBLE_IOCTL(HCIGETDEVLIST) -COMPATIBLE_IOCTL(HCIGETDEVINFO) -COMPATIBLE_IOCTL(HCIGETCONNLIST) -COMPATIBLE_IOCTL(HCIGETCONNINFO) -COMPATIBLE_IOCTL(HCISETRAW) -COMPATIBLE_IOCTL(HCISETSCAN) -COMPATIBLE_IOCTL(HCISETAUTH) -COMPATIBLE_IOCTL(HCISETENCRYPT) -COMPATIBLE_IOCTL(HCISETPTYPE) -COMPATIBLE_IOCTL(HCISETLINKPOL) -COMPATIBLE_IOCTL(HCISETLINKMODE) -COMPATIBLE_IOCTL(HCISETACLMTU) -COMPATIBLE_IOCTL(HCISETSCOMTU) -COMPATIBLE_IOCTL(HCIINQUIRY) -COMPATIBLE_IOCTL(HCIUARTSETPROTO) -COMPATIBLE_IOCTL(HCIUARTGETPROTO) -COMPATIBLE_IOCTL(RFCOMMCREATEDEV) -COMPATIBLE_IOCTL(RFCOMMRELEASEDEV) -COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) -COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) COMPATIBLE_IOCTL(RFCOMMSTEALDLC) -COMPATIBLE_IOCTL(BNEPCONNADD) -COMPATIBLE_IOCTL(BNEPCONNDEL) -COMPATIBLE_IOCTL(BNEPGETCONNLIST) -COMPATIBLE_IOCTL(BNEPGETCONNINFO) -COMPATIBLE_IOCTL(CMTPCONNADD) -COMPATIBLE_IOCTL(CMTPCONNDEL) -COMPATIBLE_IOCTL(CMTPGETCONNLIST) -COMPATIBLE_IOCTL(CMTPGETCONNINFO) -COMPATIBLE_IOCTL(HIDPCONNADD) -COMPATIBLE_IOCTL(HIDPCONNDEL) -COMPATIBLE_IOCTL(HIDPGETCONNLIST) -COMPATIBLE_IOCTL(HIDPGETCONNINFO) /* CAPI */ COMPATIBLE_IOCTL(CAPI_REGISTER) COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
net/bluetooth/bnep/sock.c +1 -0
@@ -151,6 +151,7 @@ .owner = THIS_MODULE, .release = bnep_sock_release, .ioctl = bnep_sock_ioctl, + .compat_ioctl = bnep_sock_ioctl, .bind = sock_no_bind, .getname = sock_no_getname, .sendmsg = sock_no_sendmsg,
net/bluetooth/cmtp/sock.c +1 -0
@@ -142,6 +142,7 @@ .owner = THIS_MODULE, .release = cmtp_sock_release, .ioctl = cmtp_sock_ioctl, + .compat_ioctl = cmtp_sock_ioctl, .bind = sock_no_bind, .getname = sock_no_getname, .sendmsg = sock_no_sendmsg,
net/bluetooth/hci_sock.c +1 -0
@@ -584,6 +584,7 @@ .sendmsg = hci_sock_sendmsg, .recvmsg = hci_sock_recvmsg, .ioctl = hci_sock_ioctl, + .compat_ioctl = hci_sock_ioctl, .poll = datagram_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/bluetooth/hidp/sock.c +1 -0
@@ -148,6 +148,7 @@ .owner = THIS_MODULE, .release = hidp_sock_release, .ioctl = hidp_sock_ioctl, + .compat_ioctl = hidp_sock_ioctl, .bind = sock_no_bind, .getname = sock_no_getname, .sendmsg = sock_no_sendmsg,
net/bluetooth/rfcomm/sock.c +1 -0
@@ -986,6 +986,7 @@ .setsockopt = rfcomm_sock_setsockopt, .getsockopt = rfcomm_sock_getsockopt, .ioctl = rfcomm_sock_ioctl, + .compat_ioctl = rfcomm_sock_ioctl, .poll = bt_sock_poll, .socketpair = sock_no_socketpair, .mmap = sock_no_mmap
--