posix_fadvise 和 readahead 之间的区别

posix_fadvise 和 readahead 之间的区别

根据联机帮助页,readaheadLinux 特定:

符合

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
fadvise64posix_fadvisevfs_fadvise

相关内容