
Linux 서버에서 FreeBSD 클라이언트로 NFS 마운트가 있습니다. touch
FreeBSD 클라이언트에서 파일의 atime과 mtime을 설정하는 데 사용하는 경우 ,
tavianator@muon $ touch -at "199112140000" ./foo
tavianator@muon $ touch -mt "199112150000" ./foo
그런 다음 통계 시간을 인쇄하고,
tavianator@muon $ stat -f $'Access: %Sa\nModify: %Sm\nChange: %Sc\n Birth: %SB' ./foo
Access: Dec 14 00:00:00 1991
Modify: Jun 22 16:44:08 2023
Change: Dec 15 00:00:00 1991
Birth: Jun 22 16:45:56 2023
ctime과 mtime이 교환됩니다! 그러나 Linux 서버의 관점에서는 다음이 정확합니다.
tavianator@tachyon $ stat /srv/nfs/freebsd/usr/home/tavianator/foo
File: /srv/nfs/freebsd/usr/home/tavianator/foo
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 0,33 Inode: 54691999 Links: 1
Access: (0640/-rw-r-----) Uid: ( 1000/tavianator) Gid: ( 1000/tavianator)
Access: 1991-12-14 00:00:00.000000000 -0500
Modify: 1991-12-15 00:00:00.000000000 -0500
Change: 2023-06-22 16:45:56.731038486 -0400
Birth: 2023-06-22 16:44:08.075496568 -0400
이 문제의 원인이나 해결 방법을 아시나요? 도움이 될 수 있는 추가 정보:
root@tachyon ~ # uname -a
Linux tachyon 6.3.8-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 14 Jun 2023 20:10:31 +0000 x86_64 GNU/Linux
root@tachyon ~ # findmnt -T /srv/nfs/freebsd/usr/home/tavianator
TARGET
SOURCE FSTYPE OPTIONS
/ /dev/mapper/cryptslash1[/@] btrfs rw,relatime,ssd,discard=async,space_cache=v2,subvolid=261,subvol=/@
root@tachyon ~ # exportfs -v
/srv/nfs 100.101.179.2/32(sync,wdelay,hide,no_subtree_check,fsid=0,sec=sys,rw,secure,no_root_squash,no_all_squash)
/srv/nfs 100.114.24.115/32(sync,wdelay,hide,no_subtree_check,fsid=0,sec=sys,rw,secure,no_root_squash,no_all_squash)
/srv/nfs/freebsd
100.101.179.2/32(sync,wdelay,nohide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
/srv/nfs/freebsd
100.114.24.115/32(sync,wdelay,nohide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
tavianator@muon $ uname -a
FreeBSD muon 13.2-RELEASE FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC amd64
tavianator@muon $ mount | grep nfs,
100.107.249.85:/freebsd/usr/home/tavianator on /usr/home/tavianator (nfs, nfsv4acls)
답변1
Wireshark의 패킷 캡처에 따르면 이는 FreeBSD 클라이언트가 아닌 Linux 서버의 버그인 것으로 보입니다.
나는 이것이 Linux 커널 커밋의 버그라고 생각합니다.e377a3e698fb, 버전 5.18에 처음 포함되었습니다. 이 약속은 TIME_CREATE
보고(예: 출생 시간)에 대한 지원을 추가합니다. 제출 후 파일 타임스탬프를 작성하는 코드는 다음과 같습니다.
if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
p = xdr_reserve_space(xdr, 12);
if (!p)
goto out_resource;
p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
*p++ = cpu_to_be32(stat.atime.tv_nsec);
}
if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
...
}
if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
...
}
if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
...
}
if (bmval1 & FATTR4_WORD1_TIME_CREATE) {
...
}
나는 프로토콜이 작동하는 방식이 bmval1
비트 마스크와 일치하는 순서로 시간이 기록된다는 것이라고 믿습니다. 이 경우 순서는 입니다 [ACCESS, METADATA, MODIFY, CREATE]
. 그러나 보자실제 비트 플래그 값:
#define FATTR4_WORD1_TIME_ACCESS (1UL << 15)
#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16)
#define FATTR4_WORD1_TIME_BACKUP (1UL << 17)
#define FATTR4_WORD1_TIME_CREATE (1UL << 18)
#define FATTR4_WORD1_TIME_DELTA (1UL << 19)
#define FATTR4_WORD1_TIME_METADATA (1UL << 20)
#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
그래서 그들의 주문은~해야 한다yes 로 작성되었습니다 [ACCESS, CREATE, METADATA, MODIFY]
. 이는 내가 보고 있는 것과 일치합니다.
리눅스 | FreeBSD | |
---|---|---|
사용할 권리 | 1991-12-14 00:00:00.000000000 | 1991년 12월 14일 00:00:00 |
만들다 | 2023-06-23 15:19:21.718006131 | 2023년 6월 23일 15:19:24 |
메타데이터 | 2023-06-23 15:19:24.718067075 | 1991년 12월 15일 00:00:00 |
조정 | 1991-12-15 00:00:00.000000000 | 2023년 6월 23일 15:19:21 |