NFS CB_OFFLOAD xdr

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
Olga Kornievskaia 2018-07-09 15:13:28 -04:00 committed by Anna Schumaker
parent 46483c2ea4
commit 5178a125f6
3 changed files with 98 additions and 1 deletions

View file

@ -184,6 +184,18 @@ struct cb_notify_lock_args {
extern __be32 nfs4_callback_notify_lock(void *argp, void *resp,
struct cb_process_state *cps);
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
struct cb_offloadargs {
struct nfs_fh coa_fh;
nfs4_stateid coa_stateid;
uint32_t error;
uint64_t wr_count;
struct nfs_writeverf wr_writeverf;
};
extern __be32 nfs4_callback_offload(void *args, void *dummy,
struct cb_process_state *cps);
#endif /* CONFIG_NFS_V4_2 */
extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *);
extern __be32 nfs4_callback_getattr(void *argp, void *resp,
struct cb_process_state *cps);

View file

@ -661,3 +661,10 @@ __be32 nfs4_callback_notify_lock(void *argp, void *resp,
return htonl(NFS4_OK);
}
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
__be32 nfs4_callback_offload(void *args, void *dummy,
struct cb_process_state *cps)
{
return 0;
}
#endif /* CONFIG_NFS_V4_2 */

View file

@ -38,6 +38,9 @@
#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#define CB_OP_NOTIFY_LOCK_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
#define CB_OP_OFFLOAD_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#endif /* CONFIG_NFS_V4_2 */
#define NFSDBG_FACILITY NFSDBG_CALLBACK
@ -527,7 +530,72 @@ static __be32 decode_notify_lock_args(struct svc_rqst *rqstp,
}
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
static __be32 decode_write_response(struct xdr_stream *xdr,
struct cb_offloadargs *args)
{
__be32 *p;
/* skip the always zero field */
p = read_buf(xdr, 4);
if (unlikely(!p))
goto out;
p++;
/* decode count, stable_how, verifier */
p = xdr_inline_decode(xdr, 8 + 4);
if (unlikely(!p))
goto out;
p = xdr_decode_hyper(p, &args->wr_count);
args->wr_writeverf.committed = be32_to_cpup(p);
p = xdr_inline_decode(xdr, NFS4_VERIFIER_SIZE);
if (likely(p)) {
memcpy(&args->wr_writeverf.verifier.data[0], p,
NFS4_VERIFIER_SIZE);
return 0;
}
out:
return htonl(NFS4ERR_RESOURCE);
}
static __be32 decode_offload_args(struct svc_rqst *rqstp,
struct xdr_stream *xdr,
void *data)
{
struct cb_offloadargs *args = data;
__be32 *p;
__be32 status;
/* decode fh */
status = decode_fh(xdr, &args->coa_fh);
if (unlikely(status != 0))
return status;
/* decode stateid */
status = decode_stateid(xdr, &args->coa_stateid);
if (unlikely(status != 0))
return status;
/* decode status */
p = read_buf(xdr, 4);
if (unlikely(!p))
goto out;
args->error = ntohl(*p++);
if (!args->error) {
status = decode_write_response(xdr, args);
if (unlikely(status != 0))
return status;
} else {
p = xdr_inline_decode(xdr, 8);
if (unlikely(!p))
goto out;
p = xdr_decode_hyper(p, &args->wr_count);
}
return 0;
out:
return htonl(NFS4ERR_RESOURCE);
}
#endif /* CONFIG_NFS_V4_2 */
static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
{
if (unlikely(xdr_stream_encode_opaque(xdr, str, len) < 0))
@ -773,7 +841,10 @@ preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op)
if (status != htonl(NFS4ERR_OP_ILLEGAL))
return status;
if (op_nr == OP_CB_OFFLOAD)
if (op_nr == OP_CB_OFFLOAD) {
*op = &callback_ops[op_nr];
return htonl(NFS_OK);
} else
return htonl(NFS4ERR_NOTSUPP);
return htonl(NFS4ERR_OP_ILLEGAL);
}
@ -974,6 +1045,13 @@ static struct callback_op callback_ops[] = {
.res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ,
},
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
[OP_CB_OFFLOAD] = {
.process_op = nfs4_callback_offload,
.decode_args = decode_offload_args,
.res_maxsize = CB_OP_OFFLOAD_RES_MAXSZ,
},
#endif /* CONFIG_NFS_V4_2 */
};
/*