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

问题描述 投票:3回答:1

我已经编写了一个内核模块,正在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内核特定问题的指针,我该如何在内核模块代码中解决此问题?任何指针都将非常有帮助。

file linux-kernel kernel kernel-module
1个回答
1
投票

.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)

应使用。

UPDATE:由于Linux内核4.14用于在内核空间中读取/写入文件,因此应该使用功能kernel_readkernel_write。有关更多信息,请参见that my answer


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

因为vfs_read期望缓冲区指向用户空间内存__user type属性表示),所以传递内核内缓冲区将不起作用:这可能会导致编译器警告有关预期和实际类型之间的不一致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.
© www.soinside.com 2019 - 2024. All rights reserved.