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