2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * xdr_rx.c. XDR using RX.
14 #include <afsconfig.h>
15 #include <afs/param.h>
18 # include "afs/sysincludes.h"
22 # ifdef AFS_LINUX20_ENV
23 # include "h/socket.h"
25 # include "rpc/types.h"
27 # ifdef AFS_LINUX22_ENV
29 # define quad_t __quad_t
30 # define u_quad_t __u_quad_t
33 # include "netinet/in.h"
34 # endif /* !UKERNEL */
42 /* Static prototypes */
43 static bool_t xdrrx_getint32(XDR *axdrs, afs_int32 * lp);
44 static bool_t xdrrx_putint32(XDR *axdrs, afs_int32 * lp);
45 static bool_t xdrrx_getbytes(XDR *axdrs, caddr_t addr,
47 static bool_t xdrrx_putbytes(XDR *axdrs, caddr_t addr,
49 static afs_int32 *xdrrx_inline(XDR *axdrs, u_int len);
53 * Ops vector for stdio type XDR
55 static struct xdr_ops xdrrx_ops = {
56 #ifndef HAVE_STRUCT_LABEL_SUPPORT
57 /* Windows does not support labeled assigments */
58 xdrrx_getint32, /* deserialize an afs_int32 */
59 xdrrx_putint32, /* serialize an afs_int32 */
60 xdrrx_getbytes, /* deserialize counted bytes */
61 xdrrx_putbytes, /* serialize counted bytes */
62 NULL, /* get offset in the stream: not supported. */
63 NULL, /* set offset in the stream: not supported. */
64 xdrrx_inline, /* prime stream for inline macros */
65 NULL, /* destroy stream */
67 .x_getint32 = xdrrx_getint32, /* deserialize an afs_int32 */
68 .x_putint32 = xdrrx_putint32, /* serialize an afs_int32 */
69 .x_getbytes = xdrrx_getbytes, /* deserialize counted bytes */
70 .x_putbytes = xdrrx_putbytes, /* serialize counted bytes */
71 .x_getpostn = NULL, /* get offset in the stream: not supported. */
72 .x_setpostn = NULL, /* set offset in the stream: not supported. */
73 .x_inline = xdrrx_inline, /* prime stream for inline macros */
74 .x_destroy = NULL, /* destroy stream */
79 * Initialize an rx xdr handle, for a given rx call. op must be XDR_ENCODE or XDR_DECODE.
80 * Call must have been returned by rx_MakeCall or rx_GetCall.
83 xdrrx_create(XDR * xdrs, struct rx_call *call,
87 xdrs->x_ops = &xdrrx_ops;
88 xdrs->x_private = (caddr_t) call;
91 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
92 #define STACK_TO_PIN 2*PAGESIZE /* 8K */
93 int rx_pin_failed = 0;
97 xdrrx_getint32(XDR *axdrs, afs_int32 * lp)
100 XDR * xdrs = (XDR *)axdrs;
101 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
102 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
103 char *saddr = (char *)&l;
104 saddr -= STACK_TO_PIN;
106 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
107 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
108 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
109 * 2K stack we could try to bring the next few stack pages in here before we call the rx
110 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
111 * out between here and calling splnet. So we now pin (and unpin) them instead to
112 * guarantee that they remain there.
114 if (pin(saddr, STACK_TO_PIN)) {
115 /* XXX There's little we can do by continue XXX */
120 if (rx_Read32(call, &l) == sizeof(l)) {
122 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
124 unpin(saddr, STACK_TO_PIN);
128 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
130 unpin(saddr, STACK_TO_PIN);
136 xdrrx_putint32(XDR *axdrs, afs_int32 * lp)
138 afs_int32 code, l = htonl(*lp);
139 XDR * xdrs = (XDR *)axdrs;
140 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
141 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
142 char *saddr = (char *)&code;
143 saddr -= STACK_TO_PIN;
145 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
146 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
147 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
148 * 2K stack we could try to bring the next few stack pages in here before we call the rx
149 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
150 * out between here and calling splnet. So we now pin (and unpin) them instead to
151 * guarantee that they remain there.
153 if (pin(saddr, STACK_TO_PIN)) {
158 code = (rx_Write32(call, &l) == sizeof(l));
159 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
161 unpin(saddr, STACK_TO_PIN);
167 xdrrx_getbytes(XDR *axdrs, caddr_t addr, u_int len)
170 XDR * xdrs = (XDR *)axdrs;
171 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
172 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
173 char *saddr = (char *)&code;
174 saddr -= STACK_TO_PIN;
176 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
177 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
178 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
179 * 2K stack we could try to bring the next few stack pages in here before we call the rx
180 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
181 * out between here and calling splnet. So we now pin (and unpin) them instead to
182 * guarantee that they remain there.
184 if (pin(saddr, STACK_TO_PIN)) {
185 /* XXX There's little we can do by continue XXX */
190 code = (rx_Read(call, addr, len) == len);
191 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
193 unpin(saddr, STACK_TO_PIN);
199 xdrrx_putbytes(XDR *axdrs, caddr_t addr, u_int len)
202 XDR * xdrs = (XDR *)axdrs;
203 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
204 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
205 char *saddr = (char *)&code;
206 saddr -= STACK_TO_PIN;
208 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
209 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
210 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
211 * 2K stack we could try to bring the next few stack pages in here before we call the rx
212 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
213 * out between here and calling splnet. So we now pin (and unpin) them instead to
214 * guarantee that they remain there.
216 if (pin(saddr, STACK_TO_PIN)) {
217 /* XXX There's little we can do by continue XXX */
222 code = (rx_Write(call, addr, len) == len);
223 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
225 unpin(saddr, STACK_TO_PIN);
230 #ifdef undef /* not used */
232 xdrrx_getpos(XDR * xdrs)
234 /* Not supported. What error code should we return? (It doesn't matter: it will never be called, anyway!) */
239 xdrrx_setpos(XDR * xdrs, u_int pos)
247 xdrrx_inline(XDR *axdrs, u_int len)
249 /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */