Linux Kernel 5.3
fstat
で定義されたシステムコールを考えてみましょうint fstat(int fd, struct stat *statbuf);
。fstat
ext4のシステムコールにはディスクアクセスが必要ですか?
関連調査をしていくつかの情報を見つけました。システムコールのカーネルエントリポイントは次の関数です。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
開かれたファイル記述子がある場合、メモリからすべての統計を取得できるため、高価なディスクアクセスを回避できますか?
修正するfree && sync && echo 3 > /proc/sys/vm/drop_caches && free
:カーネルキャッシュを呼び出す前にフラッシュを試みましたが、syscall
statシステムコールのタイミングには影響しませんでした。そのため、ディスクへのアクセスが必要ないと思う傾向があります。
答え1
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が提供されていないことがわかります。推測したように、データはキャッシュされたinodeから取得されます。
また、見ることができますfstat(2)
マンページそれは述べた:
ノート: パフォーマンスと単純性のため、
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 ゲスト共有フォルダに対してサポートされます。