Sdiff nfs3_xdr.c


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 /*