Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
546 views
in Technique[技术] by (71.8m points)

c - ioctl is not called if cmd = 2

I am developing a kernel module that uses unlocked_ioctl. I tested it with kernel version 2.6.24-23-generic and it works perfectly. Now I tried it with kernel version 3.3.1-1-ARCH and something weird happens: the ioctl function is not executed when the request value (cmd) is 2. It returns 0, but the function is not executed. In order to check that it is not executed I did the following:

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

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

I wrote a test program that calls ioctl for this device from 0 to 4096, and I can see in dmesg the message "Called with cmd = n" for all those values, except of "2", the only one that is not shown.

Any clues about what I am doing wrong?

Thank you in advance,

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Take a look on this:

 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 

As you can see, there is some of the switch-cases before vfs_ioctl or file_ioctl call.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...