fstat에는 Linux/ext4에서 디스크 액세스가 필요합니까?

fstat에는 Linux/ext4에서 디스크 액세스가 필요합니까?

Linux Kernel 5.3

fstat로 정의된 시스템 호출을 생각해 보세요 int fstat(int fd, struct stat *statbuf);.fstatext4의 시스템 호출에는 디스크 액세스가 필요합니까?

관련 조사를 하다가 몇 가지 정보를 찾았습니다. 시스템 호출의 커널 진입점은 다음 함수입니다.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: 커널 캐시를 호출하기 전에 플러시를 시도했지만 syscallstat 시스템 호출 타이밍에는 영향을 미치지 않았습니다. 그래서 디스크 액세스가 필요하지 않다고 생각하는 경향이 있습니다.

답변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 게스트 공유 폴더에 대해 지원됩니다.

관련 정보