ioctl,unlocked_ioctl 處理方法
在kernel 2.6.36 中已經完全刪除了struct file_operations 中的ioctl 函數指針,取而代之的是unlocked_ioctl 。
compat_ioctl少了inode參數, 可以通過filp->f_dentry->d_inode方法獲得。
https://blog.csdn.net/zhangqingsup/article/details/5721924
區別:
ioctl 和 unlock_ioctl
ioctl 不會lock_kernel()
compat_ioctl被使用在用戶空間為32位模式,而內核運行在64位模式時。這時候,需要將64位轉成32位。
引用
https://blog.chinaunix.net/u1/38994/showart_2248151.html
對幾個ioctl執行順序的分析
關於ioctl,unlocked_ioctl和compat_ioctl執行的順序
對於ioctl操作,優先執行f_op->unlocked_ioctl,如果沒有unlocked_ioctl,那麼執行f_op->ioctl
sys_ioctl
==> vfs_ioctl
==> file_ioctl
==> do_ioctl
static long do_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;
if (!filp->f_op)
goto out;
if (filp->f_op->unlocked_ioctl) { // 優先執行f_op->unlocked_ioctl
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
if (error == -ENOIOCTLCMD)
error = -EINVAL;
goto out;
} else if (filp->f_op->ioctl) { // 如果沒有unlocked_ioctl,那麼執行f_op->ioctl
lock_kernel();
error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
filp, cmd, arg);
unlock_kernel();
}
out:
return error;
}
對於compat_sys_ioctl係統調用的使用比較麻煩一些,因為默認kernel是不將它built-in進內核的,
可以通過fs/Makefile看到如下定義obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
對於CONFIG_COMPAT的定義於cpu體係結構有關,比如下麵幾個默認cpu配置了CONFIG_COMPAT=y
arch/x86_64/defconfig
arch/sparc64/defconfig
arch/powerpc/configs/ppc64_defconfig
arch/s390/defconfig
arch/parisc/configs/a500_defconfig
arch/mips/configs/ip32_defconfig
compat_sys_ioctl
filp->f_op->compat_ioctl(filp, cmd, arg);
如果該cmd在compat_ioctl中沒有找到對應的處理,同時沒有filp->f_op方法集[luther.gliethttp]
或者filp->f_op->ioct且filp->f_op->unlocked_ioctl均沒有,那麼將嚐試調用vfs_ioctl,看看是不是一些經典的ioctl命令.
對於sound/core/control.c文件[luther.gliethttp]
#ifdef CONFIG_COMPAT
#include "control_compat.c"
#else
#define snd_ctl_ioctl_compat NULL
#endif
下麵的"controlC%i"聲卡對應的控製節點fops的compat_ioctl,當沒有定義CONFIG_COMPAT時,將被置為NULL
static const struct file_operations snd_ctl_f_ops =
{
.owner = THIS_MODULE,
.read = snd_ctl_read,
.open = snd_ctl_open,
.release = snd_ctl_release,
.poll = snd_ctl_poll,
.unlocked_ioctl = snd_ctl_ioctl,
.compat_ioctl = snd_ctl_ioctl_compat,
.fasync = snd_ctl_fasync,
};
最後更新:2017-04-03 12:55:42