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