Linux VFS:vfs_read(..., &offset) 与 vfs_llseek(..., pos):如何从内核模块中查找文件

Linux VFS: vfs_read(..., &offset) vs. vfs_llseek(..., pos): How to seek in a file from kernel module

给定

fs/read_write.c 中,函数 vfs_read() 的签名如下所示:

 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)

其中最后一个参数是指向某个位置的指针。签名本身没有记录。签名,我认为,暗示初始读取位置被传递给读取函数,并且可能更新的位置(下一个要读取的位置)写在 *pos 中。然而,fs/read_write.c 中的函数 vfs_llseek() 带有签名

loff_t vfs_llseek(struct file *file, loff_t offset, int whence)                                                                              

这看起来像一个 'normal' 搜索功能。此外,签名没有与代码一起记录。

问题:

  1. 如何使用 VFS 在文件中实际查找?
  2. 位置是否等于文件中字节的索引,即第一个字节位置= 0,后续字节位置=位置+ 1?

How does one actually seek in a file using VFS?

为此使用 vfs_llseek 是正确的。

VFS 实际上有一个关于当前文件位置 的概念,它存储在file->f_pos 字段中。成功调用 vfs_llseek 更新此位置。但是要在读取文件时使用此位置,您需要通过 vfs_readpos 参数显式传递字段的值,并在成功 return 后写回该参数的结果值到现场:

loff_t pos = file->f_pos;
ssize_t res = vfs_read(file, buf, count, &pos);
if (res > 0) {
  file->f_pos = pos;
}

vfs_read 的现有签名允许在正常 read 系统调用和 pread 系统调用中使用此函数,后者使用 user-specified 位置而不是当前位置。

Is the position equal to the index of the byte in the file, i.e. first byte position = 0, position = position + 1 for subsequent bytes?

对于存储在硬盘驱动器或其他媒体上的常规文件也是如此。

对于特殊文件,比如位于 /sys/dev 下的文件,位置的含义可以是 any(即,它由文件)。例如,如果文件将信息公开为记录数组,则位置可能表示记录的索引,而不是字节的索引。