NFSD: Update XDR encoders in NFSv4 callback client
Clean up. Remove old-style NFSv4 XDR macros in favor of the style now used in fs/nfs/nfs4xdr.c. These were forgotten during the recent nfs4xdr.c rewrite. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Tested-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
3460f29a27
commit
a033db487e
1 changed files with 177 additions and 76 deletions
|
@ -50,11 +50,6 @@ enum {
|
||||||
NFSPROC4_CLNT_CB_SEQUENCE,
|
NFSPROC4_CLNT_CB_SEQUENCE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nfs_cb_opnum4 {
|
|
||||||
OP_CB_RECALL = 4,
|
|
||||||
OP_CB_SEQUENCE = 11,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NFS4_MAXTAGLEN 20
|
#define NFS4_MAXTAGLEN 20
|
||||||
|
|
||||||
#define NFS4_enc_cb_null_sz 0
|
#define NFS4_enc_cb_null_sz 0
|
||||||
|
@ -79,30 +74,6 @@ enum nfs_cb_opnum4 {
|
||||||
cb_sequence_dec_sz + \
|
cb_sequence_dec_sz + \
|
||||||
op_dec_sz)
|
op_dec_sz)
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic encode routines from fs/nfs/nfs4xdr.c
|
|
||||||
*/
|
|
||||||
static inline __be32 *
|
|
||||||
xdr_writemem(__be32 *p, const void *ptr, int nbytes)
|
|
||||||
{
|
|
||||||
int tmp = XDR_QUADLEN(nbytes);
|
|
||||||
if (!tmp)
|
|
||||||
return p;
|
|
||||||
p[tmp-1] = 0;
|
|
||||||
memcpy(p, ptr, nbytes);
|
|
||||||
return p + tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WRITE32(n) *p++ = htonl(n)
|
|
||||||
#define WRITEMEM(ptr,nbytes) do { \
|
|
||||||
p = xdr_writemem(p, ptr, nbytes); \
|
|
||||||
} while (0)
|
|
||||||
#define RESERVE_SPACE(nbytes) do { \
|
|
||||||
p = xdr_reserve_space(xdr, nbytes); \
|
|
||||||
if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \
|
|
||||||
BUG_ON(!p); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic decode routines from fs/nfs/nfs4xdr.c
|
* Generic decode routines from fs/nfs/nfs4xdr.c
|
||||||
*/
|
*/
|
||||||
|
@ -197,102 +168,232 @@ nfs_cb_stat_to_errno(int stat)
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __be32 *xdr_encode_empty_array(__be32 *p)
|
||||||
|
{
|
||||||
|
*p++ = xdr_zero;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XDR encode
|
* Encode/decode NFSv4 CB basic data types
|
||||||
|
*
|
||||||
|
* Basic NFSv4 callback data types are defined in section 15 of RFC
|
||||||
|
* 3530: "Network File System (NFS) version 4 Protocol" and section
|
||||||
|
* 20 of RFC 5661: "Network File System (NFS) Version 4 Minor Version
|
||||||
|
* 1 Protocol"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
/*
|
||||||
encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
|
* nfs_cb_opnum4
|
||||||
|
*
|
||||||
|
* enum nfs_cb_opnum4 {
|
||||||
|
* OP_CB_GETATTR = 3,
|
||||||
|
* ...
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
enum nfs_cb_opnum4 {
|
||||||
|
OP_CB_GETATTR = 3,
|
||||||
|
OP_CB_RECALL = 4,
|
||||||
|
OP_CB_LAYOUTRECALL = 5,
|
||||||
|
OP_CB_NOTIFY = 6,
|
||||||
|
OP_CB_PUSH_DELEG = 7,
|
||||||
|
OP_CB_RECALL_ANY = 8,
|
||||||
|
OP_CB_RECALLABLE_OBJ_AVAIL = 9,
|
||||||
|
OP_CB_RECALL_SLOT = 10,
|
||||||
|
OP_CB_SEQUENCE = 11,
|
||||||
|
OP_CB_WANTS_CANCELLED = 12,
|
||||||
|
OP_CB_NOTIFY_LOCK = 13,
|
||||||
|
OP_CB_NOTIFY_DEVICEID = 14,
|
||||||
|
OP_CB_ILLEGAL = 10044
|
||||||
|
};
|
||||||
|
|
||||||
|
static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op)
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
|
|
||||||
RESERVE_SPACE(sizeof(stateid_t));
|
p = xdr_reserve_space(xdr, 4);
|
||||||
WRITE32(sid->si_generation);
|
*p = cpu_to_be32(op);
|
||||||
WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/*
|
||||||
encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
|
* nfs_fh4
|
||||||
|
*
|
||||||
|
* typedef opaque nfs_fh4<NFS4_FHSIZE>;
|
||||||
|
*/
|
||||||
|
static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh)
|
||||||
|
{
|
||||||
|
u32 length = fh->fh_size;
|
||||||
|
__be32 *p;
|
||||||
|
|
||||||
|
BUG_ON(length > NFS4_FHSIZE);
|
||||||
|
p = xdr_reserve_space(xdr, 4 + length);
|
||||||
|
xdr_encode_opaque(p, &fh->fh_base, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stateid4
|
||||||
|
*
|
||||||
|
* struct stateid4 {
|
||||||
|
* uint32_t seqid;
|
||||||
|
* opaque other[12];
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
static void encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid)
|
||||||
|
{
|
||||||
|
__be32 *p;
|
||||||
|
|
||||||
|
p = xdr_reserve_space(xdr, NFS4_STATEID_SIZE);
|
||||||
|
*p++ = cpu_to_be32(sid->si_generation);
|
||||||
|
xdr_encode_opaque_fixed(p, &sid->si_opaque, NFS4_STATEID_OTHER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sessionid4
|
||||||
|
*
|
||||||
|
* typedef opaque sessionid4[NFS4_SESSIONID_SIZE];
|
||||||
|
*/
|
||||||
|
static void encode_sessionid4(struct xdr_stream *xdr,
|
||||||
|
const struct nfsd4_session *session)
|
||||||
|
{
|
||||||
|
__be32 *p;
|
||||||
|
|
||||||
|
p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN);
|
||||||
|
xdr_encode_opaque_fixed(p, session->se_sessionid.data,
|
||||||
|
NFS4_MAX_SESSIONID_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CB_COMPOUND4args
|
||||||
|
*
|
||||||
|
* struct CB_COMPOUND4args {
|
||||||
|
* utf8str_cs tag;
|
||||||
|
* uint32_t minorversion;
|
||||||
|
* uint32_t callback_ident;
|
||||||
|
* nfs_cb_argop4 argarray<>;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
static void encode_cb_compound4args(struct xdr_stream *xdr,
|
||||||
|
struct nfs4_cb_compound_hdr *hdr)
|
||||||
{
|
{
|
||||||
__be32 * p;
|
__be32 * p;
|
||||||
|
|
||||||
RESERVE_SPACE(16);
|
p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
|
||||||
WRITE32(0); /* tag length is always 0 */
|
p = xdr_encode_empty_array(p); /* empty tag */
|
||||||
WRITE32(hdr->minorversion);
|
*p++ = cpu_to_be32(hdr->minorversion);
|
||||||
WRITE32(hdr->ident);
|
*p++ = cpu_to_be32(hdr->ident);
|
||||||
|
|
||||||
hdr->nops_p = p;
|
hdr->nops_p = p;
|
||||||
WRITE32(hdr->nops);
|
*p = cpu_to_be32(hdr->nops); /* argarray element count */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update argarray element count
|
||||||
|
*/
|
||||||
static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr)
|
static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr)
|
||||||
{
|
{
|
||||||
*hdr->nops_p = htonl(hdr->nops);
|
BUG_ON(hdr->nops > NFS4_MAX_BACK_CHANNEL_OPS);
|
||||||
|
*hdr->nops_p = cpu_to_be32(hdr->nops);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/*
|
||||||
encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp,
|
* CB_RECALL4args
|
||||||
struct nfs4_cb_compound_hdr *hdr)
|
*
|
||||||
|
* struct CB_RECALL4args {
|
||||||
|
* stateid4 stateid;
|
||||||
|
* bool truncate;
|
||||||
|
* nfs_fh4 fh;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
static void encode_cb_recall4args(struct xdr_stream *xdr,
|
||||||
|
const struct nfs4_delegation *dp,
|
||||||
|
struct nfs4_cb_compound_hdr *hdr)
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
int len = dp->dl_fh.fh_size;
|
|
||||||
|
|
||||||
RESERVE_SPACE(4);
|
encode_nfs_cb_opnum4(xdr, OP_CB_RECALL);
|
||||||
WRITE32(OP_CB_RECALL);
|
encode_stateid4(xdr, &dp->dl_stateid);
|
||||||
encode_stateid(xdr, &dp->dl_stateid);
|
|
||||||
RESERVE_SPACE(8 + (XDR_QUADLEN(len) << 2));
|
p = xdr_reserve_space(xdr, 4);
|
||||||
WRITE32(0); /* truncate optimization not implemented */
|
*p++ = xdr_zero; /* truncate */
|
||||||
WRITE32(len);
|
|
||||||
WRITEMEM(&dp->dl_fh.fh_base, len);
|
encode_nfs_fh4(xdr, &dp->dl_fh);
|
||||||
|
|
||||||
hdr->nops++;
|
hdr->nops++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/*
|
||||||
encode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb,
|
* CB_SEQUENCE4args
|
||||||
struct nfs4_cb_compound_hdr *hdr)
|
*
|
||||||
|
* struct CB_SEQUENCE4args {
|
||||||
|
* sessionid4 csa_sessionid;
|
||||||
|
* sequenceid4 csa_sequenceid;
|
||||||
|
* slotid4 csa_slotid;
|
||||||
|
* slotid4 csa_highest_slotid;
|
||||||
|
* bool csa_cachethis;
|
||||||
|
* referring_call_list4 csa_referring_call_lists<>;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
static void encode_cb_sequence4args(struct xdr_stream *xdr,
|
||||||
|
const struct nfsd4_callback *cb,
|
||||||
|
struct nfs4_cb_compound_hdr *hdr)
|
||||||
{
|
{
|
||||||
|
struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
struct nfsd4_session *ses = cb->cb_clp->cl_cb_session;
|
|
||||||
|
|
||||||
if (hdr->minorversion == 0)
|
if (hdr->minorversion == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RESERVE_SPACE(1 + NFS4_MAX_SESSIONID_LEN + 20);
|
encode_nfs_cb_opnum4(xdr, OP_CB_SEQUENCE);
|
||||||
|
encode_sessionid4(xdr, session);
|
||||||
|
|
||||||
|
p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4 + 4);
|
||||||
|
*p++ = cpu_to_be32(session->se_cb_seq_nr); /* csa_sequenceid */
|
||||||
|
*p++ = xdr_zero; /* csa_slotid */
|
||||||
|
*p++ = xdr_zero; /* csa_highest_slotid */
|
||||||
|
*p++ = xdr_zero; /* csa_cachethis */
|
||||||
|
xdr_encode_empty_array(p); /* csa_referring_call_lists */
|
||||||
|
|
||||||
WRITE32(OP_CB_SEQUENCE);
|
|
||||||
WRITEMEM(ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN);
|
|
||||||
WRITE32(ses->se_cb_seq_nr);
|
|
||||||
WRITE32(0); /* slotid, always 0 */
|
|
||||||
WRITE32(0); /* highest slotid always 0 */
|
|
||||||
WRITE32(0); /* cachethis always 0 */
|
|
||||||
WRITE32(0); /* FIXME: support referring_call_lists */
|
|
||||||
hdr->nops++;
|
hdr->nops++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/*
|
||||||
nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p)
|
* NFSv4.0 and NFSv4.1 XDR encode functions
|
||||||
|
*
|
||||||
|
* NFSv4.0 callback argument types are defined in section 15 of RFC
|
||||||
|
* 3530: "Network File System (NFS) version 4 Protocol" and section 20
|
||||||
|
* of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1
|
||||||
|
* Protocol".
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB: Without this zero space reservation, callbacks over krb5p fail
|
||||||
|
*/
|
||||||
|
static int nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused)
|
||||||
{
|
{
|
||||||
struct xdr_stream xdrs, *xdr = &xdrs;
|
struct xdr_stream xdrs, *xdr = &xdrs;
|
||||||
|
|
||||||
xdr_init_encode(&xdrs, &req->rq_snd_buf, p);
|
xdr_init_encode(&xdrs, &req->rq_snd_buf, p);
|
||||||
RESERVE_SPACE(0);
|
xdr_reserve_space(xdr, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/*
|
||||||
nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p,
|
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
|
||||||
struct nfsd4_callback *cb)
|
*/
|
||||||
|
static int nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p,
|
||||||
|
const struct nfsd4_callback *cb)
|
||||||
{
|
{
|
||||||
struct xdr_stream xdr;
|
struct xdr_stream xdr;
|
||||||
struct nfs4_delegation *args = cb->cb_op;
|
const struct nfs4_delegation *args = cb->cb_op;
|
||||||
struct nfs4_cb_compound_hdr hdr = {
|
struct nfs4_cb_compound_hdr hdr = {
|
||||||
.ident = cb->cb_clp->cl_cb_ident,
|
.ident = cb->cb_clp->cl_cb_ident,
|
||||||
.minorversion = cb->cb_minorversion,
|
.minorversion = cb->cb_minorversion,
|
||||||
};
|
};
|
||||||
|
|
||||||
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
|
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
|
||||||
encode_cb_compound_hdr(&xdr, &hdr);
|
encode_cb_compound4args(&xdr, &hdr);
|
||||||
encode_cb_sequence(&xdr, cb, &hdr);
|
encode_cb_sequence4args(&xdr, cb, &hdr);
|
||||||
encode_cb_recall(&xdr, args, &hdr);
|
encode_cb_recall4args(&xdr, args, &hdr);
|
||||||
encode_cb_nops(&hdr);
|
encode_cb_nops(&hdr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue