4

我正在尝试在我的玩具文件系统模块中调用 ioctl 函数。我只是想让这个 ioctl 设置一个由调用者传入的变量。到目前为止,我已经建立了允许我进行 ioctl 调用的 ioctl 基础设施。我的模块中有这个函数来处理 ioctl。

int ospfs_ioctl(struct inode *inode, struct file *filp,
      unsigned int cmd, unsigned long arg)
{
    if(cmd == OSPFSIOCRASH)
    {
        eprintk("crash: %ld\n", arg);
        return 0;
    }
    else
        return -ENOTTY;
}

我的测试功能看起来像这样。

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define OSPFSIOCRASH 42

int main()
{
    int fd = open("/tmp/cs111/lab3-thief/test/hello.txt", O_RDWR);
    printf("ioctl call: %d\n", ioctl(fd, OSPFSIOCRASH, 100));
    close(fd);
}

我希望输出是

crash: 100
ioctl call: 0

但输出实际上是

crash: 0
ioctl call: 0

我敢打赌我做错了一些简单的事情。有人可以帮忙并指出问题所在吗?非常感谢你。

4

2 回答 2

0

这可能不是解决您问题的解决方案,但根据您的问题和评论中的有限信息,这是我可以收集的。

根据问题和评论,您似乎已经struct file_operations以这种方式定义了一个结构:

struct file_operations fops = { .ioctl=ospfs_ioctl };

你的签名ospfs_ioctl表明你正在使用旧的ioctl。

对于最近的内核(至少在 2.6.35+ 或其他版本之后),建议使用.unlocked_ioctl而不是.ioctl.

struct file_operations fops = { .unlocked_ioctl=ospfs_ioctl };

并且ospfs_ioctl函数的定义将更改为:

long ospfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

和常规 ioctl之间的区别unlocked_ioctl可以在这里找到。简而言之,BKL在调用 ioctl 之前不需要担心。

而且根据Chris Dodd的建议,你应该仔细检查你是如何定义你的OSPFIOCRASH. 推荐的方法是使用_IO(magic, some_num_for_ioctl)

于 2013-03-08T21:23:35.727 回答
0

根据 Chris Dodd 的建议,我更改#define OSPFIOCRASH 42#define OSPFSIOCRASH _IO(magic, 0)并获得了所需的行为。

于 2013-03-08T21:39:40.557 回答