diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index c737acf61c75..4797a4608c07 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -145,6 +145,12 @@ struct sock_xprt { | |||
145 | 145 | ||
146 | unsigned long tcp_copied, | 146 | unsigned long tcp_copied, |
147 | tcp_flags; | 147 | tcp_flags; |
148 | |||
149 | /* | ||
150 | * Connection of transports | ||
151 | */ | ||
152 | struct work_struct connect_worker; | ||
153 | unsigned short port; | ||
148 | }; | 154 | }; |
149 | 155 | ||
150 | /* | 156 | /* |
@@ -545,9 +551,11 @@ clear_close_wait: | |||
545 | */ | 551 | */ |
546 | static void xs_destroy(struct rpc_xprt *xprt) | 552 | static void xs_destroy(struct rpc_xprt *xprt) |
547 | { | 553 | { |
554 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
555 | |||
548 | dprintk("RPC: xs_destroy xprt %p\n", xprt); | 556 | dprintk("RPC: xs_destroy xprt %p\n", xprt); |
549 | 557 | ||
550 | cancel_delayed_work(&xprt->connect_worker); | 558 | cancel_delayed_work(&transport->connect_worker); |
551 | flush_scheduled_work(); | 559 | flush_scheduled_work(); |
552 | 560 | ||
553 | xprt_disconnect(xprt); | 561 | xprt_disconnect(xprt); |
@@ -1065,20 +1073,20 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | |||
1065 | sap->sin_port = htons(port); | 1073 | sap->sin_port = htons(port); |
1066 | } | 1074 | } |
1067 | 1075 | ||
1068 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | 1076 | static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock) |
1069 | { | 1077 | { |
1070 | struct sockaddr_in myaddr = { | 1078 | struct sockaddr_in myaddr = { |
1071 | .sin_family = AF_INET, | 1079 | .sin_family = AF_INET, |
1072 | }; | 1080 | }; |
1073 | int err; | 1081 | int err; |
1074 | unsigned short port = xprt->port; | 1082 | unsigned short port = transport->port; |
1075 | 1083 | ||
1076 | do { | 1084 | do { |
1077 | myaddr.sin_port = htons(port); | 1085 | myaddr.sin_port = htons(port); |
1078 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1086 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, |
1079 | sizeof(myaddr)); | 1087 | sizeof(myaddr)); |
1080 | if (err == 0) { | 1088 | if (err == 0) { |
1081 | xprt->port = port; | 1089 | transport->port = port; |
1082 | dprintk("RPC: xs_bindresvport bound to port %u\n", | 1090 | dprintk("RPC: xs_bindresvport bound to port %u\n", |
1083 | port); | 1091 | port); |
1084 | return 0; | 1092 | return 0; |
@@ -1087,7 +1095,7 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | |||
1087 | port = xprt_max_resvport; | 1095 | port = xprt_max_resvport; |
1088 | else | 1096 | else |
1089 | port--; | 1097 | port--; |
1090 | } while (err == -EADDRINUSE && port != xprt->port); | 1098 | } while (err == -EADDRINUSE && port != transport->port); |
1091 | 1099 | ||
1092 | dprintk("RPC: can't bind to reserved port (%d).\n", -err); | 1100 | dprintk("RPC: can't bind to reserved port (%d).\n", -err); |
1093 | return err; | 1101 | return err; |
@@ -1101,8 +1109,8 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | |||
1101 | */ | 1109 | */ |
1102 | static void xs_udp_connect_worker(void *args) | 1110 | static void xs_udp_connect_worker(void *args) |
1103 | { | 1111 | { |
1104 | struct rpc_xprt *xprt = (struct rpc_xprt *) args; | 1112 | struct sock_xprt *transport = (struct sock_xprt *)args; |
1105 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1113 | struct rpc_xprt *xprt = &transport->xprt; |
1106 | struct socket *sock = transport->sock; | 1114 | struct socket *sock = transport->sock; |
1107 | int err, status = -EIO; | 1115 | int err, status = -EIO; |
1108 | 1116 | ||
@@ -1117,7 +1125,7 @@ static void xs_udp_connect_worker(void *args) | |||
1117 | goto out; | 1125 | goto out; |
1118 | } | 1126 | } |
1119 | 1127 | ||
1120 | if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { | 1128 | if (xprt->resvport && xs_bindresvport(transport, sock) < 0) { |
1121 | sock_release(sock); | 1129 | sock_release(sock); |
1122 | goto out; | 1130 | goto out; |
1123 | } | 1131 | } |
@@ -1186,8 +1194,8 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | |||
1186 | */ | 1194 | */ |
1187 | static void xs_tcp_connect_worker(void *args) | 1195 | static void xs_tcp_connect_worker(void *args) |
1188 | { | 1196 | { |
1189 | struct rpc_xprt *xprt = (struct rpc_xprt *)args; | 1197 | struct sock_xprt *transport = (struct sock_xprt *)args; |
1190 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1198 | struct rpc_xprt *xprt = &transport->xprt; |
1191 | struct socket *sock = transport->sock; | 1199 | struct socket *sock = transport->sock; |
1192 | int err, status = -EIO; | 1200 | int err, status = -EIO; |
1193 | 1201 | ||
@@ -1201,7 +1209,7 @@ static void xs_tcp_connect_worker(void *args) | |||
1201 | goto out; | 1209 | goto out; |
1202 | } | 1210 | } |
1203 | 1211 | ||
1204 | if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { | 1212 | if (xprt->resvport && xs_bindresvport(transport, sock) < 0) { |
1205 | sock_release(sock); | 1213 | sock_release(sock); |
1206 | goto out; | 1214 | goto out; |
1207 | } | 1215 | } |
@@ -1293,14 +1301,14 @@ static void xs_connect(struct rpc_task *task) | |||
1293 | if (transport->sock != NULL) { | 1301 | if (transport->sock != NULL) { |
1294 | dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", | 1302 | dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", |
1295 | xprt, xprt->reestablish_timeout / HZ); | 1303 | xprt, xprt->reestablish_timeout / HZ); |
1296 | schedule_delayed_work(&xprt->connect_worker, | 1304 | schedule_delayed_work(&transport->connect_worker, |
1297 | xprt->reestablish_timeout); | 1305 | xprt->reestablish_timeout); |
1298 | xprt->reestablish_timeout <<= 1; | 1306 | xprt->reestablish_timeout <<= 1; |
1299 | if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) | 1307 | if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) |
1300 | xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; | 1308 | xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; |
1301 | } else { | 1309 | } else { |
1302 | dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); | 1310 | dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); |
1303 | schedule_work(&xprt->connect_worker); | 1311 | schedule_work(&transport->connect_worker); |
1304 | 1312 | ||
1305 | /* flush_scheduled_work can sleep... */ | 1313 | /* flush_scheduled_work can sleep... */ |
1306 | if (!RPC_IS_ASYNC(task)) | 1314 | if (!RPC_IS_ASYNC(task)) |
@@ -1316,8 +1324,10 @@ static void xs_connect(struct rpc_task *task) | |||
1316 | */ | 1324 | */ |
1317 | static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | 1325 | static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) |
1318 | { | 1326 | { |
1327 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
1328 | |||
1319 | seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n", | 1329 | seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n", |
1320 | xprt->port, | 1330 | transport->port, |
1321 | xprt->stat.bind_count, | 1331 | xprt->stat.bind_count, |
1322 | xprt->stat.sends, | 1332 | xprt->stat.sends, |
1323 | xprt->stat.recvs, | 1333 | xprt->stat.recvs, |
@@ -1334,13 +1344,14 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
1334 | */ | 1344 | */ |
1335 | static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | 1345 | static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) |
1336 | { | 1346 | { |
1347 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
1337 | long idle_time = 0; | 1348 | long idle_time = 0; |
1338 | 1349 | ||
1339 | if (xprt_connected(xprt)) | 1350 | if (xprt_connected(xprt)) |
1340 | idle_time = (long)(jiffies - xprt->last_used) / HZ; | 1351 | idle_time = (long)(jiffies - xprt->last_used) / HZ; |
1341 | 1352 | ||
1342 | seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n", | 1353 | seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n", |
1343 | xprt->port, | 1354 | transport->port, |
1344 | xprt->stat.bind_count, | 1355 | xprt->stat.bind_count, |
1345 | xprt->stat.connect_count, | 1356 | xprt->stat.connect_count, |
1346 | xprt->stat.connect_time, | 1357 | xprt->stat.connect_time, |
@@ -1414,7 +1425,7 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns | |||
1414 | 1425 | ||
1415 | memcpy(&xprt->addr, addr, addrlen); | 1426 | memcpy(&xprt->addr, addr, addrlen); |
1416 | xprt->addrlen = addrlen; | 1427 | xprt->addrlen = addrlen; |
1417 | xprt->port = xs_get_random_port(); | 1428 | new->port = xs_get_random_port(); |
1418 | 1429 | ||
1419 | return xprt; | 1430 | return xprt; |
1420 | } | 1431 | } |
@@ -1429,10 +1440,12 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns | |||
1429 | struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) | 1440 | struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) |
1430 | { | 1441 | { |
1431 | struct rpc_xprt *xprt; | 1442 | struct rpc_xprt *xprt; |
1443 | struct sock_xprt *transport; | ||
1432 | 1444 | ||
1433 | xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries); | 1445 | xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries); |
1434 | if (IS_ERR(xprt)) | 1446 | if (IS_ERR(xprt)) |
1435 | return xprt; | 1447 | return xprt; |
1448 | transport = container_of(xprt, struct sock_xprt, xprt); | ||
1436 | 1449 | ||
1437 | if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) | 1450 | if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) |
1438 | xprt_set_bound(xprt); | 1451 | xprt_set_bound(xprt); |
@@ -1442,7 +1455,7 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_ | |||
1442 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 1455 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
1443 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 1456 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
1444 | 1457 | ||
1445 | INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); | 1458 | INIT_WORK(&transport->connect_worker, xs_udp_connect_worker, transport); |
1446 | xprt->bind_timeout = XS_BIND_TO; | 1459 | xprt->bind_timeout = XS_BIND_TO; |
1447 | xprt->connect_timeout = XS_UDP_CONN_TO; | 1460 | xprt->connect_timeout = XS_UDP_CONN_TO; |
1448 | xprt->reestablish_timeout = XS_UDP_REEST_TO; | 1461 | xprt->reestablish_timeout = XS_UDP_REEST_TO; |
@@ -1472,10 +1485,12 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_ | |||
1472 | struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) | 1485 | struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) |
1473 | { | 1486 | { |
1474 | struct rpc_xprt *xprt; | 1487 | struct rpc_xprt *xprt; |
1488 | struct sock_xprt *transport; | ||
1475 | 1489 | ||
1476 | xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries); | 1490 | xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries); |
1477 | if (IS_ERR(xprt)) | 1491 | if (IS_ERR(xprt)) |
1478 | return xprt; | 1492 | return xprt; |
1493 | transport = container_of(xprt, struct sock_xprt, xprt); | ||
1479 | 1494 | ||
1480 | if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) | 1495 | if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) |
1481 | xprt_set_bound(xprt); | 1496 | xprt_set_bound(xprt); |
@@ -1484,7 +1499,7 @@ struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_ | |||
1484 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | 1499 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
1485 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1500 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
1486 | 1501 | ||
1487 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); | 1502 | INIT_WORK(&transport->connect_worker, xs_tcp_connect_worker, transport); |
1488 | xprt->bind_timeout = XS_BIND_TO; | 1503 | xprt->bind_timeout = XS_BIND_TO; |
1489 | xprt->connect_timeout = XS_TCP_CONN_TO; | 1504 | xprt->connect_timeout = XS_TCP_CONN_TO; |
1490 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | 1505 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; |