You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核中get_fs与sget_fc的区别及内核模块读取txt文件方法咨询

问题1:get_fs与sget_fc的区别

  • get_fs()、set_fs()、KERNEL_DS是Linux 5.10及更早版本内核的专用接口,作用是调整进程地址空间的访问权限上限。旧版本内核如果要在内核态直接调用vfs_read/vfs_write读写文件,需要先通过set_fs(KERNEL_DS)把地址访问上限修改为内核空间范围,避免系统调用的用户地址检查拦截内核地址。这套接口在5.10版本之后已经从内核主线完全移除,所以你使用5.11版本内核编译时会报隐式声明错误。
  • 编译器提示的sget_fc是完全无关的内核接口,功能是获取文件系统超级块的上下文配置,和地址空间切换没有任何关联,只是函数名拼写和get_fs相近才被编译器当作候选推荐,不需要考虑使用该接口。

问题2:内核模块中正确读取文本文件的实现方案

5.10之后的内核已经提供了原生的kernel_read/kernel_write接口,不需要再手动切换地址空间,你调整后的代码思路是正确的,但存在以下几个问题需要修复:

  1. 输入缓冲区未分配内存:你定义的void *in_buf仅为未初始化的空指针,直接传入读取接口会引发内核空指针崩溃,需要用kmalloc申请对应大小的内核内存,使用完成后通过kfree释放。
  2. 读写长度变量未初始化:count1、count2都是未初始化的局部变量,值为随机栈垃圾数据,会导致读写长度异常,需要先给长度变量赋值为实际要读写的字节数。
  3. 日志打印的换行符错误:你代码里的error/n应为error\n,否则不会正常换行。

以下是修正后的可运行代码:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/slab.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Reversing text from Jackson");
MODULE_VERSION("0.1");

#define BUF_SIZE 4096 // 可按需调整缓冲区大小

static int __init test_start(void){
        struct file *i_fp, *o_fp;
        loff_t pos;
        ssize_t read_cnt, write_cnt;
        char *in_buf;
        const char *test_out = "add";

        printk(KERN_INFO "start converting...\n");
        // 打开文件
        i_fp = filp_open("/home/j0000/Desktop/file/input.txt", O_RDONLY, 0);
        o_fp = filp_open("/home/j0000/Desktop/file/output.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
        if (IS_ERR(i_fp)){
                printk(KERN_INFO "input file open error\n");
                return PTR_ERR(i_fp);
        }
        if (IS_ERR(o_fp)){
                printk(KERN_INFO "output file open error\n");
                filp_close(i_fp, NULL);
                return PTR_ERR(o_fp);
        }
        // 分配缓冲区
        in_buf = kmalloc(BUF_SIZE, GFP_KERNEL);
        if (!in_buf) {
                printk(KERN_INFO "kmalloc failed\n");
                goto out_close;
        }
        // 读取文本文件
        pos = 0;
        read_cnt = kernel_read(i_fp, in_buf, BUF_SIZE - 1, &pos);
        if (read_cnt < 0) {
                printk(KERN_INFO "kernel_read failed: %ld\n", read_cnt);
                goto out_free;
        }
        in_buf[read_cnt] = '\0'; // 文本末尾加字符串结束符
        printk(KERN_INFO "read content: %s\n", in_buf);
        // 写入测试内容
        pos = 0;
        write_cnt = kernel_write(o_fp, test_out, strlen(test_out), &pos);
        if (write_cnt < 0) {
                printk(KERN_INFO "kernel_write failed: %ld\n", write_cnt);
        }

out_free:
        kfree(in_buf);
out_close:
        filp_close(i_fp, NULL);
        filp_close(o_fp, NULL);
        return 0;
}

static void __exit test_end(void){
        printk(KERN_INFO "Ending~\n");
}

module_init(test_start);
module_exit(test_end);

注意:内核态直接读写文件存在触发死锁、内存泄漏、文件系统不一致的风险,非特殊场景不建议使用,普通文件操作需求优先在用户态实现。

内容的提问来源于stack exchange,提问作者jackson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 15:27:03