Print this page
OS-20 share_nfs(1m) charset handling is unreliable
OS-22 Page fault at nfscmd_dropped_entrysize+0x1e()
OS-23 NFSv2/3/4: READDIR responses are inconsistent when charset conversion fails
OS-24 rfs3_readdir(): Issues related to nfscmd_convdirent()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/nfs/nfs_xdr.c
+++ new/usr/src/uts/common/fs/nfs/nfs_xdr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 +/*
26 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
27 + */
25 28
26 29 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 30 /* All Rights Reserved */
28 31
29 32 #include <sys/param.h>
30 33 #include <sys/types.h>
31 34 #include <sys/systm.h>
32 35 #include <sys/user.h>
33 36 #include <sys/vnode.h>
34 37 #include <sys/file.h>
35 38 #include <sys/dirent.h>
36 39 #include <sys/vfs.h>
37 40 #include <sys/stream.h>
38 41 #include <sys/strsubr.h>
39 42 #include <sys/debug.h>
40 43 #include <sys/t_lock.h>
41 44 #include <sys/sdt.h>
42 45
43 46 #include <rpc/types.h>
44 47 #include <rpc/xdr.h>
45 48
46 49 #include <nfs/nfs.h>
47 50
48 51 #include <vm/hat.h>
49 52 #include <vm/as.h>
50 53 #include <vm/seg.h>
51 54 #include <vm/seg_map.h>
52 55 #include <vm/seg_kmem.h>
53 56
54 57 static bool_t xdr_fastshorten(XDR *, uint_t);
55 58
56 59 /*
57 60 * These are the XDR routines used to serialize and deserialize
58 61 * the various structures passed as parameters accross the network
59 62 * between NFS clients and servers.
60 63 */
61 64
62 65 /*
63 66 * File access handle
64 67 * The fhandle struct is treated a opaque data on the wire
65 68 */
66 69 bool_t
67 70 xdr_fhandle(XDR *xdrs, fhandle_t *fh)
68 71 {
69 72 int32_t *ptr;
70 73 int32_t *fhp;
71 74
72 75 if (xdrs->x_op == XDR_FREE)
73 76 return (TRUE);
74 77
75 78 ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
76 79 if (ptr != NULL) {
77 80 fhp = (int32_t *)fh;
78 81 if (xdrs->x_op == XDR_DECODE) {
79 82 *fhp++ = *ptr++;
80 83 *fhp++ = *ptr++;
81 84 *fhp++ = *ptr++;
82 85 *fhp++ = *ptr++;
83 86 *fhp++ = *ptr++;
84 87 *fhp++ = *ptr++;
85 88 *fhp++ = *ptr++;
86 89 *fhp = *ptr;
87 90 } else {
88 91 *ptr++ = *fhp++;
89 92 *ptr++ = *fhp++;
90 93 *ptr++ = *fhp++;
91 94 *ptr++ = *fhp++;
92 95 *ptr++ = *fhp++;
93 96 *ptr++ = *fhp++;
94 97 *ptr++ = *fhp++;
95 98 *ptr = *fhp;
96 99 }
97 100 return (TRUE);
98 101 }
99 102
100 103 return (xdr_opaque(xdrs, (caddr_t)fh, NFS_FHSIZE));
101 104 }
102 105
103 106 bool_t
104 107 xdr_fastfhandle(XDR *xdrs, fhandle_t **fh)
105 108 {
106 109 int32_t *ptr;
107 110
108 111 if (xdrs->x_op != XDR_DECODE)
109 112 return (FALSE);
110 113
111 114 ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
112 115 if (ptr != NULL) {
113 116 *fh = (fhandle_t *)ptr;
114 117 return (TRUE);
115 118 }
116 119
117 120 return (FALSE);
118 121 }
119 122
120 123 /*
121 124 * Arguments to remote write and writecache
122 125 */
123 126 bool_t
124 127 xdr_writeargs(XDR *xdrs, struct nfswriteargs *wa)
125 128 {
126 129 int32_t *ptr;
127 130 int32_t *fhp;
128 131
129 132 switch (xdrs->x_op) {
130 133 case XDR_DECODE:
131 134 wa->wa_args = &wa->wa_args_buf;
132 135 ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
133 136 3 * BYTES_PER_XDR_UNIT);
134 137 if (ptr != NULL) {
135 138 fhp = (int32_t *)&wa->wa_fhandle;
136 139 *fhp++ = *ptr++;
137 140 *fhp++ = *ptr++;
138 141 *fhp++ = *ptr++;
139 142 *fhp++ = *ptr++;
140 143 *fhp++ = *ptr++;
141 144 *fhp++ = *ptr++;
142 145 *fhp++ = *ptr++;
143 146 *fhp = *ptr++;
144 147 wa->wa_begoff = IXDR_GET_U_INT32(ptr);
145 148 wa->wa_offset = IXDR_GET_U_INT32(ptr);
146 149 wa->wa_totcount = IXDR_GET_U_INT32(ptr);
147 150 wa->wa_mblk = NULL;
148 151 wa->wa_data = NULL;
149 152 wa->wa_rlist = NULL;
150 153 wa->wa_conn = NULL;
151 154 if (xdrs->x_ops == &xdrmblk_ops) {
152 155 return (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
153 156 &wa->wa_count));
154 157 } else {
155 158 if (xdrs->x_ops == &xdrrdmablk_ops) {
156 159 if (xdrrdma_getrdmablk(xdrs,
157 160 &wa->wa_rlist,
158 161 &wa->wa_count,
159 162 &wa->wa_conn,
160 163 NFS_MAXDATA) == TRUE)
161 164 return (xdrrdma_read_from_client(
162 165 wa->wa_rlist,
163 166 &wa->wa_conn,
164 167 wa->wa_count));
165 168
166 169 wa->wa_rlist = NULL;
167 170 wa->wa_conn = NULL;
168 171 }
169 172 }
170 173
171 174 /*
172 175 * It is just as efficient to xdr_bytes
173 176 * an array of unknown length as to inline copy it.
174 177 */
175 178 return (xdr_bytes(xdrs, &wa->wa_data,
176 179 &wa->wa_count, NFS_MAXDATA));
177 180 }
178 181 if (xdr_fhandle(xdrs, &wa->wa_fhandle) &&
179 182 xdr_u_int(xdrs, &wa->wa_begoff) &&
180 183 xdr_u_int(xdrs, &wa->wa_offset) &&
181 184 xdr_u_int(xdrs, &wa->wa_totcount)) {
182 185 /* deal with the variety of data transfer types */
183 186
184 187 wa->wa_mblk = NULL;
185 188 wa->wa_data = NULL;
186 189 wa->wa_rlist = NULL;
187 190 wa->wa_conn = NULL;
188 191
189 192 if (xdrs->x_ops == &xdrmblk_ops) {
190 193 if (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
191 194 &wa->wa_count) == TRUE)
192 195 return (TRUE);
193 196 } else {
194 197 if (xdrs->x_ops == &xdrrdmablk_ops) {
195 198 if (xdrrdma_getrdmablk(xdrs,
196 199 &wa->wa_rlist,
197 200 &wa->wa_count,
198 201 &wa->wa_conn,
199 202 NFS_MAXDATA) == TRUE)
200 203 return (xdrrdma_read_from_client(
201 204 wa->wa_rlist,
202 205 &wa->wa_conn,
203 206 wa->wa_count));
204 207
205 208 wa->wa_rlist = NULL;
206 209 wa->wa_conn = NULL;
207 210 }
208 211 }
209 212 return (xdr_bytes(xdrs, &wa->wa_data,
210 213 &wa->wa_count, NFS_MAXDATA));
211 214 }
212 215 return (FALSE);
213 216 case XDR_ENCODE:
214 217 ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
215 218 3 * BYTES_PER_XDR_UNIT);
216 219 if (ptr != NULL) {
217 220 fhp = (int32_t *)&wa->wa_fhandle;
218 221 *ptr++ = *fhp++;
219 222 *ptr++ = *fhp++;
220 223 *ptr++ = *fhp++;
221 224 *ptr++ = *fhp++;
222 225 *ptr++ = *fhp++;
223 226 *ptr++ = *fhp++;
224 227 *ptr++ = *fhp++;
225 228 *ptr++ = *fhp;
226 229 IXDR_PUT_U_INT32(ptr, wa->wa_begoff);
227 230 IXDR_PUT_U_INT32(ptr, wa->wa_offset);
228 231 IXDR_PUT_U_INT32(ptr, wa->wa_totcount);
229 232 } else {
230 233 if (!(xdr_fhandle(xdrs, &wa->wa_fhandle) &&
231 234 xdr_u_int(xdrs, &wa->wa_begoff) &&
232 235 xdr_u_int(xdrs, &wa->wa_offset) &&
233 236 xdr_u_int(xdrs, &wa->wa_totcount)))
234 237 return (FALSE);
235 238 }
236 239
237 240 return (xdr_bytes(xdrs, &wa->wa_data, &wa->wa_count,
238 241 NFS_MAXDATA));
239 242 case XDR_FREE:
240 243 if (wa->wa_rlist) {
241 244 (void) xdrrdma_free_clist(wa->wa_conn, wa->wa_rlist);
242 245 wa->wa_rlist = NULL;
243 246 }
244 247
245 248 if (wa->wa_data != NULL) {
246 249 kmem_free(wa->wa_data, wa->wa_count);
247 250 wa->wa_data = NULL;
248 251 }
249 252 return (TRUE);
250 253 }
251 254 return (FALSE);
252 255 }
253 256
254 257
255 258 /*
256 259 * File attributes
257 260 */
258 261 bool_t
259 262 xdr_fattr(XDR *xdrs, struct nfsfattr *na)
260 263 {
261 264 int32_t *ptr;
262 265
263 266 if (xdrs->x_op == XDR_FREE)
264 267 return (TRUE);
265 268
266 269 ptr = XDR_INLINE(xdrs, 17 * BYTES_PER_XDR_UNIT);
267 270 if (ptr != NULL) {
268 271 if (xdrs->x_op == XDR_DECODE) {
269 272 na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
270 273 na->na_mode = IXDR_GET_U_INT32(ptr);
271 274 na->na_nlink = IXDR_GET_U_INT32(ptr);
272 275 na->na_uid = IXDR_GET_U_INT32(ptr);
273 276 na->na_gid = IXDR_GET_U_INT32(ptr);
274 277 na->na_size = IXDR_GET_U_INT32(ptr);
275 278 na->na_blocksize = IXDR_GET_U_INT32(ptr);
276 279 na->na_rdev = IXDR_GET_U_INT32(ptr);
277 280 na->na_blocks = IXDR_GET_U_INT32(ptr);
278 281 na->na_fsid = IXDR_GET_U_INT32(ptr);
279 282 na->na_nodeid = IXDR_GET_U_INT32(ptr);
280 283 na->na_atime.tv_sec = IXDR_GET_U_INT32(ptr);
281 284 na->na_atime.tv_usec = IXDR_GET_U_INT32(ptr);
282 285 na->na_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
283 286 na->na_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
284 287 na->na_ctime.tv_sec = IXDR_GET_U_INT32(ptr);
285 288 na->na_ctime.tv_usec = IXDR_GET_U_INT32(ptr);
286 289 } else {
287 290 IXDR_PUT_ENUM(ptr, na->na_type);
288 291 IXDR_PUT_U_INT32(ptr, na->na_mode);
289 292 IXDR_PUT_U_INT32(ptr, na->na_nlink);
290 293 IXDR_PUT_U_INT32(ptr, na->na_uid);
291 294 IXDR_PUT_U_INT32(ptr, na->na_gid);
292 295 IXDR_PUT_U_INT32(ptr, na->na_size);
293 296 IXDR_PUT_U_INT32(ptr, na->na_blocksize);
294 297 IXDR_PUT_U_INT32(ptr, na->na_rdev);
295 298 IXDR_PUT_U_INT32(ptr, na->na_blocks);
296 299 IXDR_PUT_U_INT32(ptr, na->na_fsid);
297 300 IXDR_PUT_U_INT32(ptr, na->na_nodeid);
298 301 IXDR_PUT_U_INT32(ptr, na->na_atime.tv_sec);
299 302 IXDR_PUT_U_INT32(ptr, na->na_atime.tv_usec);
300 303 IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_sec);
301 304 IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_usec);
302 305 IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_sec);
303 306 IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_usec);
304 307 }
305 308 return (TRUE);
306 309 }
307 310
308 311 if (xdr_enum(xdrs, (enum_t *)&na->na_type) &&
309 312 xdr_u_int(xdrs, &na->na_mode) &&
310 313 xdr_u_int(xdrs, &na->na_nlink) &&
311 314 xdr_u_int(xdrs, &na->na_uid) &&
312 315 xdr_u_int(xdrs, &na->na_gid) &&
313 316 xdr_u_int(xdrs, &na->na_size) &&
314 317 xdr_u_int(xdrs, &na->na_blocksize) &&
315 318 xdr_u_int(xdrs, &na->na_rdev) &&
316 319 xdr_u_int(xdrs, &na->na_blocks) &&
317 320 xdr_u_int(xdrs, &na->na_fsid) &&
318 321 xdr_u_int(xdrs, &na->na_nodeid) &&
319 322 xdr_nfs2_timeval(xdrs, &na->na_atime) &&
320 323 xdr_nfs2_timeval(xdrs, &na->na_mtime) &&
321 324 xdr_nfs2_timeval(xdrs, &na->na_ctime)) {
322 325 return (TRUE);
323 326 }
324 327 return (FALSE);
325 328 }
326 329
327 330 #ifdef _LITTLE_ENDIAN
328 331 bool_t
329 332 xdr_fastfattr(XDR *xdrs, struct nfsfattr *na)
330 333 {
331 334 if (xdrs->x_op == XDR_FREE)
332 335 return (TRUE);
333 336 if (xdrs->x_op == XDR_DECODE)
334 337 return (FALSE);
335 338
336 339 na->na_type = htonl(na->na_type);
337 340 na->na_mode = htonl(na->na_mode);
338 341 na->na_nlink = htonl(na->na_nlink);
339 342 na->na_uid = htonl(na->na_uid);
340 343 na->na_gid = htonl(na->na_gid);
341 344 na->na_size = htonl(na->na_size);
342 345 na->na_blocksize = htonl(na->na_blocksize);
343 346 na->na_rdev = htonl(na->na_rdev);
344 347 na->na_blocks = htonl(na->na_blocks);
345 348 na->na_fsid = htonl(na->na_fsid);
346 349 na->na_nodeid = htonl(na->na_nodeid);
347 350 na->na_atime.tv_sec = htonl(na->na_atime.tv_sec);
348 351 na->na_atime.tv_usec = htonl(na->na_atime.tv_usec);
349 352 na->na_mtime.tv_sec = htonl(na->na_mtime.tv_sec);
350 353 na->na_mtime.tv_usec = htonl(na->na_mtime.tv_usec);
351 354 na->na_ctime.tv_sec = htonl(na->na_ctime.tv_sec);
352 355 na->na_ctime.tv_usec = htonl(na->na_ctime.tv_usec);
353 356 return (TRUE);
354 357 }
355 358 #endif
356 359
357 360 bool_t
358 361 xdr_readlink(XDR *xdrs, fhandle_t *fh)
359 362 {
360 363 rdma_chunkinfo_t rci;
361 364 struct xdr_ops *xops = xdrrdma_xops();
362 365
363 366 if (xdr_fhandle(xdrs, fh)) {
364 367 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
365 368 xdrs->x_op == XDR_ENCODE) {
366 369 rci.rci_type = RCI_REPLY_CHUNK;
367 370 rci.rci_len = MAXPATHLEN;
368 371 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
369 372 }
370 373
371 374 return (TRUE);
372 375 }
373 376 return (FALSE);
374 377 }
375 378
376 379 /*
377 380 * Arguments to remote read
378 381 */
379 382 bool_t
380 383 xdr_readargs(XDR *xdrs, struct nfsreadargs *ra)
381 384 {
382 385 int32_t *ptr;
383 386 int32_t *fhp;
384 387 rdma_chunkinfo_t rci;
385 388 rdma_wlist_conn_info_t rwci;
386 389 struct xdr_ops *xops = xdrrdma_xops();
387 390
388 391 if (xdrs->x_op == XDR_FREE)
389 392 return (TRUE);
390 393
391 394 ptr = XDR_INLINE(xdrs,
392 395 RNDUP(sizeof (fhandle_t)) + 3 * BYTES_PER_XDR_UNIT);
393 396 if (ptr != NULL) {
394 397 if (xdrs->x_op == XDR_DECODE) {
395 398 fhp = (int32_t *)&ra->ra_fhandle;
396 399 *fhp++ = *ptr++;
397 400 *fhp++ = *ptr++;
398 401 *fhp++ = *ptr++;
399 402 *fhp++ = *ptr++;
400 403 *fhp++ = *ptr++;
401 404 *fhp++ = *ptr++;
402 405 *fhp++ = *ptr++;
403 406 *fhp = *ptr++;
404 407 ra->ra_offset = IXDR_GET_INT32(ptr);
405 408 ra->ra_count = IXDR_GET_INT32(ptr);
406 409 ra->ra_totcount = IXDR_GET_INT32(ptr);
407 410 } else {
408 411 fhp = (int32_t *)&ra->ra_fhandle;
409 412 *ptr++ = *fhp++;
410 413 *ptr++ = *fhp++;
411 414 *ptr++ = *fhp++;
412 415 *ptr++ = *fhp++;
413 416 *ptr++ = *fhp++;
414 417 *ptr++ = *fhp++;
415 418 *ptr++ = *fhp++;
416 419 *ptr++ = *fhp;
417 420 IXDR_PUT_INT32(ptr, ra->ra_offset);
418 421 IXDR_PUT_INT32(ptr, ra->ra_count);
419 422 IXDR_PUT_INT32(ptr, ra->ra_totcount);
420 423 }
421 424 } else {
422 425 if (!xdr_fhandle(xdrs, &ra->ra_fhandle) ||
423 426 !xdr_u_int(xdrs, &ra->ra_offset) ||
424 427 !xdr_u_int(xdrs, &ra->ra_count) ||
425 428 !xdr_u_int(xdrs, &ra->ra_totcount)) {
426 429 return (FALSE);
427 430 }
428 431 }
429 432
430 433 if (ra->ra_count > NFS_MAXDATA)
431 434 return (FALSE);
432 435
433 436 ra->ra_wlist = NULL;
434 437 ra->ra_conn = NULL;
435 438
436 439 /* If this is xdrrdma_sizeof, record the expect response size */
437 440 if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
438 441 rci.rci_type = RCI_WRITE_ADDR_CHUNK;
439 442 rci.rci_len = ra->ra_count;
440 443 (void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
441 444 }
442 445 /* Nothing special to do, return */
443 446 if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
444 447 return (TRUE);
445 448
446 449 if (xdrs->x_op == XDR_ENCODE) {
447 450 /* Place the target data location into the RDMA header */
448 451 rci.rci_type = RCI_WRITE_ADDR_CHUNK;
449 452 rci.rci_a.rci_addr = ra->ra_data;
450 453 rci.rci_len = ra->ra_count;
451 454 rci.rci_clpp = &ra->ra_wlist;
452 455
453 456 return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
454 457 }
455 458
456 459 /* XDR_DECODE case */
457 460 (void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
458 461 ra->ra_wlist = rwci.rwci_wlist;
459 462 ra->ra_conn = rwci.rwci_conn;
460 463
461 464 return (TRUE);
462 465 }
463 466
464 467
465 468 /*
466 469 * Status OK portion of remote read reply
467 470 */
468 471 bool_t
469 472 xdr_rrok(XDR *xdrs, struct nfsrrok *rrok)
470 473 {
471 474 bool_t ret;
472 475 mblk_t *mp;
473 476 struct xdr_ops *xops = xdrrdma_xops();
474 477
475 478 if (xdr_fattr(xdrs, &rrok->rrok_attr) == FALSE)
476 479 return (FALSE);
477 480
478 481 /* deal with RDMA separately */
479 482 if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
480 483 if (xdrs->x_op == XDR_ENCODE &&
481 484 rrok->rrok_mp != NULL) {
482 485 ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
483 486 &rrok->rrok_count, NFS_MAXDATA);
484 487 return (ret);
485 488 }
486 489
487 490 if (xdrs->x_op == XDR_ENCODE) {
488 491 if (xdr_u_int(xdrs, &rrok->rrok_count) == FALSE) {
489 492 return (FALSE);
490 493 }
491 494 /*
492 495 * If read data sent by wlist (RDMA_WRITE), don't do
493 496 * xdr_bytes() below. RDMA_WRITE transfers the data.
494 497 */
495 498 if (rrok->rrok_wlist) {
496 499 if (rrok->rrok_count != 0) {
497 500 return (xdrrdma_send_read_data(
498 501 xdrs, rrok->rrok_count,
499 502 rrok->rrok_wlist));
500 503 }
501 504 return (TRUE);
502 505 }
503 506 if (rrok->rrok_count == 0) {
504 507 return (TRUE);
505 508 }
506 509 } else {
507 510 struct clist *cl;
508 511 uint32_t count;
509 512
510 513 XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
511 514
512 515 if (cl) {
513 516 if (!xdr_u_int(xdrs, &count))
514 517 return (FALSE);
515 518 if (count == 0) {
516 519 rrok->rrok_wlist_len = 0;
517 520 rrok->rrok_count = 0;
518 521 } else {
519 522 rrok->rrok_wlist_len = clist_len(cl);
520 523 if (rrok->rrok_wlist_len !=
521 524 roundup(count,
522 525 BYTES_PER_XDR_UNIT)) {
523 526 rrok->rrok_wlist_len = 0;
524 527 rrok->rrok_count = 0;
525 528 return (FALSE);
526 529 }
527 530 rrok->rrok_count = count;
528 531 }
529 532 return (TRUE);
530 533 }
531 534 }
532 535 ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
533 536 &rrok->rrok_count, NFS_MAXDATA);
534 537
535 538 return (ret);
536 539 }
537 540
538 541 if (xdrs->x_op == XDR_ENCODE) {
539 542 int i, rndup;
540 543
541 544 mp = rrok->rrok_mp;
542 545 if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
543 546 mp->b_wptr += rrok->rrok_count;
544 547 rndup = BYTES_PER_XDR_UNIT -
545 548 (rrok->rrok_count % BYTES_PER_XDR_UNIT);
546 549 if (rndup != BYTES_PER_XDR_UNIT)
547 550 for (i = 0; i < rndup; i++)
548 551 *mp->b_wptr++ = '\0';
549 552 if (xdrmblk_putmblk(xdrs, mp,
550 553 rrok->rrok_count) == TRUE) {
551 554 rrok->rrok_mp = NULL;
552 555 return (TRUE);
553 556 }
554 557 }
555 558
556 559 /*
557 560 * Fall thru for the xdr_bytes()
558 561 *
559 562 * Note: the mblk mp will be freed in rfs_rdfree
560 563 */
561 564 }
562 565
563 566 ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
564 567 &rrok->rrok_count, NFS_MAXDATA);
565 568
566 569 return (ret);
567 570 }
568 571
569 572 static struct xdr_discrim rdres_discrim[2] = {
570 573 { NFS_OK, xdr_rrok },
571 574 { __dontcare__, NULL_xdrproc_t }
572 575 };
573 576
574 577 /*
575 578 * Reply from remote read
576 579 */
577 580 bool_t
578 581 xdr_rdresult(XDR *xdrs, struct nfsrdresult *rr)
579 582 {
580 583 return (xdr_union(xdrs, (enum_t *)&(rr->rr_status),
581 584 (caddr_t)&(rr->rr_ok), rdres_discrim, xdr_void));
582 585 }
583 586
584 587 /*
585 588 * File attributes which can be set
586 589 */
587 590 bool_t
588 591 xdr_sattr(XDR *xdrs, struct nfssattr *sa)
589 592 {
590 593 if (xdr_u_int(xdrs, &sa->sa_mode) &&
591 594 xdr_u_int(xdrs, &sa->sa_uid) &&
592 595 xdr_u_int(xdrs, &sa->sa_gid) &&
593 596 xdr_u_int(xdrs, &sa->sa_size) &&
594 597 xdr_nfs2_timeval(xdrs, &sa->sa_atime) &&
595 598 xdr_nfs2_timeval(xdrs, &sa->sa_mtime)) {
596 599 return (TRUE);
597 600 }
598 601 return (FALSE);
599 602 }
600 603
601 604 static struct xdr_discrim attrstat_discrim[2] = {
602 605 { (int)NFS_OK, xdr_fattr },
603 606 { __dontcare__, NULL_xdrproc_t }
604 607 };
605 608
606 609 /*
607 610 * Reply status with file attributes
608 611 */
609 612 bool_t
610 613 xdr_attrstat(XDR *xdrs, struct nfsattrstat *ns)
611 614 {
612 615 return (xdr_union(xdrs, (enum_t *)&(ns->ns_status),
613 616 (caddr_t)&(ns->ns_attr), attrstat_discrim, xdr_void));
614 617 }
615 618
616 619 /*
617 620 * Fast reply status with file attributes
618 621 */
619 622 bool_t
620 623 xdr_fastattrstat(XDR *xdrs, struct nfsattrstat *ns)
621 624 {
622 625 #if defined(_LITTLE_ENDIAN)
623 626 /*
624 627 * we deal with the discriminator; it's an enum
625 628 */
626 629 if (!xdr_fastenum(xdrs, (enum_t *)&ns->ns_status))
627 630 return (FALSE);
628 631
629 632 if (ns->ns_status == NFS_OK)
630 633 return (xdr_fastfattr(xdrs, &ns->ns_attr));
631 634 #elif defined(_BIG_ENDIAN)
632 635 if (ns->ns_status == NFS_OK)
633 636 return (TRUE);
634 637 #endif
635 638 return (xdr_fastshorten(xdrs, sizeof (*ns)));
636 639 }
637 640
638 641 /*
639 642 * NFS_OK part of read sym link reply union
640 643 */
641 644 bool_t
642 645 xdr_srok(XDR *xdrs, struct nfssrok *srok)
643 646 {
644 647 /*
645 648 * It is just as efficient to xdr_bytes
646 649 * an array of unknown length as to inline copy it.
647 650 */
648 651 return (xdr_bytes(xdrs, &srok->srok_data, &srok->srok_count,
649 652 NFS_MAXPATHLEN));
650 653 }
651 654
652 655 static struct xdr_discrim rdlnres_discrim[2] = {
653 656 { (int)NFS_OK, xdr_srok },
654 657 { __dontcare__, NULL_xdrproc_t }
655 658 };
656 659
657 660 /*
658 661 * Result of reading symbolic link
659 662 */
660 663 bool_t
661 664 xdr_rdlnres(XDR *xdrs, struct nfsrdlnres *rl)
662 665 {
663 666 return (xdr_union(xdrs, (enum_t *)&(rl->rl_status),
664 667 (caddr_t)&(rl->rl_srok), rdlnres_discrim, xdr_void));
665 668 }
666 669
667 670 /*
668 671 * Arguments to readdir
669 672 */
670 673 bool_t
671 674 xdr_rddirargs(XDR *xdrs, struct nfsrddirargs *rda)
672 675 {
673 676 int32_t *ptr;
674 677 int32_t *fhp;
675 678 rdma_chunkinfo_t rci;
676 679 struct xdr_ops *xops = xdrrdma_xops();
677 680
678 681 if (xdrs->x_op == XDR_FREE)
679 682 return (TRUE);
680 683
681 684 ptr = XDR_INLINE(xdrs,
682 685 RNDUP(sizeof (fhandle_t)) + 2 * BYTES_PER_XDR_UNIT);
683 686
684 687 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
685 688 xdrs->x_op == XDR_ENCODE) {
686 689 rci.rci_type = RCI_REPLY_CHUNK;
687 690 rci.rci_len = rda->rda_count;
688 691 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
689 692 }
690 693
691 694 if (ptr != NULL) {
692 695 if (xdrs->x_op == XDR_DECODE) {
693 696 fhp = (int32_t *)&rda->rda_fh;
694 697 *fhp++ = *ptr++;
695 698 *fhp++ = *ptr++;
696 699 *fhp++ = *ptr++;
697 700 *fhp++ = *ptr++;
698 701 *fhp++ = *ptr++;
699 702 *fhp++ = *ptr++;
700 703 *fhp++ = *ptr++;
701 704 *fhp = *ptr++;
702 705 rda->rda_offset = IXDR_GET_U_INT32(ptr);
703 706 rda->rda_count = IXDR_GET_U_INT32(ptr);
704 707 } else {
705 708 fhp = (int32_t *)&rda->rda_fh;
706 709 *ptr++ = *fhp++;
707 710 *ptr++ = *fhp++;
708 711 *ptr++ = *fhp++;
709 712 *ptr++ = *fhp++;
710 713 *ptr++ = *fhp++;
711 714 *ptr++ = *fhp++;
712 715 *ptr++ = *fhp++;
713 716 *ptr++ = *fhp;
714 717 IXDR_PUT_U_INT32(ptr, rda->rda_offset);
715 718 IXDR_PUT_U_INT32(ptr, rda->rda_count);
716 719 }
717 720 return (TRUE);
718 721 }
719 722
720 723 if (xdr_fhandle(xdrs, &rda->rda_fh) &&
721 724 xdr_u_int(xdrs, &rda->rda_offset) &&
722 725 xdr_u_int(xdrs, &rda->rda_count)) {
723 726 return (TRUE);
724 727 }
725 728 return (FALSE);
726 729 }
727 730
728 731
729 732 /*
730 733 * Directory read reply:
731 734 * union (enum status) {
732 735 * NFS_OK: entlist;
733 736 * boolean eof;
734 737 * default:
735 738 * }
736 739 *
737 740 * Directory entries
738 741 * struct direct {
739 742 * off_t d_off; * offset of next entry *
740 743 * u_int d_fileno; * inode number of entry *
741 744 * u_short d_reclen; * length of this record *
742 745 * u_short d_namlen; * length of string in d_name *
743 746 * char d_name[MAXNAMLEN + 1]; * name no longer than this *
744 747 * };
745 748 * are on the wire as:
746 749 * union entlist (boolean valid) {
747 750 * TRUE: struct otw_dirent;
748 751 * u_int nxtoffset;
749 752 * union entlist;
750 753 * FALSE:
751 754 * }
752 755 * where otw_dirent is:
753 756 * struct dirent {
754 757 * u_int de_fid;
755 758 * string de_name<NFS_MAXNAMELEN>;
756 759 * }
757 760 */
758 761
759 762 #ifdef nextdp
760 763 #undef nextdp
761 764 #endif
762 765 #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
763 766 #ifdef roundup
|
↓ open down ↓ |
729 lines elided |
↑ open up ↑ |
764 767 #undef roundup
765 768 #endif
766 769 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
767 770
768 771 /*
769 772 * ENCODE ONLY
770 773 */
771 774 bool_t
772 775 xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
773 776 {
774 - struct dirent64 *dp;
775 - char *name;
776 - int size;
777 - uint_t namlen;
778 777 bool_t true = TRUE;
779 778 bool_t false = FALSE;
780 - int entrysz;
781 - int tofit;
782 - int bufsize;
783 - uint32_t ino, off;
779 + struct nfsentry *entry;
784 780
785 781 if (xdrs->x_op != XDR_ENCODE)
786 782 return (FALSE);
787 783 if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
788 784 return (FALSE);
789 785 if (rd->rd_status != NFS_OK)
790 786 return (TRUE);
791 787
792 - bufsize = 1 * BYTES_PER_XDR_UNIT;
793 - for (size = rd->rd_size, dp = rd->rd_entries;
794 - size > 0;
795 - size -= dp->d_reclen, dp = nextdp(dp)) {
796 - if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
797 - return (FALSE);
798 - if (dp->d_ino == 0)
799 - continue;
800 - ino = (uint32_t)dp->d_ino; /* for LP64 we clip the bits */
801 - if (dp->d_ino != (ino64_t)ino) /* and they better be zeros */
802 - return (FALSE);
803 - off = (uint32_t)dp->d_off;
804 - name = dp->d_name;
805 - namlen = (uint_t)strlen(name);
806 - entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
807 - roundup(namlen, BYTES_PER_XDR_UNIT);
808 - tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
809 - if (bufsize + tofit > rd->rd_bufsize) {
810 - rd->rd_eof = FALSE;
811 - break;
812 - }
788 + for (entry = rd->rd_entries; entry != NULL; entry = entry->nextentry) {
813 789 if (!xdr_bool(xdrs, &true) ||
814 - !xdr_u_int(xdrs, &ino) ||
815 - !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||
816 - !xdr_u_int(xdrs, &off)) {
790 + !xdr_u_int(xdrs, &entry->fileid) ||
791 + !xdr_string(xdrs, &entry->name, NFS_MAXNAMLEN) ||
792 + !xdr_u_int(xdrs, &entry->cookie)) {
817 793 return (FALSE);
818 794 }
819 - bufsize += entrysz;
820 795 }
821 796 if (!xdr_bool(xdrs, &false))
822 797 return (FALSE);
823 798 if (!xdr_bool(xdrs, &rd->rd_eof))
824 799 return (FALSE);
825 800 return (TRUE);
826 801 }
827 802
828 803 /*
829 804 * DECODE ONLY
830 805 */
831 806 bool_t
832 807 xdr_getrddirres(XDR *xdrs, struct nfsrddirres *rd)
833 808 {
834 809 struct dirent64 *dp;
835 810 uint_t namlen;
836 811 int size;
837 812 bool_t valid;
838 813 uint32_t offset;
839 814 uint_t fileid, this_reclen;
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
840 815
841 816 if (xdrs->x_op != XDR_DECODE)
842 817 return (FALSE);
843 818
844 819 if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
845 820 return (FALSE);
846 821 if (rd->rd_status != NFS_OK)
847 822 return (TRUE);
848 823
849 824 size = rd->rd_size;
850 - dp = rd->rd_entries;
825 + dp = rd->rd_dirents;
851 826 offset = rd->rd_offset;
852 827 for (;;) {
853 828 if (!xdr_bool(xdrs, &valid))
854 829 return (FALSE);
855 830 if (!valid)
856 831 break;
857 832 if (!xdr_u_int(xdrs, &fileid) ||
858 833 !xdr_u_int(xdrs, &namlen))
859 834 return (FALSE);
860 835 this_reclen = DIRENT64_RECLEN(namlen);
861 836 if (this_reclen > size) {
862 837 rd->rd_eof = FALSE;
863 838 goto bufovflw;
864 839 }
865 840 if (!xdr_opaque(xdrs, dp->d_name, namlen)||
866 841 !xdr_u_int(xdrs, &offset)) {
867 842 return (FALSE);
868 843 }
869 844 bzero(&dp->d_name[namlen],
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
870 845 DIRENT64_NAMELEN(this_reclen) - namlen);
871 846 dp->d_ino = (ino64_t)fileid;
872 847 dp->d_reclen = this_reclen;
873 848 dp->d_off = (off64_t)offset;
874 849 size -= dp->d_reclen;
875 850 dp = nextdp(dp);
876 851 }
877 852 if (!xdr_bool(xdrs, &rd->rd_eof))
878 853 return (FALSE);
879 854 bufovflw:
880 - rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_entries));
855 + rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_dirents));
881 856 rd->rd_offset = offset;
882 857 return (TRUE);
883 858 }
884 859
885 860 /*
886 861 * Arguments for directory operations
887 862 */
888 863 bool_t
889 864 xdr_diropargs(XDR *xdrs, struct nfsdiropargs *da)
890 865 {
891 866 int32_t *ptr;
892 867 int32_t *fhp;
893 868 uint32_t size;
894 869 uint32_t nodesize;
895 870 int i;
896 871 int rndup;
897 872 char *cptr;
898 873
899 874 if (xdrs->x_op == XDR_DECODE) {
900 875 da->da_fhandle = &da->da_fhandle_buf;
901 876 ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
902 877 1 * BYTES_PER_XDR_UNIT);
903 878 if (ptr != NULL) {
904 879 fhp = (int32_t *)da->da_fhandle;
905 880 *fhp++ = *ptr++;
906 881 *fhp++ = *ptr++;
907 882 *fhp++ = *ptr++;
908 883 *fhp++ = *ptr++;
909 884 *fhp++ = *ptr++;
910 885 *fhp++ = *ptr++;
911 886 *fhp++ = *ptr++;
912 887 *fhp = *ptr++;
913 888 size = IXDR_GET_U_INT32(ptr);
914 889 if (size > NFS_MAXNAMLEN)
915 890 return (FALSE);
916 891 nodesize = size + 1;
917 892 if (nodesize == 0)
918 893 return (TRUE);
919 894 if (da->da_name == NULL) {
920 895 da->da_name = kmem_alloc(nodesize, KM_NOSLEEP);
921 896 if (da->da_name == NULL)
922 897 return (FALSE);
923 898 da->da_flags |= DA_FREENAME;
924 899 }
925 900 ptr = XDR_INLINE(xdrs, RNDUP(size));
926 901 if (ptr == NULL) {
927 902 if (!xdr_opaque(xdrs, da->da_name, size)) {
928 903 if (da->da_flags & DA_FREENAME) {
929 904 kmem_free(da->da_name,
930 905 nodesize);
931 906 da->da_name = NULL;
932 907 }
933 908 return (FALSE);
934 909 }
935 910 da->da_name[size] = '\0';
936 911 if (strlen(da->da_name) != size) {
937 912 if (da->da_flags & DA_FREENAME) {
938 913 kmem_free(da->da_name,
939 914 nodesize);
940 915 da->da_name = NULL;
941 916 }
942 917 return (FALSE);
943 918 }
944 919 return (TRUE);
945 920 }
946 921 bcopy(ptr, da->da_name, size);
947 922 da->da_name[size] = '\0';
948 923 if (strlen(da->da_name) != size) {
949 924 if (da->da_flags & DA_FREENAME) {
950 925 kmem_free(da->da_name, nodesize);
951 926 da->da_name = NULL;
952 927 }
953 928 return (FALSE);
954 929 }
955 930 return (TRUE);
956 931 }
957 932 if (da->da_name == NULL)
958 933 da->da_flags |= DA_FREENAME;
959 934 }
960 935
961 936 if (xdrs->x_op == XDR_ENCODE) {
962 937 size = (uint32_t)strlen(da->da_name);
963 938 if (size > NFS_MAXNAMLEN)
964 939 return (FALSE);
965 940 ptr = XDR_INLINE(xdrs, (int)(RNDUP(sizeof (fhandle_t)) +
966 941 1 * BYTES_PER_XDR_UNIT + RNDUP(size)));
967 942 if (ptr != NULL) {
968 943 fhp = (int32_t *)da->da_fhandle;
969 944 *ptr++ = *fhp++;
970 945 *ptr++ = *fhp++;
971 946 *ptr++ = *fhp++;
972 947 *ptr++ = *fhp++;
973 948 *ptr++ = *fhp++;
974 949 *ptr++ = *fhp++;
975 950 *ptr++ = *fhp++;
976 951 *ptr++ = *fhp;
977 952 IXDR_PUT_U_INT32(ptr, (uint32_t)size);
978 953 bcopy(da->da_name, ptr, size);
979 954 rndup = BYTES_PER_XDR_UNIT -
980 955 (size % BYTES_PER_XDR_UNIT);
981 956 if (rndup != BYTES_PER_XDR_UNIT) {
982 957 cptr = (char *)ptr + size;
983 958 for (i = 0; i < rndup; i++)
984 959 *cptr++ = '\0';
985 960 }
986 961 return (TRUE);
987 962 }
988 963 }
989 964
990 965 if (xdrs->x_op == XDR_FREE) {
991 966 if (da->da_name == NULL)
992 967 return (TRUE);
993 968 size = (uint32_t)strlen(da->da_name);
994 969 if (size > NFS_MAXNAMLEN)
995 970 return (FALSE);
996 971 if (da->da_flags & DA_FREENAME)
997 972 kmem_free(da->da_name, size + 1);
998 973 da->da_name = NULL;
999 974 return (TRUE);
1000 975 }
1001 976
1002 977 if (xdr_fhandle(xdrs, da->da_fhandle) &&
1003 978 xdr_string(xdrs, &da->da_name, NFS_MAXNAMLEN)) {
1004 979 return (TRUE);
1005 980 }
1006 981 return (FALSE);
1007 982 }
1008 983
1009 984 /*
1010 985 * NFS_OK part of directory operation result
1011 986 */
1012 987 bool_t
1013 988 xdr_drok(XDR *xdrs, struct nfsdrok *drok)
1014 989 {
1015 990 int32_t *ptr;
1016 991 int32_t *fhp;
1017 992 struct nfsfattr *na;
1018 993
1019 994 if (xdrs->x_op == XDR_FREE)
1020 995 return (TRUE);
1021 996
1022 997 ptr = XDR_INLINE(xdrs,
1023 998 RNDUP(sizeof (fhandle_t)) + 17 * BYTES_PER_XDR_UNIT);
1024 999 if (ptr != NULL) {
1025 1000 if (xdrs->x_op == XDR_DECODE) {
1026 1001 fhp = (int32_t *)&drok->drok_fhandle;
1027 1002 *fhp++ = *ptr++;
1028 1003 *fhp++ = *ptr++;
1029 1004 *fhp++ = *ptr++;
1030 1005 *fhp++ = *ptr++;
1031 1006 *fhp++ = *ptr++;
1032 1007 *fhp++ = *ptr++;
1033 1008 *fhp++ = *ptr++;
1034 1009 *fhp = *ptr++;
1035 1010 na = &drok->drok_attr;
1036 1011 na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
1037 1012 na->na_mode = IXDR_GET_U_INT32(ptr);
1038 1013 na->na_nlink = IXDR_GET_U_INT32(ptr);
1039 1014 na->na_uid = IXDR_GET_U_INT32(ptr);
1040 1015 na->na_gid = IXDR_GET_U_INT32(ptr);
1041 1016 na->na_size = IXDR_GET_U_INT32(ptr);
1042 1017 na->na_blocksize = IXDR_GET_U_INT32(ptr);
1043 1018 na->na_rdev = IXDR_GET_U_INT32(ptr);
1044 1019 na->na_blocks = IXDR_GET_U_INT32(ptr);
1045 1020 na->na_fsid = IXDR_GET_U_INT32(ptr);
1046 1021 na->na_nodeid = IXDR_GET_U_INT32(ptr);
1047 1022 na->na_atime.tv_sec = IXDR_GET_U_INT32(ptr);
1048 1023 na->na_atime.tv_usec = IXDR_GET_U_INT32(ptr);
1049 1024 na->na_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
1050 1025 na->na_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
1051 1026 na->na_ctime.tv_sec = IXDR_GET_U_INT32(ptr);
1052 1027 na->na_ctime.tv_usec = IXDR_GET_U_INT32(ptr);
1053 1028 } else {
1054 1029 fhp = (int32_t *)&drok->drok_fhandle;
1055 1030 *ptr++ = *fhp++;
1056 1031 *ptr++ = *fhp++;
1057 1032 *ptr++ = *fhp++;
1058 1033 *ptr++ = *fhp++;
1059 1034 *ptr++ = *fhp++;
1060 1035 *ptr++ = *fhp++;
1061 1036 *ptr++ = *fhp++;
1062 1037 *ptr++ = *fhp;
1063 1038 na = &drok->drok_attr;
1064 1039 IXDR_PUT_ENUM(ptr, na->na_type);
1065 1040 IXDR_PUT_U_INT32(ptr, na->na_mode);
1066 1041 IXDR_PUT_U_INT32(ptr, na->na_nlink);
1067 1042 IXDR_PUT_U_INT32(ptr, na->na_uid);
1068 1043 IXDR_PUT_U_INT32(ptr, na->na_gid);
1069 1044 IXDR_PUT_U_INT32(ptr, na->na_size);
1070 1045 IXDR_PUT_U_INT32(ptr, na->na_blocksize);
1071 1046 IXDR_PUT_U_INT32(ptr, na->na_rdev);
1072 1047 IXDR_PUT_U_INT32(ptr, na->na_blocks);
1073 1048 IXDR_PUT_U_INT32(ptr, na->na_fsid);
1074 1049 IXDR_PUT_U_INT32(ptr, na->na_nodeid);
1075 1050 IXDR_PUT_U_INT32(ptr, na->na_atime.tv_sec);
1076 1051 IXDR_PUT_U_INT32(ptr, na->na_atime.tv_usec);
1077 1052 IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_sec);
1078 1053 IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_usec);
1079 1054 IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_sec);
1080 1055 IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_usec);
1081 1056 }
1082 1057 return (TRUE);
1083 1058 }
1084 1059
1085 1060 if (xdr_fhandle(xdrs, &drok->drok_fhandle) &&
1086 1061 xdr_fattr(xdrs, &drok->drok_attr)) {
1087 1062 return (TRUE);
1088 1063 }
1089 1064 return (FALSE);
1090 1065 }
1091 1066
1092 1067 #ifdef _LITTLE_ENDIAN
1093 1068 bool_t
1094 1069 xdr_fastdrok(XDR *xdrs, struct nfsdrok *drok)
1095 1070 {
1096 1071 struct nfsfattr *na;
1097 1072
1098 1073 if (xdrs->x_op == XDR_FREE)
1099 1074 return (TRUE);
1100 1075 if (xdrs->x_op == XDR_DECODE)
1101 1076 return (FALSE);
1102 1077
1103 1078 na = &drok->drok_attr;
1104 1079 na->na_type = (enum nfsftype)htonl(na->na_type);
1105 1080 na->na_mode = (uint32_t)htonl(na->na_mode);
1106 1081 na->na_nlink = (uint32_t)htonl(na->na_nlink);
1107 1082 na->na_uid = (uint32_t)htonl(na->na_uid);
1108 1083 na->na_gid = (uint32_t)htonl(na->na_gid);
1109 1084 na->na_size = (uint32_t)htonl(na->na_size);
1110 1085 na->na_blocksize = (uint32_t)htonl(na->na_blocksize);
1111 1086 na->na_rdev = (uint32_t)htonl(na->na_rdev);
1112 1087 na->na_blocks = (uint32_t)htonl(na->na_blocks);
1113 1088 na->na_fsid = (uint32_t)htonl(na->na_fsid);
1114 1089 na->na_nodeid = (uint32_t)htonl(na->na_nodeid);
1115 1090 na->na_atime.tv_sec = htonl(na->na_atime.tv_sec);
1116 1091 na->na_atime.tv_usec = htonl(na->na_atime.tv_usec);
1117 1092 na->na_mtime.tv_sec = htonl(na->na_mtime.tv_sec);
1118 1093 na->na_mtime.tv_usec = htonl(na->na_mtime.tv_usec);
1119 1094 na->na_ctime.tv_sec = htonl(na->na_ctime.tv_sec);
1120 1095 na->na_ctime.tv_usec = htonl(na->na_ctime.tv_usec);
1121 1096 return (TRUE);
1122 1097 }
1123 1098 #endif
1124 1099
1125 1100 static struct xdr_discrim diropres_discrim[2] = {
1126 1101 { NFS_OK, xdr_drok },
1127 1102 { __dontcare__, NULL_xdrproc_t }
1128 1103 };
1129 1104
1130 1105 /*
1131 1106 * Results from directory operation
1132 1107 */
1133 1108 bool_t
1134 1109 xdr_diropres(XDR *xdrs, struct nfsdiropres *dr)
1135 1110 {
1136 1111 return (xdr_union(xdrs, (enum_t *)&(dr->dr_status),
1137 1112 (caddr_t)&(dr->dr_drok), diropres_discrim, xdr_void));
1138 1113 }
1139 1114
1140 1115 /*
1141 1116 * Results from directory operation
1142 1117 */
1143 1118 bool_t
1144 1119 xdr_fastdiropres(XDR *xdrs, struct nfsdiropres *dr)
1145 1120 {
1146 1121 #if defined(_LITTLE_ENDIAN)
1147 1122 /*
1148 1123 * we deal with the discriminator; it's an enum
1149 1124 */
1150 1125 if (!xdr_fastenum(xdrs, (enum_t *)&dr->dr_status))
1151 1126 return (FALSE);
1152 1127
1153 1128 if (dr->dr_status == NFS_OK)
1154 1129 return (xdr_fastdrok(xdrs, &dr->dr_drok));
1155 1130 #elif defined(_BIG_ENDIAN)
1156 1131 if (dr->dr_status == NFS_OK)
1157 1132 return (TRUE);
1158 1133 #endif
1159 1134 return (xdr_fastshorten(xdrs, sizeof (*dr)));
1160 1135 }
1161 1136
1162 1137 /*
1163 1138 * Time Structure, unsigned
1164 1139 */
1165 1140 bool_t
1166 1141 xdr_nfs2_timeval(XDR *xdrs, struct nfs2_timeval *tv)
1167 1142 {
1168 1143 if (xdr_u_int(xdrs, &tv->tv_sec) &&
1169 1144 xdr_u_int(xdrs, &tv->tv_usec))
1170 1145 return (TRUE);
1171 1146 return (FALSE);
1172 1147 }
1173 1148
1174 1149 /*
1175 1150 * arguments to setattr
1176 1151 */
1177 1152 bool_t
1178 1153 xdr_saargs(XDR *xdrs, struct nfssaargs *argp)
1179 1154 {
1180 1155 int32_t *ptr;
1181 1156 int32_t *arg;
1182 1157 struct nfssattr *sa;
1183 1158
1184 1159 if (xdrs->x_op == XDR_FREE)
1185 1160 return (TRUE);
1186 1161
1187 1162 ptr = XDR_INLINE(xdrs,
1188 1163 RNDUP(sizeof (fhandle_t)) + 8 * BYTES_PER_XDR_UNIT);
1189 1164 if (ptr != NULL) {
1190 1165 if (xdrs->x_op == XDR_DECODE) {
1191 1166 arg = (int32_t *)&argp->saa_fh;
1192 1167 *arg++ = *ptr++;
1193 1168 *arg++ = *ptr++;
1194 1169 *arg++ = *ptr++;
1195 1170 *arg++ = *ptr++;
1196 1171 *arg++ = *ptr++;
1197 1172 *arg++ = *ptr++;
1198 1173 *arg++ = *ptr++;
1199 1174 *arg = *ptr++;
1200 1175 sa = &argp->saa_sa;
1201 1176 sa->sa_mode = IXDR_GET_U_INT32(ptr);
1202 1177 sa->sa_uid = IXDR_GET_U_INT32(ptr);
1203 1178 sa->sa_gid = IXDR_GET_U_INT32(ptr);
1204 1179 sa->sa_size = IXDR_GET_U_INT32(ptr);
1205 1180 sa->sa_atime.tv_sec = IXDR_GET_U_INT32(ptr);
1206 1181 sa->sa_atime.tv_usec = IXDR_GET_U_INT32(ptr);
1207 1182 sa->sa_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
1208 1183 sa->sa_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
1209 1184 } else {
1210 1185 arg = (int32_t *)&argp->saa_fh;
1211 1186 *ptr++ = *arg++;
1212 1187 *ptr++ = *arg++;
1213 1188 *ptr++ = *arg++;
1214 1189 *ptr++ = *arg++;
1215 1190 *ptr++ = *arg++;
1216 1191 *ptr++ = *arg++;
1217 1192 *ptr++ = *arg++;
1218 1193 *ptr++ = *arg;
1219 1194 sa = &argp->saa_sa;
1220 1195 IXDR_PUT_U_INT32(ptr, sa->sa_mode);
1221 1196 IXDR_PUT_U_INT32(ptr, sa->sa_uid);
1222 1197 IXDR_PUT_U_INT32(ptr, sa->sa_gid);
1223 1198 IXDR_PUT_U_INT32(ptr, sa->sa_size);
1224 1199 IXDR_PUT_U_INT32(ptr, sa->sa_atime.tv_sec);
1225 1200 IXDR_PUT_U_INT32(ptr, sa->sa_atime.tv_usec);
1226 1201 IXDR_PUT_U_INT32(ptr, sa->sa_mtime.tv_sec);
1227 1202 IXDR_PUT_U_INT32(ptr, sa->sa_mtime.tv_usec);
1228 1203 }
1229 1204 return (TRUE);
1230 1205 }
1231 1206
1232 1207 if (xdr_fhandle(xdrs, &argp->saa_fh) &&
1233 1208 xdr_sattr(xdrs, &argp->saa_sa)) {
1234 1209 return (TRUE);
1235 1210 }
1236 1211 return (FALSE);
1237 1212 }
1238 1213
1239 1214
1240 1215 /*
1241 1216 * arguments to create and mkdir
1242 1217 */
1243 1218 bool_t
1244 1219 xdr_creatargs(XDR *xdrs, struct nfscreatargs *argp)
1245 1220 {
1246 1221 argp->ca_sa = &argp->ca_sa_buf;
1247 1222
1248 1223 if (xdrs->x_op == XDR_DECODE)
1249 1224 argp->ca_sa = &argp->ca_sa_buf;
1250 1225 if (xdr_diropargs(xdrs, &argp->ca_da) &&
1251 1226 xdr_sattr(xdrs, argp->ca_sa)) {
1252 1227 return (TRUE);
1253 1228 }
1254 1229 return (FALSE);
1255 1230 }
1256 1231
1257 1232 /*
1258 1233 * arguments to link
1259 1234 */
1260 1235 bool_t
1261 1236 xdr_linkargs(XDR *xdrs, struct nfslinkargs *argp)
1262 1237 {
1263 1238 if (xdrs->x_op == XDR_DECODE)
1264 1239 argp->la_from = &argp->la_from_buf;
1265 1240 if (xdr_fhandle(xdrs, argp->la_from) &&
1266 1241 xdr_diropargs(xdrs, &argp->la_to)) {
1267 1242 return (TRUE);
1268 1243 }
1269 1244 return (FALSE);
1270 1245 }
1271 1246
1272 1247 /*
1273 1248 * arguments to rename
1274 1249 */
1275 1250 bool_t
1276 1251 xdr_rnmargs(XDR *xdrs, struct nfsrnmargs *argp)
1277 1252 {
1278 1253 if (xdr_diropargs(xdrs, &argp->rna_from) &&
1279 1254 xdr_diropargs(xdrs, &argp->rna_to))
1280 1255 return (TRUE);
1281 1256 return (FALSE);
1282 1257 }
1283 1258
1284 1259
1285 1260 /*
1286 1261 * arguments to symlink
1287 1262 */
1288 1263 bool_t
1289 1264 xdr_slargs(XDR *xdrs, struct nfsslargs *argp)
1290 1265 {
1291 1266 if (xdrs->x_op == XDR_FREE) {
1292 1267 if (!xdr_diropargs(xdrs, &argp->sla_from))
1293 1268 return (FALSE);
1294 1269 if ((argp->sla_tnm_flags & SLA_FREETNM) &&
1295 1270 !xdr_string(xdrs, &argp->sla_tnm, (uint_t)NFS_MAXPATHLEN))
1296 1271 return (FALSE);
1297 1272 return (TRUE);
1298 1273 }
1299 1274
1300 1275 if (xdrs->x_op == XDR_DECODE) {
1301 1276 argp->sla_sa = &argp->sla_sa_buf;
1302 1277 if (argp->sla_tnm == NULL)
1303 1278 argp->sla_tnm_flags |= SLA_FREETNM;
1304 1279 }
1305 1280
1306 1281 if (xdr_diropargs(xdrs, &argp->sla_from) &&
1307 1282 xdr_string(xdrs, &argp->sla_tnm, (uint_t)NFS_MAXPATHLEN) &&
1308 1283 xdr_sattr(xdrs, argp->sla_sa)) {
1309 1284 return (TRUE);
1310 1285 }
1311 1286 return (FALSE);
1312 1287 }
1313 1288
1314 1289
1315 1290 /*
1316 1291 * NFS_OK part of statfs operation
1317 1292 */
1318 1293 bool_t
1319 1294 xdr_fsok(XDR *xdrs, struct nfsstatfsok *fsok)
1320 1295 {
1321 1296 int32_t *ptr;
1322 1297
1323 1298 if (xdrs->x_op == XDR_FREE)
1324 1299 return (TRUE);
1325 1300
1326 1301 ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT);
1327 1302 if (ptr != NULL) {
1328 1303 if (xdrs->x_op == XDR_DECODE) {
1329 1304 fsok->fsok_tsize = IXDR_GET_INT32(ptr);
1330 1305 fsok->fsok_bsize = IXDR_GET_INT32(ptr);
1331 1306 fsok->fsok_blocks = IXDR_GET_INT32(ptr);
1332 1307 fsok->fsok_bfree = IXDR_GET_INT32(ptr);
1333 1308 fsok->fsok_bavail = IXDR_GET_INT32(ptr);
1334 1309 } else {
1335 1310 IXDR_PUT_INT32(ptr, fsok->fsok_tsize);
1336 1311 IXDR_PUT_INT32(ptr, fsok->fsok_bsize);
1337 1312 IXDR_PUT_INT32(ptr, fsok->fsok_blocks);
1338 1313 IXDR_PUT_INT32(ptr, fsok->fsok_bfree);
1339 1314 IXDR_PUT_INT32(ptr, fsok->fsok_bavail);
1340 1315 }
1341 1316 return (TRUE);
1342 1317 }
1343 1318
1344 1319 if (xdr_u_int(xdrs, &fsok->fsok_tsize) &&
1345 1320 xdr_u_int(xdrs, &fsok->fsok_bsize) &&
1346 1321 xdr_u_int(xdrs, &fsok->fsok_blocks) &&
1347 1322 xdr_u_int(xdrs, &fsok->fsok_bfree) &&
1348 1323 xdr_u_int(xdrs, &fsok->fsok_bavail)) {
1349 1324 return (TRUE);
1350 1325 }
1351 1326 return (FALSE);
1352 1327 }
1353 1328
1354 1329 #ifdef _LITTLE_ENDIAN
1355 1330 bool_t
1356 1331 xdr_fastfsok(XDR *xdrs, struct nfsstatfsok *fsok)
1357 1332 {
1358 1333
1359 1334 if (xdrs->x_op == XDR_FREE)
1360 1335 return (TRUE);
1361 1336 if (xdrs->x_op == XDR_DECODE)
1362 1337 return (FALSE);
1363 1338
1364 1339 fsok->fsok_tsize = htonl(fsok->fsok_tsize);
1365 1340 fsok->fsok_bsize = htonl(fsok->fsok_bsize);
1366 1341 fsok->fsok_blocks = htonl(fsok->fsok_blocks);
1367 1342 fsok->fsok_bfree = htonl(fsok->fsok_bfree);
1368 1343 fsok->fsok_bavail = htonl(fsok->fsok_bavail);
1369 1344 return (TRUE);
1370 1345 }
1371 1346 #endif
1372 1347
1373 1348 static struct xdr_discrim statfs_discrim[2] = {
1374 1349 { NFS_OK, xdr_fsok },
1375 1350 { __dontcare__, NULL_xdrproc_t }
1376 1351 };
1377 1352
1378 1353 /*
1379 1354 * Results of statfs operation
1380 1355 */
1381 1356 bool_t
1382 1357 xdr_statfs(XDR *xdrs, struct nfsstatfs *fs)
1383 1358 {
1384 1359 return (xdr_union(xdrs, (enum_t *)&(fs->fs_status),
1385 1360 (caddr_t)&(fs->fs_fsok), statfs_discrim, xdr_void));
1386 1361 }
1387 1362
1388 1363 /*
1389 1364 * Results of statfs operation
1390 1365 */
1391 1366 bool_t
1392 1367 xdr_faststatfs(XDR *xdrs, struct nfsstatfs *fs)
1393 1368 {
1394 1369 #if defined(_LITTLE_ENDIAN)
1395 1370 /*
1396 1371 * we deal with the discriminator; it's an enum
1397 1372 */
1398 1373 if (!xdr_fastenum(xdrs, (enum_t *)&fs->fs_status))
1399 1374 return (FALSE);
1400 1375
1401 1376 if (fs->fs_status == NFS_OK)
1402 1377 return (xdr_fastfsok(xdrs, &fs->fs_fsok));
1403 1378 #elif defined(_BIG_ENDIAN)
1404 1379 if (fs->fs_status == NFS_OK)
1405 1380 return (TRUE);
1406 1381 #endif
1407 1382 return (xdr_fastshorten(xdrs, sizeof (*fs)));
1408 1383 }
1409 1384
1410 1385 #ifdef _LITTLE_ENDIAN
1411 1386 /*
1412 1387 * XDR enumerations
1413 1388 */
1414 1389 #ifndef lint
1415 1390 static enum sizecheck { SIZEVAL } sizecheckvar; /* used to find the size of */
1416 1391 /* an enum */
1417 1392 #endif
1418 1393 bool_t
1419 1394 xdr_fastenum(XDR *xdrs, enum_t *ep)
1420 1395 {
1421 1396 if (xdrs->x_op == XDR_FREE)
1422 1397 return (TRUE);
1423 1398 if (xdrs->x_op == XDR_DECODE)
1424 1399 return (FALSE);
1425 1400
1426 1401 #ifndef lint
1427 1402 /*
1428 1403 * enums are treated as ints
1429 1404 */
1430 1405 if (sizeof (sizecheckvar) == sizeof (int32_t)) {
1431 1406 *ep = (enum_t)htonl((int32_t)(*ep));
1432 1407 } else if (sizeof (sizecheckvar) == sizeof (short)) {
1433 1408 *ep = (enum_t)htons((short)(*ep));
1434 1409 } else {
1435 1410 return (FALSE);
1436 1411 }
1437 1412 return (TRUE);
1438 1413 #else
1439 1414 (void) (xdr_short(xdrs, (short *)ep));
1440 1415 return (xdr_int(xdrs, (int *)ep));
1441 1416 #endif
1442 1417 }
1443 1418 #endif
1444 1419
1445 1420 static bool_t
1446 1421 xdr_fastshorten(XDR *xdrs, uint_t ressize)
1447 1422 {
1448 1423 uint_t curpos;
1449 1424
1450 1425 curpos = XDR_GETPOS(xdrs);
1451 1426 ressize -= BYTES_PER_XDR_UNIT;
1452 1427 curpos -= ressize;
1453 1428 return (XDR_SETPOS(xdrs, curpos));
1454 1429 }
|
↓ open down ↓ |
564 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX