Bug 219738

Summary: generic/647 and generic/729 fail when attribute delegation is enabled
Product: File System Reporter: Chuck Lever (chuck.lever)
Component: NFSAssignee: Trond Myklebust (trondmy)
Status: NEW ---    
Severity: normal CC: chuck.lever
Priority: P3    
Hardware: All   
OS: Linux   
Kernel Version: Subsystem:
Regression: No Bisected commit-id:

Description Chuck Lever 2025-01-31 14:39:54 UTC
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.
Comment 1 Chuck Lever 2025-01-31 14:50:01 UTC
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.