From: Chuck Lever chuck.lever@oracle.com
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.
Reported-by: Roland Mainz roland.mainz@nrubsig.org Suggested-by: Christoph Hellwig hch@infradead.org Reviewed-by: Roland Mainz roland.mainz@nrubsig.org Cc: stable@vger.kernel.org # v6.7+ Signed-off-by: Chuck Lever chuck.lever@oracle.com --- fs/nfsd/nfs4xdr.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index e67420729ecd..9eb8e5704622 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3391,6 +3391,23 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr, return nfsd4_encode_bitmap4(xdr, supp[0], supp[1], supp[2]); }
+/* + * Copied from generic_remap_checks/generic_remap_file_range_prep. + * + * These generic functions use the file system's s_blocksize, but + * individual file systems aren't required to use + * generic_remap_file_range_prep. Until there is a mechanism for + * determining a particular file system's (or file's) clone block + * size, this is the best NFSD can do. + */ +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 +3562,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,
On Wed, 2025-05-07 at 10:45 -0400, cel@kernel.org wrote:
From: Chuck Lever chuck.lever@oracle.com
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.
Isn't CLONE itself an optional operation? It wouldn't make sense to REQUIRE this attribute on servers that don't support CLONE, so I think it makes sense that it should be optional. Anyway, I'm just being pedantic.
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 roland.mainz@nrubsig.org Suggested-by: Christoph Hellwig hch@infradead.org Reviewed-by: Roland Mainz roland.mainz@nrubsig.org Cc: stable@vger.kernel.org # v6.7+ Signed-off-by: Chuck Lever chuck.lever@oracle.com
fs/nfsd/nfs4xdr.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index e67420729ecd..9eb8e5704622 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3391,6 +3391,23 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr, return nfsd4_encode_bitmap4(xdr, supp[0], supp[1], supp[2]); } +/*
- Copied from generic_remap_checks/generic_remap_file_range_prep.
- These generic functions use the file system's s_blocksize, but
- individual file systems aren't required to use
- generic_remap_file_range_prep. Until there is a mechanism for
- determining a particular file system's (or file's) clone block
- size, this is the best NFSD can do.
- */
+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 +3562,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,
Reviewed-by: Jeff Layton jlayton@kernel.org
On 5/7/25 11:34 AM, Jeff Layton wrote:
On Wed, 2025-05-07 at 10:45 -0400, cel@kernel.org wrote:
From: Chuck Lever chuck.lever@oracle.com
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.
Isn't CLONE itself an optional operation? It wouldn't make sense to REQUIRE this attribute on servers that don't support CLONE, so I think it makes sense that it should be optional. Anyway, I'm just being pedantic.
My take:
It's problematic that one part of the specification states that FATTR4_CLONE_BLKSIZE is mandatory-to-implement (with a MUST), and another categorizes the attribute as RECOMMENDED.
I understand the reasons why this might be necessary, but IMO implementers who do not read the whole document might see one or the other of these (because they are in widely separated sections) and then do the wrong thing.
Section 12.2 needs to provide an explicit explanation to make it clear.
linux-stable-mirror@lists.linaro.org