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.
26 #include <rpc/types.h>
28 #include <sys/types.h>
31 #include <rpc/rpc_rdma.h>
35 uint_t flags
; /* controls setting for rdma xdr */
37 caddr_t inline_buf
; /* temporary buffer for xdr inlining */
38 int inline_len
; /* inline buffer length */
39 uint_t xp_reply_chunk_len
;
40 uint_t xp_reply_chunk_len_alt
;
45 x_putint32_t(XDR
*xdrs
, int32_t *ip
)
47 xdrs
->x_handy
+= BYTES_PER_XDR_UNIT
;
53 x_putbytes(XDR
*xdrs
, char *bp
, int len
)
55 struct private *xdrp
= (struct private *)xdrs
->x_private
;
58 * min_chunk = 0, means that the stream of bytes, to estimate size of,
59 * contains no chunks to seperate out. See xdrrdma_putbytes()
61 if (len
< xdrp
->min_chunk
|| !(xdrp
->flags
& XDR_RDMA_CHUNK
)) {
66 * Chunk item. No impact on xdr size.
76 return (xdrs
->x_handy
);
81 x_setpostn(XDR
*xdrs
, uint_t pos
)
83 /* This is not allowed */
89 x_control(XDR
*xdrs
, int request
, void *info
)
93 rdma_chunkinfo_t
*rcip
= NULL
;
94 rdma_chunkinfo_lengths_t
*rcilp
= NULL
;
95 struct private *xdrp
= (struct private *)xdrs
->x_private
;
98 case XDR_RDMA_SET_FLAGS
:
100 * Set the flags provided in the *info in xp_flags for rdma xdr
103 int32p
= (int32_t *)info
;
104 in_flags
= (uint_t
)(*int32p
);
106 xdrp
->flags
= in_flags
;
109 case XDR_RDMA_GET_FLAGS
:
111 * Get the flags provided in xp_flags return through *info
113 int32p
= (int32_t *)info
;
115 *int32p
= (int32_t)xdrp
->flags
;
118 case XDR_RDMA_GET_CHUNK_LEN
:
119 rcilp
= (rdma_chunkinfo_lengths_t
*)info
;
120 rcilp
->rcil_len
= xdrp
->xp_reply_chunk_len
;
121 rcilp
->rcil_len_alt
= xdrp
->xp_reply_chunk_len_alt
;
125 case XDR_RDMA_ADD_CHUNK
:
126 rcip
= (rdma_chunkinfo_t
*)info
;
128 switch (rcip
->rci_type
) {
129 case RCI_WRITE_UIO_CHUNK
:
130 xdrp
->xp_reply_chunk_len_alt
+= rcip
->rci_len
;
133 case RCI_WRITE_ADDR_CHUNK
:
134 xdrp
->xp_reply_chunk_len_alt
+= rcip
->rci_len
;
137 case RCI_REPLY_CHUNK
:
138 xdrp
->xp_reply_chunk_len
+= rcip
->rci_len
;
149 static rpc_inline_t
*
150 x_inline(XDR
*xdrs
, int len
)
152 struct private *xdrp
= (struct private *)xdrs
->x_private
;
157 if (xdrs
->x_op
!= XDR_ENCODE
) {
160 if (len
>= xdrp
->min_chunk
) {
163 if (len
<= xdrp
->inline_len
) {
164 /* inline_buf was already allocated, just reuse it */
165 xdrs
->x_handy
+= len
;
166 return ((rpc_inline_t
*)xdrp
->inline_buf
);
168 /* Free the earlier space and allocate new area */
169 if (xdrp
->inline_buf
)
170 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
171 if ((xdrp
->inline_buf
= (caddr_t
)mem_alloc(len
)) == NULL
) {
172 xdrp
->inline_len
= 0;
175 xdrp
->inline_len
= len
;
176 xdrs
->x_handy
+= len
;
177 return ((rpc_inline_t
*)xdrp
->inline_buf
);
184 /* Always return FALSE/NULL, as the case may be */
191 struct private *xdrp
= (struct private *)xdrs
->x_private
;
195 if (xdrp
->inline_buf
)
196 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
197 mem_free(xdrp
, sizeof (struct private));
198 xdrs
->x_private
= NULL
;
204 xdrrdma_common(XDR
*xdrs
, int min_chunk
)
206 struct private *xdrp
;
208 xdrs
->x_ops
= xdrrdma_xops();
209 xdrs
->x_op
= XDR_ENCODE
;
212 xdrs
->x_private
= kmem_zalloc(sizeof (struct private), KM_SLEEP
);
213 xdrp
= (struct private *)xdrs
->x_private
;
214 xdrp
->min_chunk
= min_chunk
;
216 if (xdrp
->min_chunk
!= 0)
217 xdrp
->flags
|= XDR_RDMA_CHUNK
;
219 xdrp
->xp_reply_chunk_len
= 0;
220 xdrp
->xp_reply_chunk_len_alt
= 0;
226 xdrrdma_sizeof(xdrproc_t func
, void *data
, int min_chunk
,
227 uint_t
*reply_size
, uint_t
*reply_size_alt
)
232 struct private *xdrp
;
235 (void) xdrrdma_common(&x
, min_chunk
);
237 stat
= func(&x
, data
);
238 xdrp
= (struct private *)x
.x_private
;
240 if (reply_size
!= NULL
)
241 *reply_size
= xdrp
->xp_reply_chunk_len
;
242 if (reply_size_alt
!= NULL
)
243 *reply_size_alt
= xdrp
->xp_reply_chunk_len_alt
;
244 if (xdrp
->inline_buf
)
245 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
246 mem_free(xdrp
, sizeof (struct private));
248 return (stat
== TRUE
? (unsigned int)x
.x_handy
: 0);
252 xdrrdma_authsize(AUTH
*auth
, struct cred
*cred
, int min_chunk
)
257 struct private *xdrp
;
260 (void) xdrrdma_common(&x
, min_chunk
);
262 stat
= AUTH_MARSHALL(auth
, &x
, cred
);
263 xdrp
= (struct private *)x
.x_private
;
265 if (xdrp
->inline_buf
)
266 mem_free(xdrp
->inline_buf
, xdrp
->inline_len
);
267 mem_free(xdrp
, sizeof (struct private));
269 return (stat
== TRUE
? (unsigned int)x
.x_handy
: 0);
275 static struct xdr_ops ops
;
277 /* to stop ANSI-C compiler from complaining */
278 typedef bool_t (* dummyfunc1
)(XDR
*, long *);
279 typedef bool_t (* dummyfunc2
)(XDR
*, caddr_t
, int);
280 typedef bool_t (* dummyfunc3
)(XDR
*, int32_t *);
282 ops
.x_putbytes
= x_putbytes
;
283 ops
.x_inline
= x_inline
;
284 ops
.x_getpostn
= x_getpostn
;
285 ops
.x_setpostn
= x_setpostn
;
286 ops
.x_destroy
= x_destroy
;
287 ops
.x_control
= x_control
;
289 #if defined(_LP64) || defined(_KERNEL)
290 ops
.x_getint32
= (dummyfunc3
)harmless
;
291 ops
.x_putint32
= x_putint32_t
;
294 /* the other harmless ones */
295 ops
.x_getbytes
= (dummyfunc2
)harmless
;