无法在Linux内核4.2.3版上从内核模块打开/读取文本文件 [英] unable to open / read text file from kernel module on linux kernel version 4.2.3

查看:284
本文介绍了无法在Linux内核4.2.3版上从内核模块打开/读取文本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个内核模块,正在4.2.3内核上加载.我正在尝试在我的init_module中读取一个简单的文本文件,该文件基本上是通过读取文本文件的内容来加载一些配置数据的.相同的代码适用于早期版本的内核,但不适用于4.2.3.以下是我的代码段供参考:

I have written a kernel module which I'm loading on kernel 4.2.3 . I am trying to read a simple text file in my init_module which basically loads some configuration data by reading the contents of the text file. This same code works on previous versions of kernel but not on 4.2.3 Below is my code snippet for reference :

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内核特定问题的指针,如何在内核模块代码中解决此问题?任何指针都将非常有帮助.

In my case I am getting pFile->f_op->read function pointer as NULL. This code works fine for non text files like /proc/kallsyms which I am able to open & read. Please provide me some pointers as to is this a 4.2.3 kernel specific issue, how can i workaround this in my kernel module code ? Any pointers would be very helpful.

推荐答案

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

.read is not the only interface which can implement reading from file. Files also may use .read_iter for that.

要读取文件,请使用

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用于在内核空间中读取/写入文件,因此应使用功能kernel_readkernel_write代替.有关更多信息,请参见我的回答.

UPDATE: Since Linux kernel 4.14 for read/write files in the kernel space functions kernel_read and kernel_write should be used instead. See that my answer for more info.

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

Reading from file to kernel's buffer (before Linux kernel 4.14)

因为vfs_read期望缓冲区指向用户空间内存(__user type属性表示该缓冲区),所以传递内核内缓冲区将不起作用:这可能会导致编译器警告有关预期之间的不一致性以及vfs_read的第二个参数的实际类型,更重要的是,vfs_read将拒绝(通过返回-EFAULT)未指向用户空间的缓冲区.但是可以通过更改用户空间内存段来克服此问题:

Because vfs_read expects buffer pointed to user-space memory (__user type attribute denotes that), passing in-kernel buffer will not work: it may cause compiler warning about inconsysency between expected and actual type of second parameter to vfs_read, and, more important, vfs_read will reject (by returning -EFAULT) buffer as pointed not to user space. But one can overcome this behaviour by changing user-space memory segment:

/*
 * 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.

这篇关于无法在Linux内核4.2.3版上从内核模块打开/读取文本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆