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"
23 # include "h/socket.h"
25 # define quad_t __quad_t
26 # define u_quad_t __u_quad_t
29 # include "netinet/in.h"
30 # endif /* !UKERNEL */
38 /* Static prototypes */
39 static bool_t xdrrx_getint32(XDR *axdrs, afs_int32 * lp);
40 static bool_t xdrrx_putint32(XDR *axdrs, afs_int32 * lp);
41 static bool_t xdrrx_getbytes(XDR *axdrs, caddr_t addr,
43 static bool_t xdrrx_putbytes(XDR *axdrs, caddr_t addr,
45 static afs_int32 *xdrrx_inline(XDR *axdrs, u_int len);
49 * Ops vector for stdio type XDR
51 static struct xdr_ops xdrrx_ops = {
52 #ifndef HAVE_STRUCT_LABEL_SUPPORT
53 /* Windows does not support labeled assigments */
54 xdrrx_getint32, /* deserialize an afs_int32 */
55 xdrrx_putint32, /* serialize an afs_int32 */
56 xdrrx_getbytes, /* deserialize counted bytes */
57 xdrrx_putbytes, /* serialize counted bytes */
58 NULL, /* get offset in the stream: not supported. */
59 NULL, /* set offset in the stream: not supported. */
60 xdrrx_inline, /* prime stream for inline macros */
61 NULL, /* destroy stream */
63 .x_getint32 = xdrrx_getint32, /* deserialize an afs_int32 */
64 .x_putint32 = xdrrx_putint32, /* serialize an afs_int32 */
65 .x_getbytes = xdrrx_getbytes, /* deserialize counted bytes */
66 .x_putbytes = xdrrx_putbytes, /* serialize counted bytes */
67 .x_getpostn = NULL, /* get offset in the stream: not supported. */
68 .x_setpostn = NULL, /* set offset in the stream: not supported. */
69 .x_inline = xdrrx_inline, /* prime stream for inline macros */
70 .x_destroy = NULL, /* destroy stream */
75 * Initialize an rx xdr handle, for a given rx call. op must be XDR_ENCODE or XDR_DECODE.
76 * Call must have been returned by rx_MakeCall or rx_GetCall.
79 xdrrx_create(XDR * xdrs, struct rx_call *call,
83 xdrs->x_ops = &xdrrx_ops;
84 xdrs->x_private = (caddr_t) call;
87 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
88 #define STACK_TO_PIN 2*PAGESIZE /* 8K */
89 int rx_pin_failed = 0;
93 xdrrx_getint32(XDR *axdrs, afs_int32 * lp)
96 XDR * xdrs = (XDR *)axdrs;
97 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
98 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
99 char *saddr = (char *)&l;
100 saddr -= STACK_TO_PIN;
102 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
103 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
104 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
105 * 2K stack we could try to bring the next few stack pages in here before we call the rx
106 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
107 * out between here and calling splnet. So we now pin (and unpin) them instead to
108 * guarantee that they remain there.
110 if (pin(saddr, STACK_TO_PIN)) {
111 /* XXX There's little we can do by continue XXX */
116 if (rx_Read32(call, &l) == sizeof(l)) {
118 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
120 unpin(saddr, STACK_TO_PIN);
124 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
126 unpin(saddr, STACK_TO_PIN);
132 xdrrx_putint32(XDR *axdrs, afs_int32 * lp)
134 afs_int32 code, l = htonl(*lp);
135 XDR * xdrs = (XDR *)axdrs;
136 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
137 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
138 char *saddr = (char *)&code;
139 saddr -= STACK_TO_PIN;
141 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
142 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
143 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
144 * 2K stack we could try to bring the next few stack pages in here before we call the rx
145 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
146 * out between here and calling splnet. So we now pin (and unpin) them instead to
147 * guarantee that they remain there.
149 if (pin(saddr, STACK_TO_PIN)) {
154 code = (rx_Write32(call, &l) == sizeof(l));
155 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
157 unpin(saddr, STACK_TO_PIN);
163 xdrrx_getbytes(XDR *axdrs, caddr_t addr, u_int len)
166 XDR * xdrs = (XDR *)axdrs;
167 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
168 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
169 char *saddr = (char *)&code;
170 saddr -= STACK_TO_PIN;
172 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
173 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
174 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
175 * 2K stack we could try to bring the next few stack pages in here before we call the rx
176 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
177 * out between here and calling splnet. So we now pin (and unpin) them instead to
178 * guarantee that they remain there.
180 if (pin(saddr, STACK_TO_PIN)) {
181 /* XXX There's little we can do by continue XXX */
186 code = (rx_Read(call, addr, len) == len);
187 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
189 unpin(saddr, STACK_TO_PIN);
195 xdrrx_putbytes(XDR *axdrs, caddr_t addr, u_int len)
198 XDR * xdrs = (XDR *)axdrs;
199 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
200 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
201 char *saddr = (char *)&code;
202 saddr -= STACK_TO_PIN;
204 * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
205 * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
206 * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
207 * 2K stack we could try to bring the next few stack pages in here before we call the rx
208 * layer. Of course this doesn't guarantee that those stack pages won't be swapped
209 * out between here and calling splnet. So we now pin (and unpin) them instead to
210 * guarantee that they remain there.
212 if (pin(saddr, STACK_TO_PIN)) {
213 /* XXX There's little we can do by continue XXX */
218 code = (rx_Write(call, addr, len) == len);
219 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
221 unpin(saddr, STACK_TO_PIN);
227 xdrrx_inline(XDR *axdrs, u_int len)
229 /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */