根据联机帮助页,readahead
Linux 特定:
符合
readahead() 系统调用是 Linux 特定的,应避免在便携式应用程序中使用它。
并且posix_fadvise
是便携式的:
符合
POSIX.1-2001、POSIX.1-2008。请注意,在 POSIX.1-2001 TC1 中,len 参数的类型从 size_t 更改为 off_t。
但他们俩似乎都在做同样的事情。但是,除了冒着可移植性的风险之外,交换这两种功能还会产生什么后果呢?
答案1
让我们看看这些系统调用导致执行的代码。
引用mm/readahead.c
这里:
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 │ }
注意第631行:这个东西调用vfs_fadvise(…, POSIX_FADV_WILLNEED)
underground。
比较一下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 │ }
这段代码也只是调用相同的vfs_fadvise
,所以使用的posix_fadvise64(…, WILLNEED)
是功能上相同。
差异(可能)在于当您使用任一函数的文件不合适时报告的错误:readahead
它本身检查文件是否可读、映射、是否实际上具有任何有用的寻址操作,如果不合适则返回EBADF
或。 ,后面的系统调用,直接调用,以便在内部检查这些内容,并可能返回不同的错误。 (我还没有检查它是否真的如此)。EINVAL
fadvise64
posix_fadvise
vfs_fadvise