内核版本
Linux 5.15.0-58-generic
实例代码
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
static struct file *open_dump_file(char* string, mm_segment_t* fs)
{
struct file *filp = NULL;
filp = filp_open(string, O_RDWR | O_CREAT | O_APPEND, 0644);
if (IS_ERR(filp)) {
return NULL;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
*fs = get_fs();
set_fs(KERNEL_DS);
#else
*fs = force_uaccess_begin();
#endif
return filp;
}
static int close_dump_file(struct file * filp, mm_segment_t* fs)
{
if (filp == NULL || fs == NULL)
return -EFAULT;
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
set_fs(*fs);
#else
force_uaccess_end(*fs);
#endif
filp_close(filp, NULL);
return 0;
}
static int write_file(struct file * filp, char* buf, int len)
{
int ret = 0;
if (filp == NULL || buf == NULL)
return -EFAULT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
ret = kernel_write(filp, buf, len, &filp->f_pos);
#else
if (filp->f_op->write)
ret = vfs_write(filp, buf, len, &filp->f_pos);
else {
return -EFAULT;
}
#endif
memset(buf, 0, len);
return ret;
}
int write_test(void)
{
struct file *filp = NULL;
mm_segment_t fs;
char test_data[32] = {0};
int ret = 0;
filp = open_dump_file("/var/log/test.log", &fs);
if (filp == NULL) {
printk("open file failed.\n");
return -EFAULT;
}
sprintf(test_data, "just for test!");
ret = write_file(filp, test_data, strlen(test_data));
if (ret) {
printk("write_file failed.\n");
return ret;
}
ret = close_dump_file(filp, &fs);
if (ret) {
printk("close file failed. ret = %d\n", ret);
return ret;
}
return 0;
}
小结
网上当时找了很多的内容,但都没有说明内核版本,全都是vfs_write啥的,但在高版本时内核新建的文件,在系统中对应的读写成员 filp->f_op->write、filp->f_op->read
都是空指针,因此根本无法用,最后还是找经验丰富的学长才知道代码版本导致。这次真是被版本🕳了,好好更新就行了嘛非得换接口。