Merge branch 'master' into experimental
[pkg-k5-afs_openafs.git] / src / rx / xdr_rx.c
blobb7a2426c043d62ef32600811beff3f0b3a31f6e7
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
11 * xdr_rx.c. XDR using RX.
14 #include <afsconfig.h>
15 #include <afs/param.h>
17 #ifdef KERNEL
18 # include "afs/sysincludes.h"
19 # ifndef UKERNEL
20 # include "h/types.h"
21 # include "h/uio.h"
22 # ifdef AFS_LINUX20_ENV
23 # include "h/socket.h"
24 # else
25 # include "rpc/types.h"
26 # endif
27 # ifdef AFS_LINUX22_ENV
28 # ifndef quad_t
29 # define quad_t __quad_t
30 # define u_quad_t __u_quad_t
31 # endif
32 # endif
33 # include "netinet/in.h"
34 # endif /* !UKERNEL */
35 #else /* KERNEL */
36 # include <roken.h>
37 #endif /* KERNEL */
39 #include "rx.h"
40 #include "xdr.h"
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,
46 u_int len);
47 static bool_t xdrrx_putbytes(XDR *axdrs, caddr_t addr,
48 u_int len);
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 */
66 #else
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 */
75 #endif
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.
82 void
83 xdrrx_create(XDR * xdrs, struct rx_call *call,
84 enum xdr_op op)
86 xdrs->x_op = op;
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;
94 #endif
96 static bool_t
97 xdrrx_getint32(XDR *axdrs, afs_int32 * lp)
99 afs_int32 l;
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 */
116 saddr = NULL;
117 rx_pin_failed++;
119 #endif
120 if (rx_Read32(call, &l) == sizeof(l)) {
121 *lp = ntohl(l);
122 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
123 if (saddr)
124 unpin(saddr, STACK_TO_PIN);
125 #endif
126 return TRUE;
128 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
129 if (saddr)
130 unpin(saddr, STACK_TO_PIN);
131 #endif
132 return FALSE;
135 static bool_t
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)) {
154 saddr = NULL;
155 rx_pin_failed++;
157 #endif
158 code = (rx_Write32(call, &l) == sizeof(l));
159 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
160 if (saddr)
161 unpin(saddr, STACK_TO_PIN);
162 #endif
163 return code;
166 static bool_t
167 xdrrx_getbytes(XDR *axdrs, caddr_t addr, u_int len)
169 afs_int32 code;
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 */
186 saddr = NULL;
187 rx_pin_failed++;
189 #endif
190 code = (rx_Read(call, addr, len) == len);
191 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
192 if (saddr)
193 unpin(saddr, STACK_TO_PIN);
194 #endif
195 return code;
198 static bool_t
199 xdrrx_putbytes(XDR *axdrs, caddr_t addr, u_int len)
201 afs_int32 code;
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 */
218 saddr = NULL;
219 rx_pin_failed++;
221 #endif
222 code = (rx_Write(call, addr, len) == len);
223 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
224 if (saddr)
225 unpin(saddr, STACK_TO_PIN);
226 #endif
227 return code;
230 #ifdef undef /* not used */
231 static u_int
232 xdrrx_getpos(XDR * xdrs)
234 /* Not supported. What error code should we return? (It doesn't matter: it will never be called, anyway!) */
235 return -1;
238 static bool_t
239 xdrrx_setpos(XDR * xdrs, u_int pos)
241 /* Not supported */
242 return FALSE;
244 #endif
246 static afs_int32 *
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 */
250 return (0);