fstat 是否需要在 Linux/ext4 上訪問磁碟?
Linux Kernel 5.3
考慮
fstat
定義為的系統呼叫int fstat(int fd, struct stat *statbuf);
。ext4 上的系統呼叫****是否需要磁碟訪問?fstat
我做了一些與之相關的研究並找到了一些資訊。系統呼叫的核心入口點是函式
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 系統呼叫的時間。所以我傾向於認為不需要磁碟訪問。
在 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
or 通過呼叫orst_uid
被另一個程序更改, 則可能會返回 old和 new ,或者 old和 new 。chmod(2)
chown(2)
stat()``st_mode``st_uid``st_uid``st_mode
(儘管這更多地與鎖定而不是記憶體有關)。
對於其他一些文件系統,
AT_STATX_FORCE_SYNC
可以在查詢標誌中包含強制遠端同步;這在 Ceph、FUSE、NFS 和 VirtualBox 來賓共享文件夾上受支持。