在 Linux 内核模块中读/写文件 [英] Read/write files within a Linux kernel module

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

问题描述

我知道所有关于为什么不应该从内核读/写文件,而是如何使用 /procnetlink 来做到这一点的讨论.无论如何我都想读/写.我也读过让我发疯 - 在内核中你永远不应该做的事情.

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?

推荐答案

您应该意识到应该尽可能避免在 Linux 内核中进行文件 I/O.主要思想是更深一层"并调用 VFS 级别函数而不是系统调用处理程序直接:

You should be aware that you should avoid file I/O from within Linux kernel 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屋!

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