Linux 5.10+内核读写文件时get_fs/set_fs报错的替代方案是什么
内核5.10+版本读写文件接口替换方案
5.10及以上版本内核正式移除了get_fs、set_fs系列接口,原来通过修改地址段限制调用vfs读写的方案已经不可用,内核官方提供了专门针对内核空间缓冲区读写文件的接口kernel_write/kernel_read,可以直接替代原有逻辑,不需要手动处理地址段检查。
核心修改要点
- 移除原代码中
mm_segment_t fs;变量定义,以及所有get_fs()、set_fs()相关调用 - 将原
vfs_write(fp, buf, size, &pos);调用替换为kernel_write(fp, buf, size, &pos); - 如果需要读文件,将
vfs_read替换为kernel_read即可
修改后完整可运行代码
#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/string.h> #include <linux/slab.h> int __init hello_init(void) { unsigned char buf1[12] = "hello world."; unsigned char buf2[12] = "kernel file."; struct file *fp; loff_t pos; printk("hello enter\n"); fp = filp_open("/home/kernel_file", O_RDWR | O_CREAT, 0644); if (IS_ERR(fp)) { printk("create file error\n"); return PTR_ERR(fp); } pos = fp->f_pos; kernel_write(fp, buf1, sizeof(buf1), &pos); fp->f_pos = pos; kernel_write(fp, buf2, sizeof(buf2), &pos); fp->f_pos = pos; filp_close(fp, NULL); return 0; } void __exit hello_exit(void) { printk(" exit\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");
补充说明
- 内核直接读写普通文件的方案仅适合调试场景,不符合内核设计规范,生产环境建议使用sysfs、procfs、netlink等标准接口实现内核态与用户态的数据交互
- 如果你需要读取
myTest.txt获取参数,只需要修改filp_open的路径为该文件的绝对路径,调用kernel_read读取内容即可
内容的提问来源于stack exchange,提问作者liu
相关产品推荐
相关产品推荐

