nfsd: add callback encoding and decoding linkages for CB_NOTIFY

Add routines for encoding and decoding CB_NOTIFY messages. These call
into the code generated by xdrgen to do the actual encoding and
decoding.

For now, the encoder is a stub. Later patches will flesh out the payload
encoding.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260616-dir-deleg-v7-7-6cbc7eac0ade@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
Jeff Layton
2026-06-16 07:58:50 -04:00
committed by Chuck Lever
parent ee2752a884
commit 04939a5707
6 changed files with 72 additions and 2 deletions

View File

@@ -490,6 +490,7 @@ struct CB_NOTIFY4args {
nfs_fh4 cna_fh;
notify4 cna_changes<>;
};
pragma public CB_NOTIFY4args;
struct CB_NOTIFY4res {
nfsstat4 cnr_status;

View File

@@ -891,6 +891,51 @@ static void encode_stateowner(struct xdr_stream *xdr, struct nfs4_stateowner *so
xdr_encode_opaque(p, so->so_owner.data, so->so_owner.len);
}
static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *req,
struct xdr_stream *xdr,
const void *data)
{
const struct nfsd4_callback *cb = data;
struct nfs4_cb_compound_hdr hdr = {
.ident = 0,
.minorversion = cb->cb_clp->cl_minorversion,
};
struct CB_NOTIFY4args args = { };
WARN_ON_ONCE(hdr.minorversion == 0);
encode_cb_compound4args(xdr, &hdr);
encode_cb_sequence4args(xdr, cb, &hdr);
/*
* FIXME: get stateid and fh from delegation. Inline the cna_changes
* buffer, and zero it.
*/
xdrgen_encode_CB_NOTIFY4args(xdr, &args);
hdr.nops++;
encode_cb_nops(&hdr);
}
static int nfs4_xdr_dec_cb_notify(struct rpc_rqst *rqstp,
struct xdr_stream *xdr,
void *data)
{
struct nfsd4_callback *cb = data;
struct nfs4_cb_compound_hdr hdr;
int status;
status = decode_cb_compound4res(xdr, &hdr);
if (unlikely(status))
return status;
status = decode_cb_sequence4res(xdr, cb);
if (unlikely(status || cb->cb_seq_status))
return status;
return decode_cb_op_status(xdr, OP_CB_NOTIFY, &cb->cb_status);
}
static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req,
struct xdr_stream *xdr,
const void *data)
@@ -1052,6 +1097,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
#ifdef CONFIG_NFSD_PNFS
PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout),
#endif
PROC(CB_NOTIFY, COMPOUND, cb_notify, cb_notify),
PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock),
PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload),
PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any),

View File

@@ -713,7 +713,7 @@ xdrgen_decode_notify4(struct xdr_stream *xdr, struct notify4 *ptr)
return true;
}
static bool __maybe_unused
bool
xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY4args *ptr)
{
if (!xdrgen_decode_stateid4(xdr, &ptr->cna_stateid))
@@ -1135,7 +1135,7 @@ xdrgen_encode_notify4(struct xdr_stream *xdr, const struct notify4 *value)
return true;
}
static bool __maybe_unused
bool
xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_NOTIFY4args *value)
{
if (!xdrgen_encode_stateid4(xdr, &value->cna_stateid))

View File

@@ -32,4 +32,7 @@ bool xdrgen_decode_posixaceperm4(struct xdr_stream *xdr, posixaceperm4 *ptr);
bool xdrgen_encode_posixaceperm4(struct xdr_stream *xdr, const posixaceperm4 value);
bool xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY4args *ptr);
bool xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_NOTIFY4args *value);
#endif /* _LINUX_XDRGEN_NFS4_1_DECL_H */

View File

@@ -190,6 +190,13 @@ struct nfs4_cb_fattr {
u64 ncf_cur_fsize;
};
/*
* FIXME: the current backchannel encoder can't handle a send buffer longer
* than a single page (see bc_malloc/bc_free).
*/
#define NOTIFY4_EVENT_QUEUE_SIZE 3
#define NOTIFY4_PAGE_ARRAY_SIZE 1
/*
* Represents a delegation stateid. The nfs4_client holds references to these
* and they are put when it is being destroyed or when the delegation is
@@ -776,6 +783,7 @@ enum nfsd4_cb_op {
NFSPROC4_CLNT_CB_NOTIFY_LOCK,
NFSPROC4_CLNT_CB_RECALL_ANY,
NFSPROC4_CLNT_CB_GETATTR,
NFSPROC4_CLNT_CB_NOTIFY,
};
/* Returns true iff a is later than b: */

View File

@@ -33,6 +33,18 @@
cb_sequence_dec_sz + \
op_dec_sz)
#define NFS4_enc_cb_notify_sz (cb_compound_enc_hdr_sz + \
cb_sequence_enc_sz + \
1 + enc_stateid_sz + \
enc_nfs4_fh_sz + \
1 + \
NOTIFY4_EVENT_QUEUE_SIZE * \
(2 + (NFS4_OPAQUE_LIMIT >> 2)))
#define NFS4_dec_cb_notify_sz (cb_compound_dec_hdr_sz + \
cb_sequence_dec_sz + \
op_dec_sz)
#define NFS4_enc_cb_notify_lock_sz (cb_compound_enc_hdr_sz + \
cb_sequence_enc_sz + \
2 + 1 + \