diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2006-10-17 14:44:27 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-06 10:46:34 -0500 |
commit | c8541ecdd5692bcfbcb5305cab9a873288d29175 (patch) | |
tree | 45714725337f22a5eb27cbe5b87c3b01f37c9490 /net/sunrpc/xprtsock.c | |
parent | e744cf2e3ab8535a8494a4cf0177de26f94586da (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.c | 73 |
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 | ||
523 | static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) | 524 | static 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 | ||
1343 | static 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 | */ |
1348 | int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | 1380 | struct 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 | */ |
1394 | int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | 1423 | struct 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 | } |