Let's look at the code that these syscalls cause to be executed.
Citing mm/readahead.c
here:
611 │ ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
612 │ {
613 │ ssize_t ret;
614 │ struct fd f;
615 │
616 │ ret = -EBADF;
617 │ f = fdget(fd);
618 │ if (!f.file || !(f.file->f_mode & FMODE_READ))
619 │ goto out;
620 │
621 │ /*
622 │ * The readahead() syscall is intended to run only on files
623 │ * that can execute readahead. If readahead is not possible
624 │ * on this file, then we must return -EINVAL.
625 │ */
626 │ ret = -EINVAL;
627 │ if (!f.file->f_mapping || !f.file->f_mapping->a_ops ||
628 │ !S_ISREG(file_inode(f.file)->i_mode))
629 │ goto out;
630 │
631 │ ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED);
632 │ out:
633 │ fdput(f);
634 │ return ret;
635 │ }
Note line 631: this thing calls vfs_fadvise(…, POSIX_FADV_WILLNEED)
underneath.
Comparing that to mm/fadvise.c
:
192 │ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
193 │ {
194 │ struct fd f = fdget(fd);
195 │ int ret;
196 │
197 │ if (!f.file)
198 │ return -EBADF;
199 │
200 │ ret = vfs_fadvise(f.file, offset, len, advice);
201 │
202 │ fdput(f);
203 │ return ret;
204 │ }
This code also just calls the same vfs_fadvise
, so using posix_fadvise64(…, WILLNEED)
is functionally the same.
The difference lies (potentially) in the errors reported when the file you use either function on is not suitable: readahead
itself checks whether the file is readable, mapped, actually has any useful addressing operations, and returns EBADF
or EINVAL
if not.
fadvise64
, the syscall behind posix_fadvise
, directly calls vfs_fadvise
, so that this checks for these things internally, and might return different errors. (I haven't checked whether it actually does).