posix_fadviseと先読みの違い

posix_fadviseと先読みの違い

マンページによると、readaheadLinuxに関する内容は次のとおりです。

遵守する

readahead() システムコールは Linux にのみ適用され、移植可能なアプリケーションでは使用しないでください。

そしてposix_fadvise移植性に優れています:

遵守する

POSIX.1-2001、POSIX.1-2008。 POSIX.1-2001 TC1では、lenパラメーターのタイプがsize_tからoff_tに変更されました。

しかし、どちらも同じことをしているようです。しかし、移植性のリスクに加えて、これら2つの機能を交換するとどのような結果が発生しますか?

答え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)地下を呼び出します。

これを比較してください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)、次のようにします。機能的に同じ

違いは、おそらく2つの関数のいずれかで使用されるファイルが不適切な場合に報告されるエラーです。readaheadファイル自体がファイルを読み取ることができるか、マップされているか、実際に有用なアドレス指定操作があるかどうかを確認し、EBADF不適切な場合はORを返します。 、後続のシステムコールは内部的にこれを確認するために直接呼び出され、他のエラーを返すことがあります。 (実際にグランジは確認できませんでした。)EINVAL
fadvise64posix_fadvisevfs_fadvise

関連情報