コード例 #1
0
/*
 * Decode, process and encode a COMPOUND
 */
static int nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
{
	struct cb_compound_hdr_arg hdr_arg;
	struct cb_compound_hdr_res hdr_res;
	struct xdr_stream xdr_in, xdr_out;
	uint32_t *p;
	unsigned int status;
	unsigned int nops = 1;

	dprintk("%s: start\n", __FUNCTION__);

	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);

	p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

	decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	hdr_res.nops = NULL;
	encode_compound_hdr_res(&xdr_out, &hdr_res);

	for (;;) {
		status = process_op(rqstp, &xdr_in, argp, &xdr_out, resp);
		if (status != 0)
			break;
		if (nops == hdr_arg.nops)
			break;
		nops++;
	}
	*hdr_res.status = status;
	*hdr_res.nops = htonl(nops);
	dprintk("%s: done, status = %u\n", __FUNCTION__, status);
	return rpc_success;
}
コード例 #2
0
static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
{
	struct cb_compound_hdr_arg hdr_arg = { 0 };
	struct cb_compound_hdr_res hdr_res = { NULL };
	struct xdr_stream xdr_in, xdr_out;
	__be32 *p, status;
	struct cb_process_state cps = {
		.drc_status = 0,
		.clp = NULL,
		.slotid = NFS4_NO_SLOT,
		.net = rqstp->rq_xprt->xpt_net,
	};
	unsigned int nops = 0;

	dprintk("%s: start\n", __func__);

	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);

	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	if (status == __constant_htonl(NFS4ERR_RESOURCE))
		return rpc_garbage_args;

	if (hdr_arg.minorversion == 0) {
		cps.clp = nfs4_find_client_ident(rqstp->rq_xprt->xpt_net, hdr_arg.cb_ident);
		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
			return rpc_drop_reply;
	}

	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
		return rpc_system_err;

	while (status == 0 && nops != hdr_arg.nops) {
		status = process_op(hdr_arg.minorversion, nops, rqstp,
				    &xdr_in, argp, &xdr_out, resp, &cps);
		nops++;
	}

	if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
		status = htonl(NFS4ERR_RESOURCE);
		nops--;
	}

	*hdr_res.status = status;
	*hdr_res.nops = htonl(nops);
	nfs4_cb_free_slot(&cps);
	nfs_put_client(cps.clp);
	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
	return rpc_success;
}

static struct callback_op callback_ops[] = {
	[0] = {
		.res_maxsize = CB_OP_HDR_RES_MAXSZ,
	},
コード例 #3
0
/*
 * Unmarshall layout and store it in pnfslay.
 */
struct pnfs_layout_segment *
objlayout_alloc_lseg(struct pnfs_layout_hdr *pnfslay,
		     struct nfs4_layoutget_res *lgr,
		     gfp_t gfp_flags)
{
	int status = -ENOMEM;
	struct xdr_stream stream;
	struct xdr_buf buf = {
		.pages =  lgr->layoutp->pages,
		.page_len =  lgr->layoutp->len,
		.buflen =  lgr->layoutp->len,
		.len = lgr->layoutp->len,
	};
	struct page *scratch;
	struct pnfs_layout_segment *lseg;

	dprintk("%s: Begin pnfslay %p\n", __func__, pnfslay);

	scratch = alloc_page(gfp_flags);
	if (!scratch)
		goto err_nofree;

	xdr_init_decode(&stream, &buf, NULL);
	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);

	status = objio_alloc_lseg(&lseg, pnfslay, &lgr->range, &stream, gfp_flags);
	if (unlikely(status)) {
		dprintk("%s: objio_alloc_lseg Return err %d\n", __func__,
			status);
		goto err;
	}

	__free_page(scratch);

	dprintk("%s: Return %p\n", __func__, lseg);
	return lseg;

err:
	__free_page(scratch);
err_nofree:
	dprintk("%s: Err Return=>%d\n", __func__, status);
	return ERR_PTR(status);
}

/*
 * Free a layout segement
 */
void
objlayout_free_lseg(struct pnfs_layout_segment *lseg)
{
	dprintk("%s: freeing layout segment %p\n", __func__, lseg);

	if (unlikely(!lseg))
		return;

	objio_free_lseg(lseg);
}
コード例 #4
0
ファイル: nfs4callback.c プロジェクト: Tigrouzen/k1099
static int
nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p)
{
	struct xdr_stream xdr;
	struct nfs4_cb_compound_hdr hdr;
	int status;

	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
	status = decode_cb_compound_hdr(&xdr, &hdr);
	if (status)
		goto out;
	status = decode_cb_op_hdr(&xdr, OP_CB_RECALL);
out:
	return status;
}
コード例 #5
0
/*
 * Decode, process and encode a COMPOUND
 */
static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
{
	struct cb_compound_hdr_arg hdr_arg = { 0 };
	struct cb_compound_hdr_res hdr_res = { NULL };
	struct xdr_stream xdr_in, xdr_out;
	__be32 *p;
	__be32 status, drc_status = 0;
	unsigned int nops = 0;

	dprintk("%s: start\n", __func__);

	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);

	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	if (status == __constant_htonl(NFS4ERR_RESOURCE))
		return rpc_garbage_args;

	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
		return rpc_system_err;

	while (status == 0 && nops != hdr_arg.nops) {
		status = process_op(hdr_arg.minorversion, nops, rqstp,
				    &xdr_in, argp, &xdr_out, resp, &drc_status);
		nops++;
	}

	/* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
	* resource error in cb_compound status without returning op */
	if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
		status = htonl(NFS4ERR_RESOURCE);
		nops--;
	}

	*hdr_res.status = status;
	*hdr_res.nops = htonl(nops);
	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
	return rpc_success;
}
コード例 #6
0
ファイル: callback_xdr.c プロジェクト: AshishNamdev/linux
/*
 * Decode, process and encode a COMPOUND
 */
static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
{
	struct cb_compound_hdr_arg hdr_arg = { 0 };
	struct cb_compound_hdr_res hdr_res = { NULL };
	struct xdr_stream xdr_in, xdr_out;
	__be32 *p, status;
	struct cb_process_state cps = {
		.drc_status = 0,
		.clp = NULL,
		.net = SVC_NET(rqstp),
	};
	unsigned int nops = 0;

	dprintk("%s: start\n", __func__);

	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);

	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	if (status == htonl(NFS4ERR_RESOURCE))
		return rpc_garbage_args;

	if (hdr_arg.minorversion == 0) {
		cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
			goto out_invalidcred;
	}

	cps.minorversion = hdr_arg.minorversion;
	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
		return rpc_system_err;

	while (status == 0 && nops != hdr_arg.nops) {
		status = process_op(nops, rqstp, &xdr_in,
				    argp, &xdr_out, resp, &cps);
		nops++;
	}

	/* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
	* resource error in cb_compound status without returning op */
	if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
		status = htonl(NFS4ERR_RESOURCE);
		nops--;
	}

	*hdr_res.status = status;
	*hdr_res.nops = htonl(nops);
	nfs4_cb_free_slot(&cps);
	nfs_put_client(cps.clp);
	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
	return rpc_success;

out_invalidcred:
	pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
	return rpc_autherr_badcred;
}

/*
 * Define NFS4 callback COMPOUND ops.
 */
static struct callback_op callback_ops[] = {
	[0] = {
		.res_maxsize = CB_OP_HDR_RES_MAXSZ,
	},