diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
| -rw-r--r-- | net/sunrpc/xprtsock.c | 166 |
1 files changed, 134 insertions, 32 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 4b4e7dfdff14..28100e019225 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -125,6 +125,47 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count) | |||
| 125 | } | 125 | } |
| 126 | #endif | 126 | #endif |
| 127 | 127 | ||
| 128 | static void xs_format_peer_addresses(struct rpc_xprt *xprt) | ||
| 129 | { | ||
| 130 | struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; | ||
| 131 | char *buf; | ||
| 132 | |||
| 133 | buf = kzalloc(20, GFP_KERNEL); | ||
| 134 | if (buf) { | ||
| 135 | snprintf(buf, 20, "%u.%u.%u.%u", | ||
| 136 | NIPQUAD(addr->sin_addr.s_addr)); | ||
| 137 | } | ||
| 138 | xprt->address_strings[RPC_DISPLAY_ADDR] = buf; | ||
| 139 | |||
| 140 | buf = kzalloc(8, GFP_KERNEL); | ||
| 141 | if (buf) { | ||
| 142 | snprintf(buf, 8, "%u", | ||
| 143 | ntohs(addr->sin_port)); | ||
| 144 | } | ||
| 145 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; | ||
| 146 | |||
| 147 | if (xprt->prot == IPPROTO_UDP) | ||
| 148 | xprt->address_strings[RPC_DISPLAY_PROTO] = "udp"; | ||
| 149 | else | ||
| 150 | xprt->address_strings[RPC_DISPLAY_PROTO] = "tcp"; | ||
| 151 | |||
| 152 | buf = kzalloc(48, GFP_KERNEL); | ||
| 153 | if (buf) { | ||
| 154 | snprintf(buf, 48, "addr=%u.%u.%u.%u port=%u proto=%s", | ||
| 155 | NIPQUAD(addr->sin_addr.s_addr), | ||
| 156 | ntohs(addr->sin_port), | ||
| 157 | xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | ||
| 158 | } | ||
| 159 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; | ||
| 160 | } | ||
| 161 | |||
| 162 | static void xs_free_peer_addresses(struct rpc_xprt *xprt) | ||
| 163 | { | ||
| 164 | kfree(xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
| 165 | kfree(xprt->address_strings[RPC_DISPLAY_PORT]); | ||
| 166 | kfree(xprt->address_strings[RPC_DISPLAY_ALL]); | ||
| 167 | } | ||
| 168 | |||
| 128 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) | 169 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) |
| 129 | 170 | ||
| 130 | static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len) | 171 | static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len) |
| @@ -174,7 +215,6 @@ static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int a | |||
| 174 | struct page **ppage = xdr->pages; | 215 | struct page **ppage = xdr->pages; |
| 175 | unsigned int len, pglen = xdr->page_len; | 216 | unsigned int len, pglen = xdr->page_len; |
| 176 | int err, ret = 0; | 217 | int err, ret = 0; |
| 177 | ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int); | ||
| 178 | 218 | ||
| 179 | if (unlikely(!sock)) | 219 | if (unlikely(!sock)) |
| 180 | return -ENOTCONN; | 220 | return -ENOTCONN; |
| @@ -207,7 +247,6 @@ static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int a | |||
| 207 | base &= ~PAGE_CACHE_MASK; | 247 | base &= ~PAGE_CACHE_MASK; |
| 208 | } | 248 | } |
| 209 | 249 | ||
| 210 | sendpage = sock->ops->sendpage ? : sock_no_sendpage; | ||
| 211 | do { | 250 | do { |
| 212 | int flags = XS_SENDMSG_FLAGS; | 251 | int flags = XS_SENDMSG_FLAGS; |
| 213 | 252 | ||
| @@ -220,10 +259,7 @@ static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int a | |||
| 220 | if (pglen != len || xdr->tail[0].iov_len != 0) | 259 | if (pglen != len || xdr->tail[0].iov_len != 0) |
| 221 | flags |= MSG_MORE; | 260 | flags |= MSG_MORE; |
| 222 | 261 | ||
| 223 | /* Hmm... We might be dealing with highmem pages */ | 262 | err = kernel_sendpage(sock, *ppage, base, len, flags); |
| 224 | if (PageHighMem(*ppage)) | ||
| 225 | sendpage = sock_no_sendpage; | ||
| 226 | err = sendpage(sock, *ppage, base, len, flags); | ||
| 227 | if (ret == 0) | 263 | if (ret == 0) |
| 228 | ret = err; | 264 | ret = err; |
| 229 | else if (err > 0) | 265 | else if (err > 0) |
| @@ -300,7 +336,7 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
| 300 | 336 | ||
| 301 | req->rq_xtime = jiffies; | 337 | req->rq_xtime = jiffies; |
| 302 | status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr, | 338 | status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr, |
| 303 | sizeof(xprt->addr), xdr, req->rq_bytes_sent); | 339 | xprt->addrlen, xdr, req->rq_bytes_sent); |
| 304 | 340 | ||
| 305 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", | 341 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", |
| 306 | xdr->len - req->rq_bytes_sent, status); | 342 | xdr->len - req->rq_bytes_sent, status); |
| @@ -414,6 +450,33 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
| 414 | } | 450 | } |
| 415 | 451 | ||
| 416 | /** | 452 | /** |
| 453 | * xs_tcp_release_xprt - clean up after a tcp transmission | ||
| 454 | * @xprt: transport | ||
| 455 | * @task: rpc task | ||
| 456 | * | ||
| 457 | * This cleans up if an error causes us to abort the transmission of a request. | ||
| 458 | * In this case, the socket may need to be reset in order to avoid confusing | ||
| 459 | * the server. | ||
| 460 | */ | ||
| 461 | static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | ||
| 462 | { | ||
| 463 | struct rpc_rqst *req; | ||
| 464 | |||
| 465 | if (task != xprt->snd_task) | ||
| 466 | return; | ||
| 467 | if (task == NULL) | ||
| 468 | goto out_release; | ||
| 469 | req = task->tk_rqstp; | ||
| 470 | if (req->rq_bytes_sent == 0) | ||
| 471 | goto out_release; | ||
| 472 | if (req->rq_bytes_sent == req->rq_snd_buf.len) | ||
| 473 | goto out_release; | ||
| 474 | set_bit(XPRT_CLOSE_WAIT, &task->tk_xprt->state); | ||
| 475 | out_release: | ||
| 476 | xprt_release_xprt(xprt, task); | ||
| 477 | } | ||
| 478 | |||
| 479 | /** | ||
| 417 | * xs_close - close a socket | 480 | * xs_close - close a socket |
| 418 | * @xprt: transport | 481 | * @xprt: transport |
| 419 | * | 482 | * |
| @@ -463,6 +526,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
| 463 | 526 | ||
| 464 | xprt_disconnect(xprt); | 527 | xprt_disconnect(xprt); |
| 465 | xs_close(xprt); | 528 | xs_close(xprt); |
| 529 | xs_free_peer_addresses(xprt); | ||
| 466 | kfree(xprt->slot); | 530 | kfree(xprt->slot); |
| 467 | } | 531 | } |
| 468 | 532 | ||
| @@ -484,7 +548,8 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
| 484 | struct rpc_rqst *rovr; | 548 | struct rpc_rqst *rovr; |
| 485 | struct sk_buff *skb; | 549 | struct sk_buff *skb; |
| 486 | int err, repsize, copied; | 550 | int err, repsize, copied; |
| 487 | u32 _xid, *xp; | 551 | u32 _xid; |
| 552 | __be32 *xp; | ||
| 488 | 553 | ||
| 489 | read_lock(&sk->sk_callback_lock); | 554 | read_lock(&sk->sk_callback_lock); |
| 490 | dprintk("RPC: xs_udp_data_ready...\n"); | 555 | dprintk("RPC: xs_udp_data_ready...\n"); |
| @@ -930,6 +995,26 @@ static void xs_udp_timer(struct rpc_task *task) | |||
| 930 | xprt_adjust_cwnd(task, -ETIMEDOUT); | 995 | xprt_adjust_cwnd(task, -ETIMEDOUT); |
| 931 | } | 996 | } |
| 932 | 997 | ||
| 998 | static unsigned short xs_get_random_port(void) | ||
| 999 | { | ||
| 1000 | unsigned short range = xprt_max_resvport - xprt_min_resvport; | ||
| 1001 | unsigned short rand = (unsigned short) net_random() % range; | ||
| 1002 | return rand + xprt_min_resvport; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | /** | ||
| 1006 | * xs_print_peer_address - format an IPv4 address for printing | ||
| 1007 | * @xprt: generic transport | ||
| 1008 | * @format: flags field indicating which parts of the address to render | ||
| 1009 | */ | ||
| 1010 | static char *xs_print_peer_address(struct rpc_xprt *xprt, enum rpc_display_format_t format) | ||
| 1011 | { | ||
| 1012 | if (xprt->address_strings[format] != NULL) | ||
| 1013 | return xprt->address_strings[format]; | ||
| 1014 | else | ||
| 1015 | return "unprintable"; | ||
| 1016 | } | ||
| 1017 | |||
| 933 | /** | 1018 | /** |
| 934 | * xs_set_port - reset the port number in the remote endpoint address | 1019 | * xs_set_port - reset the port number in the remote endpoint address |
| 935 | * @xprt: generic transport | 1020 | * @xprt: generic transport |
| @@ -938,8 +1023,11 @@ static void xs_udp_timer(struct rpc_task *task) | |||
| 938 | */ | 1023 | */ |
| 939 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | 1024 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) |
| 940 | { | 1025 | { |
| 1026 | struct sockaddr_in *sap = (struct sockaddr_in *) &xprt->addr; | ||
| 1027 | |||
| 941 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); | 1028 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); |
| 942 | xprt->addr.sin_port = htons(port); | 1029 | |
| 1030 | sap->sin_port = htons(port); | ||
| 943 | } | 1031 | } |
| 944 | 1032 | ||
| 945 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | 1033 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) |
| @@ -952,7 +1040,7 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | |||
| 952 | 1040 | ||
| 953 | do { | 1041 | do { |
| 954 | myaddr.sin_port = htons(port); | 1042 | myaddr.sin_port = htons(port); |
| 955 | err = sock->ops->bind(sock, (struct sockaddr *) &myaddr, | 1043 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, |
| 956 | sizeof(myaddr)); | 1044 | sizeof(myaddr)); |
| 957 | if (err == 0) { | 1045 | if (err == 0) { |
| 958 | xprt->port = port; | 1046 | xprt->port = port; |
| @@ -982,11 +1070,9 @@ static void xs_udp_connect_worker(void *args) | |||
| 982 | struct socket *sock = xprt->sock; | 1070 | struct socket *sock = xprt->sock; |
| 983 | int err, status = -EIO; | 1071 | int err, status = -EIO; |
| 984 | 1072 | ||
| 985 | if (xprt->shutdown || xprt->addr.sin_port == 0) | 1073 | if (xprt->shutdown || !xprt_bound(xprt)) |
| 986 | goto out; | 1074 | goto out; |
| 987 | 1075 | ||
| 988 | dprintk("RPC: xs_udp_connect_worker for xprt %p\n", xprt); | ||
| 989 | |||
| 990 | /* Start by resetting any existing state */ | 1076 | /* Start by resetting any existing state */ |
| 991 | xs_close(xprt); | 1077 | xs_close(xprt); |
| 992 | 1078 | ||
| @@ -1000,6 +1086,9 @@ static void xs_udp_connect_worker(void *args) | |||
| 1000 | goto out; | 1086 | goto out; |
| 1001 | } | 1087 | } |
| 1002 | 1088 | ||
| 1089 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | ||
| 1090 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
| 1091 | |||
| 1003 | if (!xprt->inet) { | 1092 | if (!xprt->inet) { |
| 1004 | struct sock *sk = sock->sk; | 1093 | struct sock *sk = sock->sk; |
| 1005 | 1094 | ||
| @@ -1047,7 +1136,7 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | |||
| 1047 | */ | 1136 | */ |
| 1048 | memset(&any, 0, sizeof(any)); | 1137 | memset(&any, 0, sizeof(any)); |
| 1049 | any.sa_family = AF_UNSPEC; | 1138 | any.sa_family = AF_UNSPEC; |
| 1050 | result = sock->ops->connect(sock, &any, sizeof(any), 0); | 1139 | result = kernel_connect(sock, &any, sizeof(any), 0); |
| 1051 | if (result) | 1140 | if (result) |
| 1052 | dprintk("RPC: AF_UNSPEC connect return code %d\n", | 1141 | dprintk("RPC: AF_UNSPEC connect return code %d\n", |
| 1053 | result); | 1142 | result); |
| @@ -1065,11 +1154,9 @@ static void xs_tcp_connect_worker(void *args) | |||
| 1065 | struct socket *sock = xprt->sock; | 1154 | struct socket *sock = xprt->sock; |
| 1066 | int err, status = -EIO; | 1155 | int err, status = -EIO; |
| 1067 | 1156 | ||
| 1068 | if (xprt->shutdown || xprt->addr.sin_port == 0) | 1157 | if (xprt->shutdown || !xprt_bound(xprt)) |
| 1069 | goto out; | 1158 | goto out; |
| 1070 | 1159 | ||
| 1071 | dprintk("RPC: xs_tcp_connect_worker for xprt %p\n", xprt); | ||
| 1072 | |||
| 1073 | if (!xprt->sock) { | 1160 | if (!xprt->sock) { |
| 1074 | /* start from scratch */ | 1161 | /* start from scratch */ |
| 1075 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { | 1162 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { |
| @@ -1085,6 +1172,9 @@ static void xs_tcp_connect_worker(void *args) | |||
| 1085 | /* "close" the socket, preserving the local port */ | 1172 | /* "close" the socket, preserving the local port */ |
| 1086 | xs_tcp_reuse_connection(xprt); | 1173 | xs_tcp_reuse_connection(xprt); |
| 1087 | 1174 | ||
| 1175 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | ||
| 1176 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
| 1177 | |||
| 1088 | if (!xprt->inet) { | 1178 | if (!xprt->inet) { |
| 1089 | struct sock *sk = sock->sk; | 1179 | struct sock *sk = sock->sk; |
| 1090 | 1180 | ||
| @@ -1117,8 +1207,8 @@ static void xs_tcp_connect_worker(void *args) | |||
| 1117 | /* Tell the socket layer to start connecting... */ | 1207 | /* Tell the socket layer to start connecting... */ |
| 1118 | xprt->stat.connect_count++; | 1208 | xprt->stat.connect_count++; |
| 1119 | xprt->stat.connect_start = jiffies; | 1209 | xprt->stat.connect_start = jiffies; |
| 1120 | status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr, | 1210 | status = kernel_connect(sock, (struct sockaddr *) &xprt->addr, |
| 1121 | sizeof(xprt->addr), O_NONBLOCK); | 1211 | xprt->addrlen, O_NONBLOCK); |
| 1122 | dprintk("RPC: %p connect status %d connected %d sock state %d\n", | 1212 | dprintk("RPC: %p connect status %d connected %d sock state %d\n", |
| 1123 | xprt, -status, xprt_connected(xprt), sock->sk->sk_state); | 1213 | xprt, -status, xprt_connected(xprt), sock->sk->sk_state); |
| 1124 | if (status < 0) { | 1214 | if (status < 0) { |
| @@ -1226,8 +1316,10 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
| 1226 | 1316 | ||
| 1227 | static struct rpc_xprt_ops xs_udp_ops = { | 1317 | static struct rpc_xprt_ops xs_udp_ops = { |
| 1228 | .set_buffer_size = xs_udp_set_buffer_size, | 1318 | .set_buffer_size = xs_udp_set_buffer_size, |
| 1319 | .print_addr = xs_print_peer_address, | ||
| 1229 | .reserve_xprt = xprt_reserve_xprt_cong, | 1320 | .reserve_xprt = xprt_reserve_xprt_cong, |
| 1230 | .release_xprt = xprt_release_xprt_cong, | 1321 | .release_xprt = xprt_release_xprt_cong, |
| 1322 | .rpcbind = rpc_getport, | ||
| 1231 | .set_port = xs_set_port, | 1323 | .set_port = xs_set_port, |
| 1232 | .connect = xs_connect, | 1324 | .connect = xs_connect, |
| 1233 | .buf_alloc = rpc_malloc, | 1325 | .buf_alloc = rpc_malloc, |
| @@ -1242,8 +1334,10 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
| 1242 | }; | 1334 | }; |
| 1243 | 1335 | ||
| 1244 | static struct rpc_xprt_ops xs_tcp_ops = { | 1336 | static struct rpc_xprt_ops xs_tcp_ops = { |
| 1337 | .print_addr = xs_print_peer_address, | ||
| 1245 | .reserve_xprt = xprt_reserve_xprt, | 1338 | .reserve_xprt = xprt_reserve_xprt, |
| 1246 | .release_xprt = xprt_release_xprt, | 1339 | .release_xprt = xs_tcp_release_xprt, |
| 1340 | .rpcbind = rpc_getport, | ||
| 1247 | .set_port = xs_set_port, | 1341 | .set_port = xs_set_port, |
| 1248 | .connect = xs_connect, | 1342 | .connect = xs_connect, |
| 1249 | .buf_alloc = rpc_malloc, | 1343 | .buf_alloc = rpc_malloc, |
| @@ -1264,20 +1358,20 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
| 1264 | int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | 1358 | int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) |
| 1265 | { | 1359 | { |
| 1266 | size_t slot_table_size; | 1360 | size_t slot_table_size; |
| 1267 | 1361 | struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; | |
| 1268 | dprintk("RPC: setting up udp-ipv4 transport...\n"); | ||
| 1269 | 1362 | ||
| 1270 | xprt->max_reqs = xprt_udp_slot_table_entries; | 1363 | xprt->max_reqs = xprt_udp_slot_table_entries; |
| 1271 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); | 1364 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); |
| 1272 | xprt->slot = kmalloc(slot_table_size, GFP_KERNEL); | 1365 | xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); |
| 1273 | if (xprt->slot == NULL) | 1366 | if (xprt->slot == NULL) |
| 1274 | return -ENOMEM; | 1367 | return -ENOMEM; |
| 1275 | memset(xprt->slot, 0, slot_table_size); | 1368 | |
| 1369 | if (ntohs(addr->sin_port != 0)) | ||
| 1370 | xprt_set_bound(xprt); | ||
| 1371 | xprt->port = xs_get_random_port(); | ||
| 1276 | 1372 | ||
| 1277 | xprt->prot = IPPROTO_UDP; | 1373 | xprt->prot = IPPROTO_UDP; |
| 1278 | xprt->port = xprt_max_resvport; | ||
| 1279 | xprt->tsh_size = 0; | 1374 | xprt->tsh_size = 0; |
| 1280 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | ||
| 1281 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 1375 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
| 1282 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 1376 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
| 1283 | 1377 | ||
| @@ -1294,6 +1388,10 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
| 1294 | else | 1388 | else |
| 1295 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); | 1389 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); |
| 1296 | 1390 | ||
| 1391 | xs_format_peer_addresses(xprt); | ||
| 1392 | dprintk("RPC: set up transport to address %s\n", | ||
| 1393 | xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
| 1394 | |||
| 1297 | return 0; | 1395 | return 0; |
| 1298 | } | 1396 | } |
| 1299 | 1397 | ||
| @@ -1306,20 +1404,20 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
| 1306 | int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | 1404 | int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) |
| 1307 | { | 1405 | { |
| 1308 | size_t slot_table_size; | 1406 | size_t slot_table_size; |
| 1309 | 1407 | struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; | |
| 1310 | dprintk("RPC: setting up tcp-ipv4 transport...\n"); | ||
| 1311 | 1408 | ||
| 1312 | xprt->max_reqs = xprt_tcp_slot_table_entries; | 1409 | xprt->max_reqs = xprt_tcp_slot_table_entries; |
| 1313 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); | 1410 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); |
| 1314 | xprt->slot = kmalloc(slot_table_size, GFP_KERNEL); | 1411 | xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); |
| 1315 | if (xprt->slot == NULL) | 1412 | if (xprt->slot == NULL) |
| 1316 | return -ENOMEM; | 1413 | return -ENOMEM; |
| 1317 | memset(xprt->slot, 0, slot_table_size); | 1414 | |
| 1415 | if (ntohs(addr->sin_port) != 0) | ||
| 1416 | xprt_set_bound(xprt); | ||
| 1417 | xprt->port = xs_get_random_port(); | ||
| 1318 | 1418 | ||
| 1319 | xprt->prot = IPPROTO_TCP; | 1419 | xprt->prot = IPPROTO_TCP; |
| 1320 | xprt->port = xprt_max_resvport; | ||
| 1321 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | 1420 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
| 1322 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | ||
| 1323 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1421 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
| 1324 | 1422 | ||
| 1325 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); | 1423 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); |
| @@ -1335,5 +1433,9 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
| 1335 | else | 1433 | else |
| 1336 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); | 1434 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); |
| 1337 | 1435 | ||
| 1436 | xs_format_peer_addresses(xprt); | ||
| 1437 | dprintk("RPC: set up transport to address %s\n", | ||
| 1438 | xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
| 1439 | |||
| 1338 | return 0; | 1440 | return 0; |
| 1339 | } | 1441 | } |
