[PATCH v4 16/21] nfsd: allow encoding a filehandle into fattr4 without a svc_fh
From: Jeff Layton
Date: Fri May 22 2026 - 08:41:46 EST
The current fattr4 encoder requires a svc_fh in order to encode the
filehandle. This is not available in a CB_NOTIFY callback. Add a a new
"fhandle" field to struct nfsd4_fattr_args and copy the filehandle into
there from the svc_fh. CB_NOTIFY will populate it via other means.
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
fs/nfsd/nfs4xdr.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 61c555446f63..33b6cd492e56 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2702,7 +2702,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
}
static __be32 nfsd4_encode_nfs_fh4(struct xdr_stream *xdr,
- struct knfsd_fh *fh_handle)
+ const struct knfsd_fh *fh_handle)
{
return nfsd4_encode_opaque(xdr, fh_handle->fh_raw, fh_handle->fh_size);
}
@@ -3145,6 +3145,7 @@ struct nfsd4_fattr_args {
struct svc_fh *fhp;
struct svc_export *exp;
struct dentry *dentry;
+ struct knfsd_fh fhandle;
struct kstat stat;
struct kstatfs statfs;
struct nfs4_acl *acl;
@@ -3389,7 +3390,7 @@ static __be32 nfsd4_encode_fattr4_homogeneous(struct xdr_stream *xdr,
static __be32 nfsd4_encode_fattr4_filehandle(struct xdr_stream *xdr,
const struct nfsd4_fattr_args *args)
{
- return nfsd4_encode_nfs_fh4(xdr, &args->fhp->fh_handle);
+ return nfsd4_encode_nfs_fh4(xdr, &args->fhandle);
}
static __be32 nfsd4_encode_fattr4_fileid(struct xdr_stream *xdr,
@@ -4002,19 +4003,24 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
if (err)
goto out_nfserr;
}
- if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) &&
- !fhp) {
- tempfh = kmalloc_obj(struct svc_fh);
- status = nfserr_jukebox;
- if (!tempfh)
- goto out;
- fh_init(tempfh, NFS4_FHSIZE);
- status = fh_compose(tempfh, exp, dentry, NULL);
- if (status)
- goto out;
- args.fhp = tempfh;
- } else
- args.fhp = fhp;
+
+ args.fhp = fhp;
+ if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID))) {
+ if (!args.fhp) {
+ tempfh = kmalloc_obj(struct svc_fh);
+ status = nfserr_jukebox;
+ if (!tempfh)
+ goto out;
+ fh_init(tempfh, NFS4_FHSIZE);
+ status = fh_compose(tempfh, exp, dentry, NULL);
+ if (status)
+ goto out;
+ args.fhp = tempfh;
+ }
+ if (args.fhp)
+ fh_copy_shallow(&args.fhandle, &args.fhp->fh_handle);
+ }
+
if (attrmask[0] & (FATTR4_WORD0_CASE_INSENSITIVE |
FATTR4_WORD0_CASE_PRESERVING)) {
/*
--
2.54.0