The new way of ioctl()---ioctl新方法

2.6.35版本移除了ioctl()

http://lwn.net/Articles/119652/

                                             The new way of ioctl()

The ioctl() system call has long been out of favor among the kernel developers, who see it as a completely uncontrolled entry point into the kernel.  Given the vast number of applications which expectioctl() to be present, however, it will not go away anytime soon.  So it is worth the trouble to ensure thatioctl()calls are performed quickly and correctly - and that they do not unnecessarily impact the rest of the system.

ioctl() is one of the remaining parts of the kernel which runs under the Big Kernel Lock (BKL).  In the past, the usage of the BKL has made it possible for long-runningioctl() methods to create long latencies for unrelated processes.  Recent changes, which have made BKL-covered code preemptible, have mitigated that problem somewhat.  Even so, the desire to eventually get rid of the BKL altogether suggests thatioctl() should move out from under its protection.

Simply removing the lock_kernel() call before callingioctl() methods is not an option, however.  Each one of those methods must first be audited to see what other locking may be necessary for it to run safely outside of the BKL.  That is a huge job, one which would be hard to do in a single "flag day" operation.  So a migration path must be provided.  As of 2.6.11, that path will exist.

The patch(by Michael s. Tsirkin) adds a new member to thefile_operations structure:

    long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, 
                            unsigned long arg);

If a driver or filesystem provides an unlocked_ioctl() method, it will be called in preference to the olderioctl().  The differences are that the inode argument is not provided (it's available asfilp->f_dentry->d_inode) and the BKL is not taken prior to the call.  All new code should be written with its own locking, and should useunlocked_ioctl().  Old code should be converted as time allows.  For code which must run on multiple kernels, there is a newHAVE_UNLOCKED_IOCTL macro which can be tested to see if the newer method is available or not.

Michael's patch adds one other operation:

    long (*compat_ioctl) (struct file *filp, unsigned int cmd, 
                          unsigned long arg);

If this method exists, it will be called (without the BKL) whenever a 32-bit process callsioctl() on a 64-bit system.  It should then do whatever is required to convert the argument to native data types and carry out the request.  Ifcompat_ioctl() is not provided, the older conversion mechanism will be used, as before.  TheHAVE_COMPAT_IOCTLmacro can be tested to see if this mechanism is available on any given kernel.

The compat_ioctl() method will probably filter down into a few subsystems.  Andi Kleen has posted patches adding newcompat_ioctl() methods to theblock_device_operations andscsi_host_template structures, for example, though those patches have not been merged as of this writing.


           ( Log in to post comments)          

more on compat_ioctl

Posted Oct 23, 2005 14:19 UTC (Sun) byarnd (subscriber, #8866)       [Link]   

    There are a few noteworthy points about compat_ioctl:    
  • If you are writing a new device driver that needs ioctl methods (which     some might argue you should not do in the first place), make sure the data     structure are compatible between 32 and 64 bit, so unlocked_ioctl and     compat_ioctl can point to the same function. In particular, data     structures containing must not contain fields that have different sizes     (e.g. 'void *' or 'long') or need padding (e.g. 'long long' after 'int')      on 64 bit systems.   
  • As of 2.6.14, nobody has started converting the network layer to    compat_ioctl, so the next person that needs new compatibility code for    socket ioctls should add the infrastructure for that instead of adding on    to fs/compat_ioctl.c.  
  • While the fs/compat_ioctl.c infrastructure still exists, it is valid   for compat_ioctl methods to return -ENOIOCTLCMD for anything they don't   know. This is particularly useful for block or tty devices that have a lot   of ioctl numbers common to all drivers.  The vfs layer first calls ->compat_ioctl and if that does not exist or  returns -ENOIOCTLCMD, it scans the list of known conversions between 32  and 64 bit ioctls and if it finds a valid conversion, it enters the native  64 bit ->unlocked_ioctl/->ioctl path.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值