NFSD in v6.14 now has an implementation of attribute delegation. This implementation is active and enabled when NFSv4.2 is in use. xfstests with a recent vintage Linux NFS client shows passing tests for everything but generic/647 and generic/729. FSTYP -- nfs PLATFORM -- Linux/x86_64 morisot 6.11.10-200.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Nov 23 00:53:13 UTC 2024 MKFS_OPTIONS -- klimt.ib.1015granger.net:/export/fast MOUNT_OPTIONS -- -o vers=4.2,rdma,sec=sys klimt.ib.1015granger.net:/export/fast /media/scratch generic/729 0s ... [failed, exit status 1]- output mismatch (see /home/cel/src/xfstests/results//generic/729.out.bad) --- tests/generic/729.out 2023-08-22 18:02:12.821736344 -0400 +++ /home/cel/src/xfstests/results//generic/729.out.bad 2024-12-18 09:11:12.878767053 -0500 @@ -1,2 +1,3 @@ QA output created by 729 Silence is golden +mmap-rw-fault: pread /media/test/mmap-rw-fault.tmp (O_DIRECT): 0 != 4096: Bad address ... (Run 'diff -u /home/cel/src/xfstests/tests/generic/729.out /home/cel/src/xfstests/results//generic/729.out.bad' to see the entire diff) Ran: generic/729 Failures: generic/729 Failed 1 of 1 tests Both of these failures go away when NFSv4.1 is used.
The mmap-rw-fault program truncates a test file, then writes the file with O_DIRECT, and then reads from that file using mmap. After writing the file and closing it, the mmap fails with EFAULT because the cached file size on the client is still zero. This is because, upon completion of the direct WRITE, nfs_writeback_update_inode() skips the file size update if an attribute delegation is present. The mmap-rw-fault program opens and closes the test program repeatedly. Every other open specifies the O_DIRECT flag. However the Linux NFS client caches open and delegation state IDs after the application closes. For the O_DIRECT WRITEs, the client uses the cached delegation state ID, and that state ID is what quashes the file size update (when it represents an attribute delegation). NFSv4.1 also uses a delegation state ID in this case, but because it does not represent an attribute delegation, nfs_writeback_update_inode() updates the file size appropriately. NFSv4.2 OPEN_XOR_DELEG makes this problem worse because in that case, there is no cached OPEN state ID for the direct I/O to fall back on.