如何在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()之后在内核中读/写)?
  • 一般来说,如何在内核中使用包含在macrosSYSCALL_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,这是在较新的内核版本。 感谢那个可怜的人提出这个改变,但是他的改变被拒绝了。 编辑被拒绝之前,我可以检讨它。