根据手册,readahead
是特定于Linux的:
遵循readahead()系统调用是Linux特有的,在可移植应用程序中应该避免使用它。
posix_fadvise
是可移植的:
符合POSIX.1-2001,POSIX.1-2008。注意,在POSIX.1-2001 size_t中,len参数的类型从off_t更改为TC1。
但他们俩似乎都在做同样的事。但是,除了冒着可移植性的风险之外,交换这两个功能会带来什么后果呢?
发布于 2021-12-12 18:01:29
让我们看一下这些syscalls导致执行的代码。
在这里引用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)
。
将其与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
后面的syscall,直接调用vfs_fadvise
,这样就可以在内部检查这些事情,并可能返回不同的错误。(我没有检查它是否真的存在)。
https://unix.stackexchange.com/questions/681188
复制相似问题