閱讀828 返回首頁    go 阿裏雲 go 技術社區[雲棲]


ioctl,unlocked_ioctl 處理方法

kernel 2.6.35 及之前的版本中struct file_operations 一共有3個ioctl :
ioctl,unlocked_ioctl和compat_ioctl
現在隻有unlocked_ioctl和compat_ioctl 了

在kernel 2.6.36 中已經完全刪除了struct file_operations 中的ioctl 函數指針,取而代之的是unlocked_ioctl 。

這個指針函數變了之後最大的影響是參數中少了inode ,不過這個不是問題,因為用戶程序中的ioctl對應的係統調用接口沒有變化,所以用戶程序不需要改變,一切都交給內核處理了,如果想在unlocked_ioctl中獲得inode 等信息可以用如下方法:
struct inode *inode = file->f_mapping->host;
struct block_device *bdev = inode->i_bdev;
struct gendisk *disk = bdev->bd_disk;
fmode_t mode = file->f_mode;

和int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)相比
compat_ioctl少了inode參數, 可以通過filp->f_dentry->d_inode方法獲得。
2011-08-27 16:28

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

  上一篇:go printk優先級
  下一篇:go Sql Server 常用函數