Commit 5178a125 authored by Olga Kornievskaia's avatar Olga Kornievskaia Committed by Anna Schumaker
Browse files

NFS CB_OFFLOAD xdr

parent 46483c2e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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);
+7 −0
Original line number Diff line number Diff line
@@ -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 */
+79 −1
Original line number Diff line number Diff line
@@ -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 */
};

/*