问题 如果cmd = 2,则不调用ioctl


我正在开发一个使用unlocked_ioctl的内核模块。我用内核版本2.6.24-23-generic测试了它,它运行得很好。现在我尝试使用内核版本3.3.1-1-ARCH并发生一些奇怪的事情:当请求值(cmd)为2时,不会执行ioctl函数。它返回0,但函数未执行。为了检查它是否未执行,我执行了以下操作:

static long midriver_ioctl(struct file *file,
    unsigned int cmd, unsigned long arg) {

printk("Called with cmd = %d\n", cmd);

我写了一个测试程序,从0到4096调用此设备的ioctl,我可以在dmesg中看到所有这些值的消息“用cmd = n调用”,除了“2”,唯一没有显示的值。

关于我做错了什么的线索?

先谢谢你,


12024
2018-04-09 09:26


起源

链中的一些代码是拦截cmd == 2并处理它? - zvrba


答案:


看看吧 这个

 546 int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 547             unsigned long arg)
 548 {
 549        int error = 0;
 550        int __user *argp = (int __user *)arg;
 551        struct inode *inode = filp->f_path.dentry->d_inode;
 552
 553        switch (cmd) {
 554        case FIOCLEX:
 555                set_close_on_exec(fd, 1);
 556                break;
 557
 558        case FIONCLEX:
 559                set_close_on_exec(fd, 0);
 560                break;
 561
 562        case FIONBIO:
 563                error = ioctl_fionbio(filp, argp);
 564                break;
 565
 566        case FIOASYNC:
 567                error = ioctl_fioasync(fd, filp, argp);
 568                break;
 569
 570        case FIOQSIZE:
 571                if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
 572                    S_ISLNK(inode->i_mode)) {
 573                        loff_t res = inode_get_bytes(inode);
 574                        error = copy_to_user(argp, &res, sizeof(res)) ?
 575                                        -EFAULT : 0;
 576                } else
 577                        error = -ENOTTY;
 578                break;
 579
 580        case FIFREEZE:
 581                error = ioctl_fsfreeze(filp);
 582                break;
 583
 584        case FITHAW:
 585                error = ioctl_fsthaw(filp);
 586                break;
 587
 588        case FS_IOC_FIEMAP:
 589                return ioctl_fiemap(filp, arg);
 590
 591        case FIGETBSZ:
 592                return put_user(inode->i_sb->s_blocksize, argp);
 593
 594        default:
 595                if (S_ISREG(inode->i_mode))
 596                        error = file_ioctl(filp, cmd, arg);
 597                else
 598                        error = vfs_ioctl(filp, cmd, arg);
 599                break;
 600        }
 601        return error;
 602 

如您所见,之前有一些交换机案例 vfs_ioctl 要么 file_ioctl 呼叫。


9
2018-04-09 09:32



我没有看到相关性,这些情况都不适用 - Hasturkun
我的立场得到了纠正,价值 FIGETBSZ 实际上是2,+ 1 - Hasturkun


正如@Ilya指出的那样,你正在打一个通用案例(FIGETBSZ 在这种情况下)。

通常,您希望使用。撰写ioctl命令 _IO 宏的家庭,具有独特的类型,以避免碰撞。

我建议读书 IOCTL-number.txt 从内核文档中获取更多信息,包括最常用类型的列表


3
2018-04-09 09:45



这是一个最小的 ioctl 使用示例 _IOx: stackoverflow.com/a/44613896/895245 - Ciro Santilli 新疆改造中心 六四事件 法轮功