Search code examples
cfile-iolinux-kernelvfs

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


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:

  1. How does one actually seek in a file using VFS?
  2. 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?

Solution

  • 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.