GIVEN:
in fs/read_write.c
the function vfs_read()
has a signature as shown bewlow:
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
where the last argument is a pointer to a position. The signature itself is not documented. The signature, I would think, insinuates that the initial read position is passed to the read function, and maybe the updated position (next position to be read from) is written in *pos
. Then, however, there is the function vfs_llseek()
in fs/read_write.c
with the signature
loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
which looks like a 'normal' seek function. Also, the signature is not documented along side with the code.
QUESTIONS:
How does one actually seek in a file using VFS?
Using vfs_llseek
is correct for this purpose.
VFS actually has a notion about current file's position, which is stored in the file->f_pos
field. Successful call for vfs_llseek
updates this position. But for use this position when read the file, you need explicitly pass the value of the field via pos
parameter of the vfs_read
and, upon successful return, write resulted value of that parameter back to the field:
loff_t pos = file->f_pos;
ssize_t res = vfs_read(file, buf, count, &pos);
if (res > 0) {
file->f_pos = pos;
}
Existed signature of vfs_read
allows to use this function both in normal read
syscall and in pread
syscall, which uses user-specified position instead of the current one.
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?
This is true for regular files, which are stored on a hard drive or other media.
For special files, like ones located under /sys
or /dev
, meaning of the position could be any (that is, it is defined by the file). E.g., if a file exposes information as an array of records, position could mean the index of the record, not the index of the byte.