• ioctl,unlocked_ioctl 处理方法 分类: arm-linux-Ubuntu 2014-03-20 09:32 503人阅读 评论(0) 收藏


    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

    http://blog.csdn.net/zhangqingsup/article/details/5721924

     

    区别:

    ioctl 和 unlock_ioctl

    ioctl 不会lock_kernel()

     

    compat_ioctl被使用在用户空间为32位模式,而内核运行在64位模式时。这时候,需要将64位转成32位。

     

    引用

    http://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,
    };

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    更改discuz!3.4注册后用户所在用户组
    APACHE服务器500错误解决方法
    有关redis笔记
    真正免费!!!爱客追剧神器【珍藏】
    discuz 论坛如何设置一个邀请码重复使用不过期,真正管理员专用
    discuz3.4设置会员免回复查看隐藏帖
    BigDecimal的用法详解(保留两位小数,四舍五入,数字格式化,科学计数法转数字,数字里的逗号处理)
    tinyproxy轻量代理服务器安装
    人物-企业家-实业家、发明家:松下幸之助
    图书-励志:《你的梦想一定能实现》
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706639.html
Copyright © 2020-2023  润新知