File 无法在linux内核版本4.2.3上从内核模块打开/读取文本文件

File 无法在linux内核版本4.2.3上从内核模块打开/读取文本文件,file,linux-kernel,kernel,kernel-module,File,Linux Kernel,Kernel,Kernel Module,我已经编写了一个内核模块,正在内核4.2.3上加载。我试图在我的init_模块中读取一个简单的文本文件,它基本上通过读取文本文件的内容来加载一些配置数据。这段代码适用于以前版本的内核,但不适用于4.2.3。下面是我的代码片段供参考: struct file* pFile = NULL; pFile = filp_open(fileName, mode, 0); if(pFile != NULL){ if(IS_ERR(pFile)) { printk("<1>error %p f

我已经编写了一个内核模块,正在内核4.2.3上加载。我试图在我的
init_模块
中读取一个简单的文本文件,它基本上通过读取文本文件的内容来加载一些配置数据。这段代码适用于以前版本的内核,但不适用于4.2.3。下面是我的代码片段供参考:

struct file* pFile = NULL;
pFile = filp_open(fileName, mode, 0);
if(pFile != NULL){
if(IS_ERR(pFile))
{
  printk("<1>error %p for %s**\n", pFile, fileName);
  pFile = NULL;
}
else if(pFile->f_op->read == NULL || pFile->f_op->write == NULL)
{
  filp_close(pFile, 0);
  pFile = NULL;
}
struct file*pFile=NULL;
pFile=filp_open(文件名,模式,0);
if(pFile!=NULL){
如果(是错误(pFile))
{
printk(“错误%p,用于%s**\n”,pFile,fileName);
pFile=NULL;
}
else if(pFile->f|u op->read==NULL | pFile->f|u op->write==NULL)
{
filp_关闭(pFile,0);
pFile=NULL;
}

在我的例子中,我得到
pFile->f_op->read
函数指针为
NULL
。这段代码适用于非文本文件,如
/proc/kallsyms
,我可以打开和读取。请提供一些指针,说明这是4.2.3内核特有的问题,我如何在我的内核模块代码中解决这个问题?任何指针都可以这会很有帮助。

.read
并不是唯一可以实现文件读取的接口。文件也可以使用
.read\u iter

要读取文件,请使用

ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
这考虑到了所有的可能性

类似地,用于编写文件

ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
应该使用

更新:由于Linux内核4.14用于内核空间中的读/写文件,因此应使用函数
内核读取
内核写入
。有关更多信息,请参阅


从文件读取到内核缓冲区(Linux内核4.14之前)

因为
vfs\u read
需要指向用户空间内存的缓冲区(
\uu user
type属性表示该缓冲区),传入内核缓冲区将不起作用:它可能会导致编译器发出警告,警告第二个参数的预期类型和实际类型之间不一致,从而
vfs\u read
,更重要的是,
vfs\u read
将拒绝(返回-EFAULT)缓冲区不指向用户空间。但可以通过更改用户空间内存段来克服此行为:

/*
 * Assume that `kernel_buf` points to kernel's memory and has type char*.
 */
char __user *user_buf = (__force char __user *)kernel_buf; // Make compiler happy.
mm_segment_t oldfs = get_fs(); // Store current use-space memory segment.
set_fs(KERNEL_DS); // Set user-space memory segment equal to kernel's one.

vfs_read(file, user_buf, count, pos);

set_fs(oldfs); // Restore user-space memory segment after reading.

在内核中乱放文件通常是个坏主意。为什么首先要这么做?另外,如果你希望代码进入上游,我鼓励你坚持这样做(坦率地说,我只是跳过了阅读你的代码,因为它对我来说完全不可读)是的,我知道所有这些,但是在4.2.3中是什么导致了这种行为。这是一段非常简单的代码,任何处理过内核模块的人都应该能够很容易地理解它。通过
vfs\u read
,你到底得到了什么?函数调用是否会出错?它返回了哪个错误代码?
vfs\u read
是syscall
read
解析文件对象后使用。因此,如果
vfs\u read
失败,从用户空间读取文件可能也会失败。我从vfs\u read得到错误代码EFAULT作为返回值。EFAULT意味着
buf
不是由用户分配的。您可能使用内核缓冲区,这在这里不太正确。您可以尝试se
\uuu vfs\u read
而不是
vfs\u read
:它不使用
access\u ok
检查缓冲区。但没有任何东西阻止
。读取文件的接口以执行相同的检查。我使用kmalloc(大小,GFP\u内核)在我希望读取文件内容的位置分配缓冲区。将此缓冲区作为vfs\u read调用中的第二个参数传递。非常感谢…我现在能够使用vfs\u read读取内容,但我没有正确执行get\u fs()&set\u fs(),这导致了默认错误。