如何在Linux内核模块中读取/写入文件?
我知道为什么不应该从内核读取/写入文件的所有讨论,而是如何使用/ proc或netlink来做到这一点。 无论如何,我想读/写。 我也读过“ 驱动我的坚果 – 你永远不应该在内核中做的事情” 。
但是,问题是2.6.30不会导出sys_read()
。 而是包裹在SYSCALL_DEFINE3
。 所以如果我在模块中使用它,我会得到以下警告:
WARNING: "sys_read" [xxx.ko] undefined! WARNING: "sys_open" [xxx.ko] undefined!
显然insmod
不能加载模块,因为链接没有正确发生。
问题:
- 如何在2.6.22(其中没有导出
sys_read()
/sys_open()
之后在内核中读/写)? - 一般来说,如何在内核中使用包含在macros
SYSCALL_DEFINEn()
系统调用?
你应该知道,你应该尽可能地避免文件I / O。 主要思路是“深入一层”,直接调用VFS级别的函数,而不是直接调用syscall处理函数:
包括:
#include <linux/fs.h> #include <asm/segment.h> #include <asm/uaccess.h> #include <linux/buffer_head.h>
打开一个文件(类似于打开):
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; }
closures一个文件(类似于closures):
void file_close(struct file *file) { filp_close(file, NULL); }
从文件读取数据(类似于前导):
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):
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):
int file_sync(struct file *file) { vfs_fsync(file, 0); return 0; }
[编辑]最初,我提出使用file_fsync,这是在较新的内核版本。 感谢那个可怜的人提出这个改变,但是他的改变被拒绝了。 编辑被拒绝之前,我可以检讨它。