Linux kernel文件操作

在linux kernel中读写文件使用的api和用户态的是不一样的,不能直接使用用户态的api。这里简单记录下使用的函数和使用方法。内核内的文件操作主要通过 file 结构体进行,配合 vfs(虚拟文件系统)的相关 API 来读写文件

1 打开文件

在内核中要操作文件,首先要打开文件。内核中使用的是 filp_open 函数。

struct file *filp_open(const char *filename, int flags, umode_t mode);
  • filename:文件路径。
  • flags:文件打开的标志(例如 O_RDONLYO_WRONLYO_RDWR 等,可以与用户态中的标志相同)。
  • mode:当创建新文件时的权限(可选)。
struct file *file;
file = filp_open("/path/to/file", O_RDONLY, 0);
if (IS_ERR(file)) {
    printk("Failed to open file\n");
    return PTR_ERR(file);
}

2 读取文件

读取文件的主要接口是 kernel_read,该函数从已打开的文件中读取数据。

ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos);
  • file:文件结构指针。
  • buf:读取数据的缓冲区。
  • count:读取的字节数。
  • pos:文件偏移量指针。
loff_t pos = 0;
char buf[128];
ssize_t ret = kernel_read(file, buf, sizeof(buf), &pos);
if (ret >= 0) {
    printk("Read %zd bytes from file\n", ret);
} else {
    printk("Failed to read from file\n");
}

3 写文件

写入文件可以使用 kernel_write 接口,该函数将数据写入到文件中。

ssize_t kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos);
  • file:文件结构指针。
  • buf:要写入的数据缓冲区。
  • count:要写入的字节数。
  • pos:文件偏移量指针。
loff_t pos = 0;
const char *data = "Hello, kernel!";
ssize_t ret = kernel_write(file, data, strlen(data), &pos);
if (ret >= 0) {
    printk("Wrote %zd bytes to file\n", ret);
} else {
    printk("Failed to write to file\n");
}

4 同步文件

为了确保文件写入磁盘,可以使用 vfs_fsync 来同步文件数据。

int vfs_fsync(struct file *file, int datasync);
  • file:文件结构指针。
  • datasync:如果为 1,只同步文件数据;如果为 0,则同步所有文件元数据和数据。

5 关闭文件

int filp_close(struct file *filp, fl_owner_t id);
filp_close(file, NULL);

6 获取和设置文件偏移

文件的读写偏移量可以通过 vfs_llseek 函数来获取和设置。

loff_t vfs_llseek(struct file *file, loff_t offset, int whence);
  • file:文件结构指针。
  • offset:偏移量。
  • whence:基准位置,如 SEEK_SETSEEK_CURSEEK_END
loff_t new_pos;
new_pos = vfs_llseek(file, 0, SEEK_END); // 移动到文件末尾

在旧版本的 Linux 内核中,内核与用户态之间的内存空间隔离机制要求在进行文件读写时使用 get_fs()set_fs() 函数来切换内存访问权限。这些函数将内核代码的内存访问限制临时解除,允许访问用户态内存地址。

但是,在现代的 Linux 内核(从 5.10 版本起),已经废除了这种方式,内核提供的 kernel_readkernel_write 等接口不再需要 get_fsset_fs 的切换。这些 API 只在内核空间中工作,不再涉及用户空间的内存访问,因此没有了跨空间访问的风险,开发者不需要手动进行切换保护。

特别说明:

本文转载自:https://blog.csdn.net/sz66cm/article/details/142653909

posted @ 2025-09-24 12:04  cockpunctual  阅读(29)  评论(0)    收藏  举报