Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 内核模块检查文件是否存在_C_Linux Kernel_Linux Device Driver_Kernel Module - Fatal编程技术网

C 内核模块检查文件是否存在

C 内核模块检查文件是否存在,c,linux-kernel,linux-device-driver,kernel-module,C,Linux Kernel,Linux Device Driver,Kernel Module,我正在对内核模块进行一些扩展,在打开文件之前,我很难找到正确的方法来测试文件是否存在。我已经读过了,其中介绍了基本的打开/读取/写入操作是如何进行的,但是我很难弄清楚正常的打开(2)标志是否以及如何在这里应用 我很清楚,在内核模块中读写文件是不好的做法;此代码已经存在于内核中,并且已经在读取和写入文件。我只是想对已经存在的东西做一些调整。目前,当加载模块并指示其使用缓存文件(在调用modprobe时指定为字符串路径)时,它会使用filp_open()打开该文件,或者在该文件不存在时创建该文件:

我正在对内核模块进行一些扩展,在打开文件之前,我很难找到正确的方法来测试文件是否存在。我已经读过了,其中介绍了基本的打开/读取/写入操作是如何进行的,但是我很难弄清楚正常的打开(2)标志是否以及如何在这里应用

我很清楚,在内核模块中读写文件是不好的做法;此代码已经存在于内核中,并且已经在读取和写入文件。我只是想对已经存在的东西做一些调整。目前,当加载模块并指示其使用缓存文件(在调用modprobe时指定为字符串路径)时,它会使用filp_open()打开该文件,或者在该文件不存在时创建该文件:

nandsim.c中的
/**/
...
模块参数(缓存文件,charp,0400);
...
模块_PARM_DESC(缓存文件,“用于缓存nand页而不是内存的文件”);
...
结构文件*c文件;
cfile=filp_open(cache_文件,O_create | O_RDWR | O_LARGEFILE,0600);
您可能会问,“您到底想在这里做什么?”我想为缓存文件包含一个头文件,以便在需要重置系统时可以重用它。通过在这个文件的开头包含有关nand页面几何结构和页面计数的信息,我可以更容易地模拟一些错误情况,否则在nandsim框架中是不可能的。如果我可以在文件操作期间关闭nandsim模块,或修改备份文件以模拟真实故障模式,我可以重新创建这些错误条件的净影响。 这将允许我使用nandsim使模拟设备重新联机,并评估容错文件系统的工作情况

我的想法是按如下方式修改它,这样它就无法强制创建一个已经存在的文件:

struct文件*cfile;
cfile=filp|u open(缓存|u文件,O|u创建| O|u排除| O|u RDWR | O|u大文件,0600);
如果(是错误的(文件)){
printk(KERN_INFO“文件不存在:%ld”,PTR_ERR(cfile));
/*首次运行NAND模拟时执行标头设置*/
}
否则{
/*读取标头并根据系统参数进行验证。恢复操作*/
}
我看到的是一个错误,但这不是我所期望的。它报告的是errno 14,EFAULT(错误地址),而不是errno 17 EEXIST(文件存在)。我不想用它来运行,因为我希望它尽可能地地道和正确

我还有别的办法吗

我是否需要以某种方式指定文件路径在用户地址空间中?如果是的话,为什么代码中的情况并非如此

编辑:我只能用
O_RDWR
O_LARGEFILE
打开文件,从而得到了一个可靠的错误,结果是
enoint
。现在还不清楚为什么我最初的方法是错误的,也不清楚实现我的目标的最佳方式是什么。也就是说,如果有更有经验的人可以对此发表评论,我可以将其作为一种解决方案添加进来。

实际上,需要一个位于内核地址空间中的文件路径。证明是使用了
getname\u内核
。您可以在您的用例中使用以下内容来模拟:

struct filename *name = getname(cache_file);
struct file *cfile = ERR_CAST(name);

if (!IS_ERR(name)) {
        cfile = file_open_name(name, O_CREAT | O_EXCL | O_RDWR | O_LARGEFILE, 0600);
        if (IS_ERR(cfile))
                return PTR_ERR(cfile);

        putname(name);
}
请注意,
getname
需要一个用户空间地址,它相当于
getname\u kernel

实际上,需要一个位于内核地址空间的文件路径。证明是使用了
getname\u内核
。您可以在您的用例中使用以下内容来模拟:

struct filename *name = getname(cache_file);
struct file *cfile = ERR_CAST(name);

if (!IS_ERR(name)) {
        cfile = file_open_name(name, O_CREAT | O_EXCL | O_RDWR | O_LARGEFILE, 0600);
        if (IS_ERR(cfile))
                return PTR_ERR(cfile);

        putname(name);
}

请注意,
getname
需要一个用户空间地址,它相当于
getname\u kernel

OP使用的路径已经在内核空间中,它是一个模块参数()。我被OP的语句
弄糊涂了,我是否需要以某种方式指定文件路径在用户地址空间中?
,他们提到他们正在对(已经存在的)内核模块进行一些修改。你是对的,这很让人困惑,OP应该指定他们从哪里获取路径,如果它仍然是一个模块参数或不是,我已经在上面进行了评论。通过查看OP的编辑,它看起来好像只传递了一些标志,这意味着
cache\u file
应该是原始的(和内核空间)文件。因此,问题可能来自其他地方,让我们等待OP的响应。@是的,调用时模块参数当然会复制到内核空间(这就是
modprobe
所做的)。问题不在那里
file\u open\u name
返回
-EFAULT
是因为其他一些奇怪的原因…OP使用的路径已经在内核空间中,它是一个模块参数()。我被OP的语句
弄糊涂了,我是否需要以某种方式指定文件路径在用户地址空间中?
嗯,他们提到他们正在对(已经存在的)内核模块进行一些修改。你是对的,这很让人困惑,OP应该指定他们从哪里获取路径,如果它仍然是一个模块参数或不是,我已经在上面进行了评论。通过查看OP的编辑,它看起来好像只传递了一些标志,这意味着
cache\u file
应该是原始的(和内核空间)文件。因此,问题可能来自其他地方,让我们等待OP的响应。@是的,调用时模块参数当然会复制到内核空间(这就是
modprobe
所做的)。问题不在那里<代码>文件\u打开\u名称由于其他奇怪的原因返回
-EFAULT
…从哪里获取
缓存\u文件
变量?它是原始文件中的模块参数,还是您更改了它?如果是,请说明并添加相关代码。这是从模块参数获取的原始缓存文件。我已经更新了代码段,以包括它是如何填充的。您从哪里获取
cache\u文件
变量?它是像origi中那样的模块参数吗