c - 内核模块检查文件是否存在
问题描述
我正在对内核模块nandsim进行一些扩展,并且在打开文件之前找不到正确的方法来测试文件是否存在。我已经阅读了这个问题,它涵盖了基本的打开/读/写操作是如何进行的,但是我无法确定正常的 open(2) 标志是否以及如何应用在这里。
我很清楚在内核模块中读写文件是不好的做法;这段代码已经存在于内核中并且已经在读写文件了。我只是想对已经存在的内容进行一些调整。目前,当模块加载并指示使用缓存文件(调用 modprobe 时指定为字符串路径)时,它使用 filp_open() 打开文件,如果文件不存在则创建:
/* in nandsim.c */
...
module_param(cache_file, charp, 0400);
...
MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of memory");
...
struct file *cfile;
cfile = filp_open(cache_file, O_CREAT | O_RDWR | O_LARGEFILE, 0600);
你可能会问,“你真的想在这里做什么?” 我想为缓存文件包含一个标头,以便在需要重置系统时可以重用它。通过在此文件的开头包含有关 nand 页几何和页数的信息,我可以更轻松地模拟许多错误情况,否则这些情况在 nandsim 框架中是不可能的。如果我可以在文件操作期间关闭 nandsim 模块,或者修改支持文件以模拟真实世界的故障模式,我可以重新创建这些错误条件的净效应。这将允许我使用 nandsim 使模拟设备重新联机,并评估容错文件系统的工作情况。
我的想法是按如下方式对其进行修改,以便尝试强制创建已经存在的文件时会失败:
struct file *cfile;
cfile = filp_open(cache_file, O_CREAT | O_EXCL | O_RDWR | O_LARGEFILE, 0600);
if(IS_ERR(cfile)){
printk(KERN_INFO "File didn't exist: %ld", PTR_ERR(cfile));
/* Do header setup for first-time run of NAND simulation */
}
else{
/* Read header and validate against system parameters. Recover operations */
}
我看到的是一个错误,但这不是我所期望的。它报告 errno 14, EFAULT(错误地址)而不是 errno 17 EEXIST(文件存在)。我不想用这个来运行,因为我希望它尽可能地惯用和正确。
还有其他方法我应该这样做吗?
我是否需要以某种方式指定文件路径在用户地址空间中?如果是这样,为什么代码中的情况不是这样?
O_RDWR
编辑:通过尝试仅使用and打开,我能够得到一个可靠的错误O_LARGEFILE
,这导致ENOENT
. 仍然不清楚为什么我最初的方法是不正确的,也不清楚实现我的目标的最佳方法是什么。也就是说,如果更有经验的人可以对此发表评论,我可以将其添加为解决方案。
解决方案
实际上,filp_open需要一个位于内核地址空间中的文件路径。证明是使用getname_kernel
. 您可以通过以下方式为您的用例模仿这一点:
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_kernel
.
推荐阅读
- android - DataSource.Factory 未使用正确的变量值 Android Paging
- java - Java 8 功能接口和接口
- git - git push 挂起...可能与 ssh 配置相关
- oracle - Oracle Enterprise Manager 11g Database Control - 代理无法访问
- ios - iOS:在自定义框架中条纹 Apple Pay
- google-cloud-firestore - 在 Firestore 中,如何忽略不需要的创建输入?
- python - Python与串行设备通信
- python - statsmodels.tsa.api-0.9.0 ZeroDivisionError:除以零
- command-line - Vlang cli 示例不能以直观的方式工作
- django - Django:如何在电子商务中获取总购物车项目