DEVEL15-death-to-longc-procs-20060804
[openafs.git] / src / rx / xdr_rx.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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  */
9
10 /*
11  * xdr_rx.c.  XDR using RX. 
12  */
13
14 #include <afsconfig.h>
15 #ifdef  KERNEL
16 #include "afs/param.h"
17 #else
18 #include <afs/param.h>
19 #endif
20
21 RCSID
22     ("$Header$");
23
24 #ifdef KERNEL
25 #include "afs/sysincludes.h"
26 #ifndef UKERNEL
27 #include "h/types.h"
28 #include "h/uio.h"
29 #ifdef  AFS_OSF_ENV
30 #include <net/net_globals.h>
31 #endif /* AFS_OSF_ENV */
32 #ifdef AFS_LINUX20_ENV
33 #include "h/socket.h"
34 #else
35 #include "rpc/types.h"
36 #endif
37 #ifdef  AFS_OSF_ENV
38 #undef kmem_alloc
39 #undef kmem_free
40 #undef mem_alloc
41 #undef mem_free
42 #undef register
43 #endif /* AFS_OSF_ENV */
44 #ifdef AFS_LINUX22_ENV
45 #ifndef quad_t
46 #define quad_t __quad_t
47 #define u_quad_t __u_quad_t
48 #endif
49 #endif
50 #include "rx/xdr.h"
51 #include "netinet/in.h"
52 #else /* !UKERNEL */
53 #include "rpc/types.h"
54 #include "rpc/xdr.h"
55 #endif /* !UKERNEL */
56 #include "rx/rx.h"
57
58 #else /* KERNEL */
59 #include <sys/types.h>
60 #include <stdio.h>
61 #ifndef AFS_NT40_ENV
62 #include <netinet/in.h>
63 #endif
64 #include "rx.h"
65 #include "xdr.h"
66 #endif /* KERNEL */
67
68 /*
69  * This section should really go in the param.*.h files.
70  */
71 #if defined(KERNEL)
72 /*
73  * kernel version needs to agree with <rpc/xdr.h>
74  * except on Linux which does XDR differently from everyone else
75  */
76 # if defined(AFS_LINUX20_ENV) && !defined(UKERNEL)
77 #  define AFS_XDRS_T void *
78 # else
79 #  define AFS_XDRS_T XDR *
80 # endif
81 # if defined(AFS_SUN57_ENV)
82 #  define AFS_RPC_INLINE_T rpc_inline_t
83 # elif defined(AFS_DUX40_ENV)
84 #  define AFS_RPC_INLINE_T int
85 # elif defined(AFS_LINUX20_ENV) && !defined(UKERNEL)
86 #  define AFS_RPC_INLINE_T afs_int32
87 # elif defined(AFS_LINUX20_ENV)
88 #  define AFS_RPC_INLINE_T int32_t *
89 # else
90 #  define AFS_RPC_INLINE_T long
91 # endif
92 #else /* KERNEL */
93 /*
94  * user version needs to agree with "xdr.h", i.e. <rx/xdr.h>
95  */
96 #  define AFS_XDRS_T void *
97 #  define AFS_RPC_INLINE_T afs_int32
98 #endif /* KERNEL */
99
100 /* Static prototypes */
101 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)
102 static bool_t xdrrx_getint64(AFS_XDRS_T axdrs, long *lp);
103 static bool_t xdrrx_putint64(AFS_XDRS_T axdrs, long *lp);
104 #endif /* (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV) */
105
106 static bool_t xdrrx_getint32(AFS_XDRS_T axdrs, afs_int32 * lp);
107 static bool_t xdrrx_putint32(AFS_XDRS_T axdrs, afs_int32 * lp);
108 static bool_t xdrrx_getbytes(AFS_XDRS_T axdrs, caddr_t addr,
109                              u_int len);
110 static bool_t xdrrx_putbytes(AFS_XDRS_T axdrs, caddr_t addr,
111                              u_int len);
112 static AFS_RPC_INLINE_T *xdrrx_inline(AFS_XDRS_T axdrs, u_int len);
113
114
115 /*
116  * Ops vector for stdio type XDR
117  */
118 static struct xdr_ops xdrrx_ops = {
119 #if defined(KERNEL) && ((defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV))
120     xdrrx_getint64,
121     xdrrx_putint64,
122 #endif /* defined(KERNEL) && ((defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)) */
123 #if !(defined(KERNEL) && defined(AFS_SUN57_ENV))
124     xdrrx_getint32,             /* deserialize an afs_int32 */
125     xdrrx_putint32,             /* serialize an afs_int32 */
126 #endif
127     xdrrx_getbytes,             /* deserialize counted bytes */
128     xdrrx_putbytes,             /* serialize counted bytes */
129     0,                          /* get offset in the stream: not supported. */
130     0,                          /* set offset in the stream: not supported. */
131     xdrrx_inline,               /* prime stream for inline macros */
132     0,                          /* destroy stream */
133 #if defined(KERNEL) && defined(AFS_SUN57_ENV)
134     0,
135     xdrrx_getint32,             /* deserialize an afs_int32 */
136     xdrrx_putint32,             /* serialize an afs_int32 */
137 #endif
138 };
139
140 /*
141  * Initialize an rx xdr handle, for a given rx call.  op must be XDR_ENCODE or XDR_DECODE.
142  * Call must have been returned by rx_MakeCall or rx_GetCall.
143  */
144 void
145 xdrrx_create(XDR * xdrs, struct rx_call *call,
146              enum xdr_op op)
147 {
148     xdrs->x_op = op;
149     xdrs->x_ops = &xdrrx_ops;
150     xdrs->x_private = (caddr_t) call;
151 }
152
153 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
154 #define STACK_TO_PIN    2*PAGESIZE      /* 8K */
155 int rx_pin_failed = 0;
156 #endif
157
158 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)
159 static bool_t
160 xdrrx_getint64(AFS_XDRS_T axdrs, long *lp)
161 {
162     XDR * xdrs = (XDR *)axdrs;
163     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
164     afs_int32 i;
165
166     if (rx_Read32(call, &i) == sizeof(i)) {
167         *lp = ntohl(i);
168         return TRUE;
169     }
170     return FALSE;
171 }
172
173 static bool_t
174 xdrrx_putint64(AFS_XDRS_T axdrs, long *lp)
175 {
176     XDR * xdrs = (XDR *)axdrs;
177     afs_int32 code, i = htonl(*lp);
178     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
179
180     code = (rx_Write32(call, &i) == sizeof(i));
181     return code;
182 }
183 #endif /* (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV) */
184
185 static bool_t
186 xdrrx_getint32(AFS_XDRS_T axdrs, afs_int32 * lp)
187 {
188     afs_int32 l;
189     XDR * xdrs = (XDR *)axdrs;
190     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
191 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
192     char *saddr = (char *)&l;
193     saddr -= STACK_TO_PIN;
194     /*
195      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
196      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
197      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
198      * 2K stack we could try to bring the next few stack pages in here before we call the rx
199      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
200      * out between here and calling splnet. So we now pin (and unpin) them instead to
201      * guarantee that they remain there.
202      */
203     if (pin(saddr, STACK_TO_PIN)) {
204         /* XXX There's little we can do by continue XXX */
205         saddr = NULL;
206         rx_pin_failed++;
207     }
208 #endif
209     if (rx_Read32(call, &l) == sizeof(l)) {
210         *lp = ntohl(l);
211 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
212         if (saddr)
213             unpin(saddr, STACK_TO_PIN);
214 #endif
215         return TRUE;
216     }
217 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
218     if (saddr)
219         unpin(saddr, STACK_TO_PIN);
220 #endif
221     return FALSE;
222 }
223
224 static bool_t
225 xdrrx_putint32(AFS_XDRS_T axdrs, afs_int32 * lp)
226 {
227     afs_int32 code, l = htonl(*lp);
228     XDR * xdrs = (XDR *)axdrs;
229     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
230 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
231     char *saddr = (char *)&code;
232     saddr -= STACK_TO_PIN;
233     /*
234      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
235      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
236      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
237      * 2K stack we could try to bring the next few stack pages in here before we call the rx
238      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
239      * out between here and calling splnet. So we now pin (and unpin) them instead to
240      * guarantee that they remain there.
241      */
242     if (pin(saddr, STACK_TO_PIN)) {
243         saddr = NULL;
244         rx_pin_failed++;
245     }
246 #endif
247     code = (rx_Write32(call, &l) == sizeof(l));
248 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
249     if (saddr)
250         unpin(saddr, STACK_TO_PIN);
251 #endif
252     return code;
253 }
254
255 static bool_t
256 xdrrx_getbytes(AFS_XDRS_T axdrs, caddr_t addr, u_int len)
257 {
258     afs_int32 code;
259     XDR * xdrs = (XDR *)axdrs;
260     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
261 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
262     char *saddr = (char *)&code;
263     saddr -= STACK_TO_PIN;
264     /*
265      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
266      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
267      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
268      * 2K stack we could try to bring the next few stack pages in here before we call the rx
269      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
270      * out between here and calling splnet. So we now pin (and unpin) them instead to
271      * guarantee that they remain there.
272      */
273     if (pin(saddr, STACK_TO_PIN)) {
274         /* XXX There's little we can do by continue XXX */
275         saddr = NULL;
276         rx_pin_failed++;
277     }
278 #endif
279     code = (rx_Read(call, addr, len) == len);
280 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
281     if (saddr)
282         unpin(saddr, STACK_TO_PIN);
283 #endif
284     return code;
285 }
286
287 static bool_t
288 xdrrx_putbytes(AFS_XDRS_T axdrs, caddr_t addr, u_int len)
289 {
290     afs_int32 code;
291     XDR * xdrs = (XDR *)axdrs;
292     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
293 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
294     char *saddr = (char *)&code;
295     saddr -= STACK_TO_PIN;
296     /*
297      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
298      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
299      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
300      * 2K stack we could try to bring the next few stack pages in here before we call the rx
301      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
302      * out between here and calling splnet. So we now pin (and unpin) them instead to
303      * guarantee that they remain there.
304      */
305     if (pin(saddr, STACK_TO_PIN)) {
306         /* XXX There's little we can do by continue XXX */
307         saddr = NULL;
308         rx_pin_failed++;
309     }
310 #endif
311     code = (rx_Write(call, addr, len) == len);
312 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
313     if (saddr)
314         unpin(saddr, STACK_TO_PIN);
315 #endif
316     return code;
317 }
318
319 #ifdef undef                    /* not used */
320 static u_int
321 xdrrx_getpos(XDR * xdrs)
322 {
323     /* Not supported.  What error code should we return? (It doesn't matter:  it will never be called, anyway!) */
324     return -1;
325 }
326
327 static bool_t
328 xdrrx_setpos(XDR * xdrs, u_int pos)
329 {
330     /* Not supported */
331     return FALSE;
332 }
333 #endif
334
335 static AFS_RPC_INLINE_T *
336 xdrrx_inline(AFS_XDRS_T axdrs, u_int len)
337 {
338     /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */
339     return (0);
340 }