aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2006-10-17 14:44:27 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-12-06 10:46:34 -0500
commitc8541ecdd5692bcfbcb5305cab9a873288d29175 (patch)
tree45714725337f22a5eb27cbe5b87c3b01f37c9490 /net/sunrpc/xprtsock.c
parente744cf2e3ab8535a8494a4cf0177de26f94586da (diff)
SUNRPC: Make the transport-specific setup routine allocate rpc_xprt
Change the location where the rpc_xprt structure is allocated so each transport implementation can allocate a private area from the same chunk of memory. Note also that xprt->ops->destroy, rather than xprt_destroy, is now responsible for freeing rpc_xprt when the transport is destroyed. Test plan: Connectathon. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 25620851d4bf..ec3462f141b4 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -518,6 +518,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
518 xs_close(xprt); 518 xs_close(xprt);
519 xs_free_peer_addresses(xprt); 519 xs_free_peer_addresses(xprt);
520 kfree(xprt->slot); 520 kfree(xprt->slot);
521 kfree(xprt);
521} 522}
522 523
523static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) 524static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -1339,26 +1340,53 @@ static struct rpc_xprt_ops xs_tcp_ops = {
1339 .print_stats = xs_tcp_print_stats, 1340 .print_stats = xs_tcp_print_stats,
1340}; 1341};
1341 1342
1343static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size)
1344{
1345 struct rpc_xprt *xprt;
1346
1347 if (addrlen > sizeof(xprt->addr)) {
1348 dprintk("RPC: xs_setup_xprt: address too large\n");
1349 return ERR_PTR(-EBADF);
1350 }
1351
1352 xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL);
1353 if (xprt == NULL) {
1354 dprintk("RPC: xs_setup_xprt: couldn't allocate rpc_xprt\n");
1355 return ERR_PTR(-ENOMEM);
1356 }
1357
1358 xprt->max_reqs = slot_table_size;
1359 xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL);
1360 if (xprt->slot == NULL) {
1361 kfree(xprt);
1362 dprintk("RPC: xs_setup_xprt: couldn't allocate slot table\n");
1363 return ERR_PTR(-ENOMEM);
1364 }
1365
1366 memcpy(&xprt->addr, addr, addrlen);
1367 xprt->addrlen = addrlen;
1368 xprt->port = xs_get_random_port();
1369
1370 return xprt;
1371}
1372
1342/** 1373/**
1343 * xs_setup_udp - Set up transport to use a UDP socket 1374 * xs_setup_udp - Set up transport to use a UDP socket
1344 * @xprt: transport to set up 1375 * @addr: address of remote server
1376 * @addrlen: length of address in bytes
1345 * @to: timeout parameters 1377 * @to: timeout parameters
1346 * 1378 *
1347 */ 1379 */
1348int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) 1380struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
1349{ 1381{
1350 size_t slot_table_size; 1382 struct rpc_xprt *xprt;
1351 struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
1352 1383
1353 xprt->max_reqs = xprt_udp_slot_table_entries; 1384 xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
1354 slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); 1385 if (IS_ERR(xprt))
1355 xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); 1386 return xprt;
1356 if (xprt->slot == NULL)
1357 return -ENOMEM;
1358 1387
1359 if (ntohs(addr->sin_port) != 0) 1388 if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
1360 xprt_set_bound(xprt); 1389 xprt_set_bound(xprt);
1361 xprt->port = xs_get_random_port();
1362 1390
1363 xprt->prot = IPPROTO_UDP; 1391 xprt->prot = IPPROTO_UDP;
1364 xprt->tsh_size = 0; 1392 xprt->tsh_size = 0;
@@ -1382,29 +1410,26 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
1382 dprintk("RPC: set up transport to address %s\n", 1410 dprintk("RPC: set up transport to address %s\n",
1383 xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); 1411 xs_print_peer_address(xprt, RPC_DISPLAY_ALL));
1384 1412
1385 return 0; 1413 return xprt;
1386} 1414}
1387 1415
1388/** 1416/**
1389 * xs_setup_tcp - Set up transport to use a TCP socket 1417 * xs_setup_tcp - Set up transport to use a TCP socket
1390 * @xprt: transport to set up 1418 * @addr: address of remote server
1419 * @addrlen: length of address in bytes
1391 * @to: timeout parameters 1420 * @to: timeout parameters
1392 * 1421 *
1393 */ 1422 */
1394int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) 1423struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
1395{ 1424{
1396 size_t slot_table_size; 1425 struct rpc_xprt *xprt;
1397 struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
1398 1426
1399 xprt->max_reqs = xprt_tcp_slot_table_entries; 1427 xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
1400 slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); 1428 if (IS_ERR(xprt))
1401 xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); 1429 return xprt;
1402 if (xprt->slot == NULL)
1403 return -ENOMEM;
1404 1430
1405 if (ntohs(addr->sin_port) != 0) 1431 if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
1406 xprt_set_bound(xprt); 1432 xprt_set_bound(xprt);
1407 xprt->port = xs_get_random_port();
1408 1433
1409 xprt->prot = IPPROTO_TCP; 1434 xprt->prot = IPPROTO_TCP;
1410 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); 1435 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
@@ -1427,5 +1452,5 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
1427 dprintk("RPC: set up transport to address %s\n", 1452 dprintk("RPC: set up transport to address %s\n",
1428 xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); 1453 xs_print_peer_address(xprt, RPC_DISPLAY_ALL));
1429 1454
1430 return 0; 1455 return xprt;
1431} 1456}