Linux
posix_fadvise 和 readahead 之間的區別
根據手冊頁,
readahead
是 Linux 特定的:符合
readahead() 系統呼叫是特定於 Linux 的,應避免在可移植應用程序中使用它。
並且
posix_fadvise
是攜帶式的:符合
POSIX.1-2001,POSIX.1-2008。請注意,在 POSIX.1-2001 TC1 中,len 參數的類型從 size_t 更改為 off_t。
但他們倆似乎都在做同樣的事情。但是,除了冒便攜性之外,交換這兩種功能的後果是什麼?
讓我們看看這些系統呼叫導致執行的程式碼。
在這裡引用
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
, 直接呼叫vfs_fadvise
, 以便在內部檢查這些東西, 並可能返回不同的錯誤。(我還沒有檢查它是否真的如此)。