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