aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/linux/sunrpc/xprt.h4
-rw-r--r--net/sunrpc/xprt.c31
-rw-r--r--net/sunrpc/xprtsock.c73
3 files changed, 61 insertions, 47 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 0321fb53bd02..d7919010863d 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -265,8 +265,8 @@ void xprt_disconnect(struct rpc_xprt *xprt);
265/* 265/*
266 * Socket transport setup operations 266 * Socket transport setup operations
267 */ 267 */
268int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to); 268struct rpc_xprt * xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to);
269int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to); 269struct rpc_xprt * xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to);
270 270
271/* 271/*
272 * Reserved bit positions in xprt->state 272 * Reserved bit positions in xprt->state
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 80857470dc11..8cc2afa2942c 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -891,39 +891,25 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
891 */ 891 */
892struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to) 892struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
893{ 893{
894 int result;
895 struct rpc_xprt *xprt; 894 struct rpc_xprt *xprt;
896 struct rpc_rqst *req; 895 struct rpc_rqst *req;
897 896
898 if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) {
899 dprintk("RPC: xprt_create_transport: no memory\n");
900 return ERR_PTR(-ENOMEM);
901 }
902 if (size <= sizeof(xprt->addr)) {
903 memcpy(&xprt->addr, ap, size);
904 xprt->addrlen = size;
905 } else {
906 kfree(xprt);
907 dprintk("RPC: xprt_create_transport: address too large\n");
908 return ERR_PTR(-EBADF);
909 }
910
911 switch (proto) { 897 switch (proto) {
912 case IPPROTO_UDP: 898 case IPPROTO_UDP:
913 result = xs_setup_udp(xprt, to); 899 xprt = xs_setup_udp(ap, size, to);
914 break; 900 break;
915 case IPPROTO_TCP: 901 case IPPROTO_TCP:
916 result = xs_setup_tcp(xprt, to); 902 xprt = xs_setup_tcp(ap, size, to);
917 break; 903 break;
918 default: 904 default:
919 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", 905 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
920 proto); 906 proto);
921 return ERR_PTR(-EIO); 907 return ERR_PTR(-EIO);
922 } 908 }
923 if (result) { 909 if (IS_ERR(xprt)) {
924 kfree(xprt); 910 dprintk("RPC: xprt_create_transport: failed, %ld\n",
925 dprintk("RPC: xprt_create_transport: failed, %d\n", result); 911 -PTR_ERR(xprt));
926 return ERR_PTR(result); 912 return xprt;
927 } 913 }
928 914
929 kref_init(&xprt->kref); 915 kref_init(&xprt->kref);
@@ -969,8 +955,11 @@ static void xprt_destroy(struct kref *kref)
969 dprintk("RPC: destroying transport %p\n", xprt); 955 dprintk("RPC: destroying transport %p\n", xprt);
970 xprt->shutdown = 1; 956 xprt->shutdown = 1;
971 del_timer_sync(&xprt->timer); 957 del_timer_sync(&xprt->timer);
958
959 /*
960 * Tear down transport state and free the rpc_xprt
961 */
972 xprt->ops->destroy(xprt); 962 xprt->ops->destroy(xprt);
973 kfree(xprt);
974} 963}
975 964
976/** 965/**
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}