]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFS: add basic STATX_DIOALIGN and STATX_DIO_READ_ALIGN support
authorMike Snitzer <snitzer@kernel.org>
Fri, 19 Sep 2025 14:36:31 +0000 (10:36 -0400)
committerAnna Schumaker <anna.schumaker@oracle.com>
Tue, 30 Sep 2025 20:10:30 +0000 (16:10 -0400)
NFS doesn't have DIO alignment constraints, so have NFS respond with
accommodating DIO alignment attributes (rather than plumb in GETATTR
support for STATX_DIOALIGN and STATX_DIO_READ_ALIGN).

The most coarse-grained dio_offset_align is the most accommodating
(e.g. PAGE_SIZE, in future larger may be supported).

Now that NFS has support, NFS reexport will now handle unaligned DIO
(NFSD's NFSD_IO_DIRECT support requires the underlying filesystem
support STATX_DIOALIGN and/or STATX_DIO_READ_ALIGN).

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
fs/nfs/inode.c

index 49df9debb1a6912862e838b3bc134806baa10d8f..84bf3d21c25cc46d4f2786607f4cec974e5738a4 100644 (file)
@@ -1073,6 +1073,21 @@ out_no_revalidate:
        if (S_ISDIR(inode->i_mode))
                stat->blksize = NFS_SERVER(inode)->dtsize;
        stat->btime = NFS_I(inode)->btime;
+
+       /* Special handling for STATX_DIOALIGN and STATX_DIO_READ_ALIGN
+        * - NFS doesn't have DIO alignment constraints, avoid getting
+        *   these DIO attrs from remote and just respond with most
+        *   accommodating limits (so client will issue supported DIO).
+        * - this is unintuitive, but the most coarse-grained
+        *   dio_offset_align is the most accommodating.
+        */
+       if ((request_mask & (STATX_DIOALIGN | STATX_DIO_READ_ALIGN)) &&
+           S_ISREG(inode->i_mode)) {
+               stat->result_mask |= STATX_DIOALIGN | STATX_DIO_READ_ALIGN;
+               stat->dio_mem_align = 4; /* 4-byte alignment */
+               stat->dio_offset_align = PAGE_SIZE;
+               stat->dio_read_offset_align = stat->dio_offset_align;
+       }
 out:
        trace_nfs_getattr_exit(inode, err);
        return err;