问题
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\n", 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,
回答1:
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.
回答2:
As pointed out by @Ilya, You are hitting a generic case (FIGETBSZ
in this case).
In general, you want to compose your ioctl commands using the _IO family of macros, with a unique type, to avoid collisions.
I suggest reading ioctl-number.txt from the kernel documentation for more information, including a list of most used types
来源:https://stackoverflow.com/questions/10071296/ioctl-is-not-called-if-cmd-2