NFSD: Implement FATTR4_CLONE_BLKSIZE attribute
Subsystems (2)
[email protected]
maintainerPATCH v2 1/1 NFSD: Implement FATTR4_CLONE_BLKSIZE attribute
From: Chuck Lever <[email protected]>
RFC 7862 states that if an NFS server implements a CLONE operation, it MUST also implement FATTR4_CLONE_BLKSIZE. NFSD implements CLONE, but does not implement FATTR4_CLONE_BLKSIZE.
Note that in Section 12.2, RFC 7862 claims that FATTR4_CLONE_BLKSIZE is RECOMMENDED, not REQUIRED. Likely this is because a minor version is not permitted to add a REQUIRED attribute. Confusing.
We assume this attribute reports a block size as a count of bytes, as RFC 7862 does not specify a unit.
X-Cc: [email protected] # v6.7+
--- fs/nfsd/nfs4xdr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +9 -1
@@ -3391,6 +3391,14 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr,return nfsd4_encode_bitmap4 (xdr, supp[0 ], supp[1 ], supp[2 ]); } +static __be32 nfsd4_encode_fattr4_clone_blksize (struct xdr_stream *xdr, +const struct nfsd4_fattr_args *args) +{ +struct inode *inode =d_inode (args->dentry); + +return nfsd4_encode_uint32_t (xdr, inode->i_sb->s_blocksize); +} +#ifdef CONFIG_NFSD_V4_SECURITY_LABEL static __be32 nfsd4_encode_fattr4_sec_label (struct xdr_stream *xdr,const struct nfsd4_fattr_args *args)
@@ -3545,7 +3553,7 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { [FATTR4_MODE_SET_MASKED] = nfsd4_encode_fattr4__noop, [FATTR4_SUPPATTR_EXCLCREAT] = nfsd4_encode_fattr4_suppattr_exclcreat, [FATTR4_FS_CHARSET_CAP] = nfsd4_encode_fattr4__noop, - [FATTR4_CLONE_BLKSIZE] = nfsd4_encode_fattr4__noop, + [FATTR4_CLONE_BLKSIZE] = nfsd4_encode_fattr4_clone_blksize, [FATTR4_SPACE_FREED] = nfsd4_encode_fattr4__noop, [FATTR4_CHANGE_ATTR_TYPE] = nfsd4_encode_fattr4__noop,
Signature · 1 line
2.49.0
Quoted 43 lines · On Tue, May 6, 2025 at 5:01 PM <[email protected]> wrote:
From: Chuck Lever <[email protected]>
RFC 7862 states that if an NFS server implements a CLONE operation, it MUST also implement
FATTR4_CLONE_BLKSIZE. NFSD implements CLONE, but does not implementFATTR4_CLONE_BLKSIZE.Note that in Section 12.2, RFC 7862 claims that
FATTR4_CLONE_BLKSIZEis RECOMMENDED, not REQUIRED. Likely this is because a minor version is not permitted to add a REQUIRED attribute. Confusing.We assume this attribute reports a block size as a count of bytes, as RFC 7862 does not specify a unit.
Reported-by Roland Mainz <[email protected]>Suggested-by Christoph Hellwig <[email protected]>X-Cc: [email protected] # v6.7+
Signed-off-by Chuck Lever <[email protected]>--- fs/nfsd/nfs4xdr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)fs/nfsd/nfs4xdr.c +8
-0@@ -3391,6 +3391,14 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr,return nfsd4_encode_bitmap4 (xdr, supp[0 ], supp[1 ], supp[2 ]); } +static __be32 nfsd4_encode_fattr4_clone_blksize (struct xdr_stream *xdr, +const struct nfsd4_fattr_args *args) +{ +struct inode *inode =d_inode (args->dentry); + +return nfsd4_encode_uint32_t (xdr, inode->i_sb->s_blocksize); +} +#ifdef CONFIG_NFSD_V4_SECURITY_LABEL static __be32 nfsd4_encode_fattr4_sec_label (struct xdr_stream *xdr,const struct nfsd4_fattr_args *args)
fs/nfsd/nfs4xdr.c static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { · line 3558
Quoted 7 lines
fs/nfsd/nfs4xdr.c +1
-1@@ -3545,7 +3553,7 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { [FATTR4_MODE_SET_MASKED] = nfsd4_encode_fattr4__noop, [FATTR4_SUPPATTR_EXCLCREAT] = nfsd4_encode_fattr4_suppattr_exclcreat, [FATTR4_FS_CHARSET_CAP] = nfsd4_encode_fattr4__noop, - [FATTR4_CLONE_BLKSIZE] = nfsd4_encode_fattr4__noop, + [FATTR4_CLONE_BLKSIZE] = nfsd4_encode_fattr4_clone_blksize, [FATTR4_SPACE_FREED] = nfsd4_encode_fattr4__noop, [FATTR4_CHANGE_ATTR_TYPE] = nfsd4_encode_fattr4__noop,
Looks good to me - Reviewed-by: Roland Mainz <[email protected]>
----
Bye,
Roland
Signature · 5 lines
__ . . __ (o.\ \/ /.o) [email protected] \__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer /O /==\ O\ TEL +49 641 3992797 (;O/ \/ \O;)
fs/nfsd/nfs4xdr.c static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr, · line 3395
Quoted 2 lines · On Tue, May 06, 2025 at 11:01:05AM -0400, [email protected] wrote:
fs/nfsd/nfs4xdr.c +2
-0+static __be32 nfsd4_encode_fattr4_clone_blksize (struct xdr_stream *xdr, +const struct nfsd4_fattr_args *args)
Overly long line here. And easily avoided by using the much more maintainable two-tab indents for prototype continuations.
fs/nfsd/nfs4xdr.c static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr, · line 3399
Quoted 4 lines
fs/nfsd/nfs4xdr.c +4
-0+{ +struct inode *inode =d_inode (args->dentry); + +return nfsd4_encode_uint32_t (xdr, inode->i_sb->s_blocksize);
That's a bit of an assumption. The generic clone prep function uses the block size, but file systems aren't required to actually use generic_remap_file_range_prep.
Probably still the best we can do, but a comment explaining including a reference to generic_remap_checks / generic_remap_file_range_prep would be very useful here.