4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * Copyright 2017 RackTop Systems.
28 #include <rpc/types.h>
30 #include <sys/types.h>
33 #include <rpc/rpc_rdma.h>
37 uint_t flags
; /* controls setting for rdma xdr */
39 caddr_t inline_buf
; /* temporary buffer for xdr inlining */
40 int inline_len
; /* inline buffer length */
41 uint_t xp_reply_chunk_len
;
42 uint_t xp_reply_chunk_len_alt
;
47 x_putint32_t(XDR
*xdrs
, int32_t *ip
)
49 xdrs
->x_handy
+= BYTES_PER_XDR_UNIT
;
55 x_putbytes(XDR
*xdrs
, char *bp
, int len
)
57 struct private *xdrp
= (struct private *)xdrs
->x_private
;
60 * min_chunk = 0, means that the stream of bytes, to estimate size of,
61 * contains no chunks to seperate out. See xdrrdma_putbytes()
63 if (len
< xdrp
->min_chunk
|| !(xdrp
->flags
& XDR_RDMA_CHUNK
)) {
68 * Chunk item. No impact on xdr size.
78 return (xdrs
->x_handy
);
83 x_setpostn(XDR
*xdrs
, uint_t pos
)
85 /* This is not allowed */
91 x_control(XDR
*xdrs
, int request
, void *info
)
95 rdma_chunkinfo_t
*rcip
= NULL
;
96 rdma_chunkinfo_lengths_t
*rcilp
= NULL
;
97 struct private *xdrp
= (struct private *)xdrs
->x_private
;
100 case XDR_RDMA_SET_FLAGS
:
102 * Set the flags provided in the *info in xp_flags for rdma xdr
105 int32p
= (int32_t *)info
;
106 in_flags
= (uint_t
)(*int32p
);
108 xdrp
->flags
= in_flags
;
111 case XDR_RDMA_GET_FLAGS
:
113 * Get the flags provided in xp_flags return through *info
115 int32p
= (int32_t *)info
;
117 *int32p
= (int32_t)xdrp
->flags
;
120 case XDR_RDMA_GET_CHUNK_LEN
:
121 rcilp
= (rdma_chunkinfo_lengths_t
*)info
;
122 rcilp
->rcil_len
= xdrp
->xp_reply_chunk_len
;
123 rcilp
->rcil_len_alt
= xdrp
->xp_reply_chunk_len_alt
;
127 case XDR_RDMA_ADD_CHUNK
:
128 rcip
= (rdma_chunkinfo_t
*)info
;
130 switch (rcip
->rci_type
) {
131 case RCI_WRITE_UIO_CHUNK
:
132 xdrp
->xp_reply_chunk_len_alt
+= rcip
->rci_len
;
135 case RCI_WRITE_ADDR_CHUNK
:
136 xdrp
->xp_reply_chunk_len_alt
+= rcip
->rci_len
;
139 case RCI_REPLY_CHUNK
:
140 xdrp
->xp_reply_chunk_len
+= rcip
->rci_len
;
151 static rpc_inline_t
*
152 x_inline(XDR
*xdrs
, int len
)
154 struct private *xdrp
= (struct private *)xdrs
->x_private
;
159 if (xdrs
->x_op
!= XDR_ENCODE
) {
162 if (len
>= xdrp
->min_chunk
) {
165 if (len
<= xdrp
->inline_len
) {
166 /* inline_buf was already allocated, just reuse it */
167 xdrs
->x_handy
+= len
;
168 return ((rpc_inline_t
*)xdrp
->inline_buf
);
170 /* Free the earlier space and allocate new area */
171 if (xdrp
->inline_buf
)
172 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
173 if ((xdrp
->inline_buf
= (caddr_t
)mem_alloc(len
)) == NULL
) {
174 xdrp
->inline_len
= 0;
177 xdrp
->inline_len
= len
;
178 xdrs
->x_handy
+= len
;
179 return ((rpc_inline_t
*)xdrp
->inline_buf
);
186 /* Always return FALSE/NULL, as the case may be */
193 struct private *xdrp
= (struct private *)xdrs
->x_private
;
197 if (xdrp
->inline_buf
)
198 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
199 mem_free(xdrp
, sizeof (struct private));
200 xdrs
->x_private
= NULL
;
206 xdrrdma_common(XDR
*xdrs
, int min_chunk
)
208 struct private *xdrp
;
210 xdrs
->x_ops
= xdrrdma_xops();
211 xdrs
->x_op
= XDR_ENCODE
;
214 xdrs
->x_private
= kmem_zalloc(sizeof (struct private), KM_SLEEP
);
215 xdrp
= (struct private *)xdrs
->x_private
;
216 xdrp
->min_chunk
= min_chunk
;
218 if (xdrp
->min_chunk
!= 0)
219 xdrp
->flags
|= XDR_RDMA_CHUNK
;
221 xdrp
->xp_reply_chunk_len
= 0;
222 xdrp
->xp_reply_chunk_len_alt
= 0;
228 xdrrdma_sizeof(xdrproc_t func
, void *data
, int min_chunk
,
229 uint_t
*reply_size
, uint_t
*reply_size_alt
)
234 struct private *xdrp
;
237 (void) xdrrdma_common(&x
, min_chunk
);
239 stat
= func(&x
, data
);
240 xdrp
= (struct private *)x
.x_private
;
242 if (reply_size
!= NULL
)
243 *reply_size
= xdrp
->xp_reply_chunk_len
;
244 if (reply_size_alt
!= NULL
)
245 *reply_size_alt
= xdrp
->xp_reply_chunk_len_alt
;
246 if (xdrp
->inline_buf
)
247 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
248 mem_free(xdrp
, sizeof (struct private));
250 return (stat
== TRUE
? (unsigned int)x
.x_handy
: 0);
254 xdrrdma_authsize(AUTH
*auth
, struct cred
*cred
, int min_chunk
)
259 struct private *xdrp
;
262 (void) xdrrdma_common(&x
, min_chunk
);
264 stat
= AUTH_MARSHALL(auth
, &x
, cred
);
265 xdrp
= (struct private *)x
.x_private
;
267 if (xdrp
->inline_buf
)
268 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
269 mem_free(xdrp
, sizeof (struct private));
271 return (stat
== TRUE
? (unsigned int)x
.x_handy
: 0);
277 static struct xdr_ops ops
;
279 /* to stop ANSI-C compiler from complaining */
280 typedef bool_t (* dummyfunc1
)(XDR
*, caddr_t
, int);
281 #if defined(_LP64) || defined(_KERNEL)
282 typedef bool_t (* dummyfunc2
)(XDR
*, int32_t *);
285 ops
.x_putbytes
= x_putbytes
;
286 ops
.x_inline
= x_inline
;
287 ops
.x_getpostn
= x_getpostn
;
288 ops
.x_setpostn
= x_setpostn
;
289 ops
.x_destroy
= x_destroy
;
290 ops
.x_control
= x_control
;
292 #if defined(_LP64) || defined(_KERNEL)
293 ops
.x_getint32
= (dummyfunc2
)harmless
;
294 ops
.x_putint32
= x_putint32_t
;
297 /* the other harmless ones */
298 ops
.x_getbytes
= (dummyfunc1
)harmless
;