10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "@(#)nfs3_xdr.c 1.62 05/06/08 SMI"
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/user.h>
36 #include <sys/vnode.h>
37 #include <sys/file.h>
38 #include <sys/dirent.h>
39 #include <sys/vfs.h>
40 #include <sys/stream.h>
41 #include <sys/strsubr.h>
42 #include <sys/debug.h>
43 #include <sys/t_lock.h>
44 #include <sys/cmn_err.h>
45 #include <sys/dnlc.h>
46 #include <sys/cred.h>
47 #include <sys/time.h>
48
49 #include <rpc/types.h>
50 #include <rpc/xdr.h>
51
52 #include <nfs/nfs.h>
53 #include <nfs/rnode.h>
54
55 /* Checks if the fh is 32 bytes and returns TRUE if it is, otherwise FALSE */
56 #define XDR_CHECKFHSIZE(x, len, sz) \
57 (((int32_t)ntohl(len) == NFS3_CURFHSIZE) ? TRUE : \
58 (xdr_rewind(x, sz), FALSE))
59
60 /*
61 * These are the XDR routines used to serialize and deserialize
62 * the various structures passed as parameters across the network
63 * between NFS clients and servers.
64 */
65
66 /*
67 * XDR null terminated ASCII strings
68 * xdr_string3 deals with "C strings" - arrays of bytes that are
69 * terminated by a NULL character. The parameter cpp references a
70 * pointer to storage; If the pointer is null, then the necessary
71 * storage is allocated. The last parameter is the max allowed length
72 * of the string as allowed by the system. The NFS Version 3 protocol
73 * does not place limits on strings, but the implementation needs to
1255 xdr_u_int(xdrs, &resokp->count) == FALSE ||
1256 xdr_bool(xdrs, &resokp->eof) == FALSE) {
1257 return (FALSE);
1258 }
1259
1260 if (xdrs->x_op == XDR_ENCODE) {
1261 int i, rndup;
1262
1263 mp = resokp->data.mp;
1264 if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
1265 mp->b_wptr += resokp->count;
1266 rndup = BYTES_PER_XDR_UNIT -
1267 (resokp->data.data_len % BYTES_PER_XDR_UNIT);
1268 if (rndup != BYTES_PER_XDR_UNIT)
1269 for (i = 0; i < rndup; i++)
1270 *mp->b_wptr++ = '\0';
1271 if (xdrmblk_putmblk(xdrs, mp, resokp->count) == TRUE) {
1272 resokp->data.mp = NULL;
1273 return (TRUE);
1274 }
1275 }
1276 /*
1277 * Fall thru for the xdr_bytes()
1278 *
1279 * note: the mblk will be freed in
1280 * rfs3_read_free.
1281 */
1282 }
1283
1284 ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
1285 &resokp->data.data_len, nfs3tsize());
1286
1287 return (ret);
1288 }
1289
1290 bool_t
1291 xdr_READ3vres(XDR *xdrs, READ3vres *objp)
1292 {
1293 /*
1294 * DECODE or FREE only
1295 */
1296 if (xdrs->x_op == XDR_FREE)
1297 return (TRUE);
1298
1299 if (xdrs->x_op != XDR_DECODE)
1300 return (FALSE);
1301
1302 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1303 return (FALSE);
1304
1305 if (!xdr_post_op_vattr(xdrs, &objp->pov))
1306 return (FALSE);
1307
1308 if (objp->status != NFS3_OK)
1309 return (TRUE);
1310
1311 if (!xdr_u_int(xdrs, &objp->count))
1312 return (FALSE);
1313
1314 if (!xdr_bool(xdrs, &objp->eof))
1315 return (FALSE);
1316
1317 return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1318 &objp->data.data_len, nfs3tsize()));
1319 }
1320
1321 bool_t
1322 xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
1323 {
1324 bool_t attributes;
1325 mblk_t *mp;
1326 size_t n;
1327 int error;
1328 int size = (int)objp->size;
1329 struct uio *uiop = objp->uiop;
1330 int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
1331 int32_t *ptr;
1332
1333 /*
1334 * DECODE or FREE only
1335 */
1336 if (xdrs->x_op == XDR_FREE)
1337 return (TRUE);
1338
1339 if (xdrs->x_op != XDR_DECODE)
1340 return (FALSE);
1341
1342 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
1343 return (FALSE);
1379 return (FALSE);
1380
1381 size = (int)objp->size;
1382 do {
1383 n = MIN(size, mp->b_wptr - mp->b_rptr);
1384 if ((n = MIN(uiop->uio_resid, n)) != 0) {
1385
1386 error = uiomove((char *)mp->b_rptr, n, UIO_READ,
1387 uiop);
1388 if (error)
1389 return (FALSE);
1390 mp->b_rptr += n;
1391 size -= n;
1392 }
1393
1394 while (mp && (mp->b_rptr >= mp->b_wptr))
1395 mp = mp->b_cont;
1396 } while (mp && size > 0 && uiop->uio_resid > 0);
1397
1398 return (TRUE);
1399 }
1400
1401 /*
1402 * This isn't an xdrmblk stream. Handle the likely
1403 * case that it can be inlined (ex. xdrmem).
1404 */
1405 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
1406 return (FALSE);
1407
1408 if (objp->size == 0)
1409 return (TRUE);
1410
1411 if (objp->size > size)
1412 return (FALSE);
1413
1414 size = (int)objp->size;
1415 if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
1416 return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
1417
1418 /*
|
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /* Copyright (c) 2006, The Ohio State University. All rights reserved.
31 *
32 * Portions of this source code is developed by the team members of
33 * The Ohio State University's Network-Based Computing Laboratory (NBCL),
34 * headed by Professor Dhabaleswar K. (DK) Panda.
35 *
36 * Acknowledgements to contributions from developors:
37 * Ranjit Noronha: noronha@cse.ohio-state.edu
38 * Lei Chai : chail@cse.ohio-state.edu
39 * Weikuan Yu : yuw@cse.ohio-state.edu
40 *
41 */
42 #pragma ident "@(#)nfs3_xdr.c 1.62 05/06/08 SMI"
43
44 #include <sys/param.h>
45 #include <sys/types.h>
46 #include <sys/systm.h>
47 #include <sys/user.h>
48 #include <sys/vnode.h>
49 #include <sys/file.h>
50 #include <sys/dirent.h>
51 #include <sys/vfs.h>
52 #include <sys/stream.h>
53 #include <sys/strsubr.h>
54 #include <sys/debug.h>
55 #include <sys/t_lock.h>
56 #include <sys/cmn_err.h>
57 #include <sys/dnlc.h>
58 #include <sys/cred.h>
59 #include <sys/time.h>
60
61 #include <rpc/types.h>
62 #include <rpc/xdr.h>
63
64 #include <nfs/nfs.h>
65 #include <nfs/rnode.h>
66 #include <rpc/rpc_rdma.h>
67
68 /* Checks if the fh is 32 bytes and returns TRUE if it is, otherwise FALSE */
69 #define XDR_CHECKFHSIZE(x, len, sz) \
70 (((int32_t)ntohl(len) == NFS3_CURFHSIZE) ? TRUE : \
71 (xdr_rewind(x, sz), FALSE))
72
73 /*
74 * These are the XDR routines used to serialize and deserialize
75 * the various structures passed as parameters across the network
76 * between NFS clients and servers.
77 */
78
79 /*
80 * XDR null terminated ASCII strings
81 * xdr_string3 deals with "C strings" - arrays of bytes that are
82 * terminated by a NULL character. The parameter cpp references a
83 * pointer to storage; If the pointer is null, then the necessary
84 * storage is allocated. The last parameter is the max allowed length
85 * of the string as allowed by the system. The NFS Version 3 protocol
86 * does not place limits on strings, but the implementation needs to
1268 xdr_u_int(xdrs, &resokp->count) == FALSE ||
1269 xdr_bool(xdrs, &resokp->eof) == FALSE) {
1270 return (FALSE);
1271 }
1272
1273 if (xdrs->x_op == XDR_ENCODE) {
1274 int i, rndup;
1275
1276 mp = resokp->data.mp;
1277 if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
1278 mp->b_wptr += resokp->count;
1279 rndup = BYTES_PER_XDR_UNIT -
1280 (resokp->data.data_len % BYTES_PER_XDR_UNIT);
1281 if (rndup != BYTES_PER_XDR_UNIT)
1282 for (i = 0; i < rndup; i++)
1283 *mp->b_wptr++ = '\0';
1284 if (xdrmblk_putmblk(xdrs, mp, resokp->count) == TRUE) {
1285 resokp->data.mp = NULL;
1286 return (TRUE);
1287 }
1288
1289 } else {
1290 if(xdr_u_int(xdrs, &resokp->count) == FALSE){
1291 return (FALSE);
1292 }
1293 /*
1294 * If read data sent by wlist (RDMA_WRITE), don't do
1295 * xdr_bytes() below. RDMA_WRITE transfers the data.
1296 * Note: this is encode-only because the client code
1297 * uses xdr_READ3vres/xdr_READ3uiores to decode results.
1298 */
1299 if (resokp->wlist) {
1300 /*clist_free(resokp->wlist);*/
1301 return (TRUE);
1302 }
1303 }
1304
1305 /*
1306 * Fall thru for the xdr_bytes()
1307 *
1308 * note: the mblk will be freed in
1309 * rfs3_read_free.
1310 */
1311 }
1312
1313 /* no RDMA_WRITE transfer -- send data inline */
1314
1315 ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
1316 &resokp->data.data_len, nfs3tsize());
1317 return (ret);
1318 }
1319
1320 bool_t
1321 xdr_READ3vres(XDR *xdrs, READ3vres *objp)
1322 {
1323 count3 ocount;
1324 /*
1325 * DECODE or FREE only
1326 */
1327 if (xdrs->x_op == XDR_FREE)
1328 return (TRUE);
1329
1330 if (xdrs->x_op != XDR_DECODE)
1331 return (FALSE);
1332
1333 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1334 return (FALSE);
1335
1336 if (!xdr_post_op_vattr(xdrs, &objp->pov))
1337 return (FALSE);
1338
1339 if (objp->status != NFS3_OK)
1340 return (TRUE);
1341
1342 if (!xdr_u_int(xdrs, &objp->count))
1343 return (FALSE);
1344
1345 if (!xdr_bool(xdrs, &objp->eof))
1346 return (FALSE);
1347
1348 /*
1349 * If read data received via RDMA_WRITE, don't do xdr_bytes().
1350 * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
1351 */
1352 if (objp->wlist) {
1353 if (!xdr_u_int(xdrs, &ocount))
1354 return (FALSE);
1355 if(ocount != objp->count){
1356 cmn_err(CE_NOTE,"NFS: READ count doesn't match RPC opaque count.\n");
1357 return(FALSE);
1358 }
1359 objp->data.data_len = objp->wlist_len;
1360 clist_free(objp->wlist);
1361 return (TRUE);
1362 }
1363
1364 return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1365 &objp->data.data_len, nfs3tsize()));
1366 }
1367
1368 bool_t
1369 xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
1370 {
1371 count3 ocount;
1372 bool_t attributes;
1373 mblk_t *mp;
1374 size_t n;
1375 int error;
1376 int size = (int)objp->size;
1377 struct uio *uiop = objp->uiop;
1378 int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
1379 int32_t *ptr;
1380
1381 /*
1382 * DECODE or FREE only
1383 */
1384 if (xdrs->x_op == XDR_FREE)
1385 return (TRUE);
1386
1387 if (xdrs->x_op != XDR_DECODE)
1388 return (FALSE);
1389
1390 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
1391 return (FALSE);
1427 return (FALSE);
1428
1429 size = (int)objp->size;
1430 do {
1431 n = MIN(size, mp->b_wptr - mp->b_rptr);
1432 if ((n = MIN(uiop->uio_resid, n)) != 0) {
1433
1434 error = uiomove((char *)mp->b_rptr, n, UIO_READ,
1435 uiop);
1436 if (error)
1437 return (FALSE);
1438 mp->b_rptr += n;
1439 size -= n;
1440 }
1441
1442 while (mp && (mp->b_rptr >= mp->b_wptr))
1443 mp = mp->b_cont;
1444 } while (mp && size > 0 && uiop->uio_resid > 0);
1445
1446 return (TRUE);
1447 }
1448
1449 if (objp->wlist) {
1450 if (!xdr_u_int(xdrs, &ocount))
1451 return (FALSE);
1452 if(ocount != objp->count){
1453 cmn_err(CE_NOTE,"NFS: READ count doesn't match RPC opaque count.\n");
1454 return(FALSE);
1455 }
1456 /*
1457 * XXX: Assume 1 iov, needs to be changed.
1458 */
1459 uiop->uio_resid -= objp->count;
1460 uiop->uio_iov->iov_len -= objp->count;
1461 uiop->uio_iov->iov_base += objp->count;
1462 uiop->uio_loffset += objp->count;
1463 objp->size = objp->wlist_len;
1464 clist_free(objp->wlist);
1465
1466 return (TRUE);
1467 }
1468
1469 /*
1470 * This isn't an xdrmblk stream. Handle the likely
1471 * case that it can be inlined (ex. xdrmem).
1472 */
1473 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
1474 return (FALSE);
1475
1476 if (objp->size == 0)
1477 return (TRUE);
1478
1479 if (objp->size > size)
1480 return (FALSE);
1481
1482 size = (int)objp->size;
1483 if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
1484 return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
1485
1486 /*
|