Linux读写文件的一个demo如下,运行后系统死机了,原因是f->f_op->write为NULL,导致空指针,将
f->f_op->write换成vfs_write代码正常运行
static int stmvl53l0x_write_offset_calibration_file(void)
{
struct file *f;
char buf[8];
mm_segment_t fs;
f = filp_open("/productinfo/offset", O_WRONLY|O_CREAT, 0666);
if (IS_ERR(f)) {
vl53l0x_dbgmsg("unable to open /productinfo/offsetl\n");
return PTR_ERR(f);
}
fs = get_fs();
set_fs(KERNEL_DS);
snprintf(buf, 8, "%d", offset_calib);
vl53l0x_dbgmsg("write offset as:%s, buf[0]:%c\n", buf, buf[0]);
f->f_op->write(f, buf, 8, &f->f_pos);
set_fs(fs);
filp_close(f, NULL);
return 0;
}
ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
loff_t *pos)
{
if (file->f_op->write)
return file->f_op->write(file, p, count, pos);
else if (file->f_op->write_iter)
return new_sync_write(file, p, count, pos);
else
return -EINVAL;
}
ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
{
ret = __vfs_write(file, buf, count, pos);
}
也就是说有些文件是write接口,有些是write_iter
对于ext4
const struct file_operations ext4_file_operations = {
.llseek = ext4_llseek,
.read_iter = generic_file_read_iter,
.write_iter = ext4_file_write_iter,
.unlocked_ioctl = ext4_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext4_compat_ioctl,
#endif
.mmap = ext4_file_mmap,
.open = ext4_file_open,
.release = ext4_release_file,
.fsync = ext4_sync_file,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ext4_fallocate,
};
对于procfs
static const struct file_operations proc_reg_file_ops = {
.llseek = proc_reg_llseek,
.read = proc_reg_read,
.write = proc_reg_write,
.poll = proc_reg_poll,
.unlocked_ioctl = proc_reg_unlocked_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = proc_reg_compat_ioctl,
#endif
.mmap = proc_reg_mmap,
.get_unmapped_area = proc_reg_get_unmapped_area,
.open = proc_reg_open,
.release = proc_reg_release,
};
也就是不同的文件系统,相应的file_ops有差异,所以有了VFS(Virtual File System)