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

时间:2015-10-17 07:13:54

标签: file linux-kernel kernel kernel-module

我编写了一个内核模块,我正在内核4.2.3上加载。我试图在我的init_module中读取一个简单的文本文件,它基本上通过读取文本文件的内容来加载一些配置数据。这个代码适用于以前版本的内核但不适用于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;
}

在我的情况下,我得到pFile->f_op->read函数指针为NULL。此代码适用于我能够打开的非/proc/kallsyms非文本文件。读。请提供一些指示,这是一个4.2.3内核特定问题,我如何在我的内核模块代码中解决这个问题?任何指针都会非常有用。

1 个答案:

答案 0 :(得分:0)

.read不是唯一可以实现从文件读取的接口。文件也可以使用.read_iter

要读取文件,请使用

,而不是直接调用->read
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)

应该使用。

从文件读取到内核的缓冲区

因为vfs_read期望缓冲区指向用户空间内存__user类型属性表示),所以传入内核缓冲区将不起作用:它可能导致编译器警告关于vfs_read的第二个参数的预期和实际类型之间的不一致性,更重要的是,vfs_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.