_Linux Kernel 5.3
_
int fstat(int fd, struct stat *statbuf);
として定義されているfstat
syscallを考えてみましょう。 ext4のfstat
syscallにディスクアクセスは必要ですか?
私はそれに関連するいくつかの調査を行い、いくつかの情報を見つけました。システムコールへのカーネル内のエントリポイントは、関数 _vfs_statx_fd
_ です。その実装は次のようになります。
_int vfs_statx_fd(unsigned int fd, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{
struct fd f;
int error = -EBADF;
if (query_flags & ~KSTAT_QUERY_FLAGS)
return -EINVAL;
f = fdget_raw(fd);
if (f.file) {
error = vfs_getattr(&f.file->f_path, stat,
request_mask, query_flags);
fdput(f);
}
return error;
}
_
つまり、ユーザーがシステムコールに渡した実際のファイル記述子である_unsigned int fd
_を使用して、 _struct file
_ へのポインターを見つけます。その定義の重要な部分は
_struct file {
//...
struct path f_path;
struct inode *f_inode; /* cached value */
//...
}
_
つまり、基本的に、_struct file
_は開いているファイルを表し、構造体にはdentry
およびinode
への参照が含まれています。
開いているファイル記述子がある場合に、メモリからのみすべての統計を取得して、コストのかかるディスクアクセスを回避できるのは本当ですか?
更新:syscall
を呼び出す直前に_free && sync && echo 3 > /proc/sys/vm/drop_caches && free
_を使用してカーネルキャッシュをフラッシュしようとしましたが、stat syscallのタイミングに影響しませんでした。そのため、ディスクへのアクセスは必要ないと思いがちです。
Ext4ファイルシステムでは、_vfs_statx_fd
_から始まる関数グラフは
_ 0) | vfs_statx_fd() {
0) | __fdget_raw() {
0) 0.225 us | __fget_light();
0) 0.775 us | }
0) | vfs_getattr() {
0) | security_inode_getattr() {
0) | selinux_inode_getattr() {
0) | __inode_security_revalidate() {
0) | _cond_resched() {
0) 0.216 us | rcu_all_qs();
0) 0.575 us | }
0) 0.945 us | }
0) | inode_has_perm() {
0) 0.356 us | avc_has_perm();
0) 0.709 us | }
0) 2.223 us | }
0) 2.808 us | }
0) | vfs_getattr_nosec() {
0) | ext4_file_getattr() {
0) | ext4_getattr() {
0) 0.203 us | generic_fillattr();
0) 0.600 us | }
0) 1.040 us | }
0) 1.502 us | }
0) 4.854 us | }
0) 6.913 us | }
_
これらすべての機能の実装を見ると、ディスクI/Oのプロビジョニングがないことがわかります。ご想像のとおり、データはキャッシュされたiノードから取得されます。
the fstat(2)
manpage も参照してください:
注:パフォーマンスと単純化の理由から、
stat
構造体のさまざまなフィールドには、システムの実行中のさまざまな瞬間の状態情報が含まれる場合がありますコール。たとえば、_st_mode
_または_st_uid
_がchmod(2)
またはchown(2)
を呼び出して別のプロセスによって変更された場合=、stat()
は、古い_st_mode
_と新しい_st_uid
_を一緒に返すか、古い_st_uid
_と新しい_st_mode
_を一緒に返します。
(ただし、これはキャッシングよりもロックに関係しています)。
他の一部のファイルシステムでは、_AT_STATX_FORCE_SYNC
_をクエリフラグに含めて、リモート同期を強制できます。これは、Ceph、Fuse、NFS、およびVirtualBoxゲスト共有フォルダーでサポートされています。