在Linux内核模块中读取/写入文件 [英] Read/write files within a Linux kernel module
问题描述
我知道所有有关为什么不应该从内核读取/写入文件,而是如何使用/proc 或 netlink 进行此操作的讨论.我还是想读/写.我也看过 驱动我的坚果-内核中不应该做的事情.
I know all the discussions about why one should not read/write files from kernel, instead how to use /proc or netlink to do that. I want to read/write anyway. I have also read Driving Me Nuts - Things You Never Should Do in the Kernel.
但是,问题是2.6.30无法导出sys_read()
.而是将其包装在SYSCALL_DEFINE3
中.因此,如果我在模块中使用它,则会收到以下警告:
However, the problem is that 2.6.30 does not export sys_read()
. Rather it's wrapped in SYSCALL_DEFINE3
. So if I use it in my module, I get the following warnings:
WARNING: "sys_read" [xxx.ko] undefined!
WARNING: "sys_open" [xxx.ko] undefined!
很显然,insmod
无法加载模块,因为链接未正确进行.
Obviously insmod
cannot load the module because linking does not happen correctly.
问题:
- 如何在2.6.22之后(不导出
sys_read()
/sys_open()
的情况下)在内核中进行读取/写入? - 通常,如何从内核内部使用包裹在宏
SYSCALL_DEFINEn()
中的系统调用?
- How to read/write within kernel after 2.6.22 (where
sys_read()
/sys_open()
are not exported)? - In general, how to use system calls wrapped in macro
SYSCALL_DEFINEn()
from within the kernel?
推荐答案
您应注意,应尽可能避免文件I/O.主要思想是更深一层"并调用 VFS级别函数,而不是syscall处理程序直接:
You should be aware that that you should avoid file I/O when possible. The main idea is to go "one level deeper" and call VFS level functions instead of the syscall handler directly:
包括:
#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>
打开文件(类似于打开):
Opening a file (similar to open):
struct file *file_open(const char *path, int flags, int rights)
{
struct file *filp = NULL;
mm_segment_t oldfs;
int err = 0;
oldfs = get_fs();
set_fs(get_ds());
filp = filp_open(path, flags, rights);
set_fs(oldfs);
if (IS_ERR(filp)) {
err = PTR_ERR(filp);
return NULL;
}
return filp;
}
关闭文件(类似于关闭):
Close a file (similar to close):
void file_close(struct file *file)
{
filp_close(file, NULL);
}
从文件中读取数据(类似于pread):
Reading data from a file (similar to pread):
int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
{
mm_segment_t oldfs;
int ret;
oldfs = get_fs();
set_fs(get_ds());
ret = vfs_read(file, data, size, &offset);
set_fs(oldfs);
return ret;
}
将数据写入文件(类似于pwrite):
Writing data to a file (similar to pwrite):
int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
{
mm_segment_t oldfs;
int ret;
oldfs = get_fs();
set_fs(get_ds());
ret = vfs_write(file, data, size, &offset);
set_fs(oldfs);
return ret;
}
同步会更改文件(类似于fsync):
Syncing changes a file (similar to fsync):
int file_sync(struct file *file)
{
vfs_fsync(file, 0);
return 0;
}
最初,我建议使用file_fsync,在较新的内核版本中已不再使用.感谢那个可怜的家伙提出的改变,但是拒绝了他的改变.该修改被拒绝,然后我才能对其进行审核.
Originally, I proposed using file_fsync, which is gone in newer kernel versions. Thanks to the poor guy suggesting the change, but whose change was rejected. The edit was rejected before I could review it.
这篇关于在Linux内核模块中读取/写入文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!