diff options
| -rw-r--r-- | include/linux/sunrpc/xprt.h | 4 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 62 |
2 files changed, 41 insertions, 25 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index d7919010863d..4c074a73670c 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #include <linux/sunrpc/xdr.h> | 17 | #include <linux/sunrpc/xdr.h> |
| 18 | #include <linux/sunrpc/msg_prot.h> | 18 | #include <linux/sunrpc/msg_prot.h> |
| 19 | 19 | ||
| 20 | #include <net/sock.h> | ||
| 21 | |||
| 20 | extern unsigned int xprt_udp_slot_table_entries; | 22 | extern unsigned int xprt_udp_slot_table_entries; |
| 21 | extern unsigned int xprt_tcp_slot_table_entries; | 23 | extern unsigned int xprt_tcp_slot_table_entries; |
| 22 | 24 | ||
| @@ -126,8 +128,6 @@ struct rpc_xprt_ops { | |||
| 126 | struct rpc_xprt { | 128 | struct rpc_xprt { |
| 127 | struct kref kref; /* Reference count */ | 129 | struct kref kref; /* Reference count */ |
| 128 | struct rpc_xprt_ops * ops; /* transport methods */ | 130 | struct rpc_xprt_ops * ops; /* transport methods */ |
| 129 | struct socket * sock; /* BSD socket layer */ | ||
| 130 | struct sock * inet; /* INET layer */ | ||
| 131 | 131 | ||
| 132 | struct rpc_timeout timeout; /* timeout parms */ | 132 | struct rpc_timeout timeout; /* timeout parms */ |
| 133 | struct sockaddr_storage addr; /* server address */ | 133 | struct sockaddr_storage addr; /* server address */ |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index dc4a21f1a129..0f455fd1820c 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -127,6 +127,12 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count) | |||
| 127 | 127 | ||
| 128 | struct sock_xprt { | 128 | struct sock_xprt { |
| 129 | struct rpc_xprt xprt; | 129 | struct rpc_xprt xprt; |
| 130 | |||
| 131 | /* | ||
| 132 | * Network layer | ||
| 133 | */ | ||
| 134 | struct socket * sock; | ||
| 135 | struct sock * inet; | ||
| 130 | }; | 136 | }; |
| 131 | 137 | ||
| 132 | static void xs_format_peer_addresses(struct rpc_xprt *xprt) | 138 | static void xs_format_peer_addresses(struct rpc_xprt *xprt) |
| @@ -285,19 +291,20 @@ static void xs_nospace(struct rpc_task *task) | |||
| 285 | { | 291 | { |
| 286 | struct rpc_rqst *req = task->tk_rqstp; | 292 | struct rpc_rqst *req = task->tk_rqstp; |
| 287 | struct rpc_xprt *xprt = req->rq_xprt; | 293 | struct rpc_xprt *xprt = req->rq_xprt; |
| 294 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
| 288 | 295 | ||
| 289 | dprintk("RPC: %4d xmit incomplete (%u left of %u)\n", | 296 | dprintk("RPC: %4d xmit incomplete (%u left of %u)\n", |
| 290 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, | 297 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, |
| 291 | req->rq_slen); | 298 | req->rq_slen); |
| 292 | 299 | ||
| 293 | if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) { | 300 | if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { |
| 294 | /* Protect against races with write_space */ | 301 | /* Protect against races with write_space */ |
| 295 | spin_lock_bh(&xprt->transport_lock); | 302 | spin_lock_bh(&xprt->transport_lock); |
| 296 | 303 | ||
| 297 | /* Don't race with disconnect */ | 304 | /* Don't race with disconnect */ |
| 298 | if (!xprt_connected(xprt)) | 305 | if (!xprt_connected(xprt)) |
| 299 | task->tk_status = -ENOTCONN; | 306 | task->tk_status = -ENOTCONN; |
| 300 | else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) | 307 | else if (test_bit(SOCK_NOSPACE, &transport->sock->flags)) |
| 301 | xprt_wait_for_buffer_space(task); | 308 | xprt_wait_for_buffer_space(task); |
| 302 | 309 | ||
| 303 | spin_unlock_bh(&xprt->transport_lock); | 310 | spin_unlock_bh(&xprt->transport_lock); |
| @@ -321,6 +328,7 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
| 321 | { | 328 | { |
| 322 | struct rpc_rqst *req = task->tk_rqstp; | 329 | struct rpc_rqst *req = task->tk_rqstp; |
| 323 | struct rpc_xprt *xprt = req->rq_xprt; | 330 | struct rpc_xprt *xprt = req->rq_xprt; |
| 331 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
| 324 | struct xdr_buf *xdr = &req->rq_snd_buf; | 332 | struct xdr_buf *xdr = &req->rq_snd_buf; |
| 325 | int status; | 333 | int status; |
| 326 | 334 | ||
| @@ -329,8 +337,10 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
| 329 | req->rq_svec->iov_len); | 337 | req->rq_svec->iov_len); |
| 330 | 338 | ||
| 331 | req->rq_xtime = jiffies; | 339 | req->rq_xtime = jiffies; |
| 332 | status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr, | 340 | status = xs_sendpages(transport->sock, |
| 333 | xprt->addrlen, xdr, req->rq_bytes_sent); | 341 | (struct sockaddr *) &xprt->addr, |
| 342 | xprt->addrlen, xdr, | ||
| 343 | req->rq_bytes_sent); | ||
| 334 | 344 | ||
| 335 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", | 345 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", |
| 336 | xdr->len - req->rq_bytes_sent, status); | 346 | xdr->len - req->rq_bytes_sent, status); |
| @@ -386,6 +396,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
| 386 | { | 396 | { |
| 387 | struct rpc_rqst *req = task->tk_rqstp; | 397 | struct rpc_rqst *req = task->tk_rqstp; |
| 388 | struct rpc_xprt *xprt = req->rq_xprt; | 398 | struct rpc_xprt *xprt = req->rq_xprt; |
| 399 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
| 389 | struct xdr_buf *xdr = &req->rq_snd_buf; | 400 | struct xdr_buf *xdr = &req->rq_snd_buf; |
| 390 | int status, retry = 0; | 401 | int status, retry = 0; |
| 391 | 402 | ||
| @@ -400,8 +411,8 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
| 400 | * called sendmsg(). */ | 411 | * called sendmsg(). */ |
| 401 | while (1) { | 412 | while (1) { |
| 402 | req->rq_xtime = jiffies; | 413 | req->rq_xtime = jiffies; |
| 403 | status = xs_sendpages(xprt->sock, NULL, 0, xdr, | 414 | status = xs_sendpages(transport->sock, |
| 404 | req->rq_bytes_sent); | 415 | NULL, 0, xdr, req->rq_bytes_sent); |
| 405 | 416 | ||
| 406 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", | 417 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", |
| 407 | xdr->len - req->rq_bytes_sent, status); | 418 | xdr->len - req->rq_bytes_sent, status); |
| @@ -479,8 +490,9 @@ out_release: | |||
| 479 | */ | 490 | */ |
| 480 | static void xs_close(struct rpc_xprt *xprt) | 491 | static void xs_close(struct rpc_xprt *xprt) |
| 481 | { | 492 | { |
| 482 | struct socket *sock = xprt->sock; | 493 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 483 | struct sock *sk = xprt->inet; | 494 | struct socket *sock = transport->sock; |
| 495 | struct sock *sk = transport->inet; | ||
| 484 | 496 | ||
| 485 | if (!sk) | 497 | if (!sk) |
| 486 | goto clear_close_wait; | 498 | goto clear_close_wait; |
| @@ -488,8 +500,8 @@ static void xs_close(struct rpc_xprt *xprt) | |||
| 488 | dprintk("RPC: xs_close xprt %p\n", xprt); | 500 | dprintk("RPC: xs_close xprt %p\n", xprt); |
| 489 | 501 | ||
| 490 | write_lock_bh(&sk->sk_callback_lock); | 502 | write_lock_bh(&sk->sk_callback_lock); |
| 491 | xprt->inet = NULL; | 503 | transport->inet = NULL; |
| 492 | xprt->sock = NULL; | 504 | transport->sock = NULL; |
| 493 | 505 | ||
| 494 | sk->sk_user_data = NULL; | 506 | sk->sk_user_data = NULL; |
| 495 | sk->sk_data_ready = xprt->old_data_ready; | 507 | sk->sk_data_ready = xprt->old_data_ready; |
| @@ -946,7 +958,8 @@ static void xs_tcp_write_space(struct sock *sk) | |||
| 946 | 958 | ||
| 947 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) | 959 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) |
| 948 | { | 960 | { |
| 949 | struct sock *sk = xprt->inet; | 961 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 962 | struct sock *sk = transport->inet; | ||
| 950 | 963 | ||
| 951 | if (xprt->rcvsize) { | 964 | if (xprt->rcvsize) { |
| 952 | sk->sk_userlocks |= SOCK_RCVBUF_LOCK; | 965 | sk->sk_userlocks |= SOCK_RCVBUF_LOCK; |
| @@ -1062,7 +1075,8 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | |||
| 1062 | static void xs_udp_connect_worker(void *args) | 1075 | static void xs_udp_connect_worker(void *args) |
| 1063 | { | 1076 | { |
| 1064 | struct rpc_xprt *xprt = (struct rpc_xprt *) args; | 1077 | struct rpc_xprt *xprt = (struct rpc_xprt *) args; |
| 1065 | struct socket *sock = xprt->sock; | 1078 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 1079 | struct socket *sock = transport->sock; | ||
| 1066 | int err, status = -EIO; | 1080 | int err, status = -EIO; |
| 1067 | 1081 | ||
| 1068 | if (xprt->shutdown || !xprt_bound(xprt)) | 1082 | if (xprt->shutdown || !xprt_bound(xprt)) |
| @@ -1084,7 +1098,7 @@ static void xs_udp_connect_worker(void *args) | |||
| 1084 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | 1098 | dprintk("RPC: worker connecting xprt %p to address: %s\n", |
| 1085 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | 1099 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); |
| 1086 | 1100 | ||
| 1087 | if (!xprt->inet) { | 1101 | if (!transport->inet) { |
| 1088 | struct sock *sk = sock->sk; | 1102 | struct sock *sk = sock->sk; |
| 1089 | 1103 | ||
| 1090 | write_lock_bh(&sk->sk_callback_lock); | 1104 | write_lock_bh(&sk->sk_callback_lock); |
| @@ -1101,8 +1115,8 @@ static void xs_udp_connect_worker(void *args) | |||
| 1101 | xprt_set_connected(xprt); | 1115 | xprt_set_connected(xprt); |
| 1102 | 1116 | ||
| 1103 | /* Reset to new socket */ | 1117 | /* Reset to new socket */ |
| 1104 | xprt->sock = sock; | 1118 | transport->sock = sock; |
| 1105 | xprt->inet = sk; | 1119 | transport->inet = sk; |
| 1106 | 1120 | ||
| 1107 | write_unlock_bh(&sk->sk_callback_lock); | 1121 | write_unlock_bh(&sk->sk_callback_lock); |
| 1108 | } | 1122 | } |
| @@ -1120,7 +1134,7 @@ out: | |||
| 1120 | static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | 1134 | static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) |
| 1121 | { | 1135 | { |
| 1122 | int result; | 1136 | int result; |
| 1123 | struct socket *sock = xprt->sock; | 1137 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 1124 | struct sockaddr any; | 1138 | struct sockaddr any; |
| 1125 | 1139 | ||
| 1126 | dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt); | 1140 | dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt); |
| @@ -1131,7 +1145,7 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | |||
| 1131 | */ | 1145 | */ |
| 1132 | memset(&any, 0, sizeof(any)); | 1146 | memset(&any, 0, sizeof(any)); |
| 1133 | any.sa_family = AF_UNSPEC; | 1147 | any.sa_family = AF_UNSPEC; |
| 1134 | result = kernel_connect(sock, &any, sizeof(any), 0); | 1148 | result = kernel_connect(transport->sock, &any, sizeof(any), 0); |
| 1135 | if (result) | 1149 | if (result) |
| 1136 | dprintk("RPC: AF_UNSPEC connect return code %d\n", | 1150 | dprintk("RPC: AF_UNSPEC connect return code %d\n", |
| 1137 | result); | 1151 | result); |
| @@ -1146,13 +1160,14 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | |||
| 1146 | static void xs_tcp_connect_worker(void *args) | 1160 | static void xs_tcp_connect_worker(void *args) |
| 1147 | { | 1161 | { |
| 1148 | struct rpc_xprt *xprt = (struct rpc_xprt *)args; | 1162 | struct rpc_xprt *xprt = (struct rpc_xprt *)args; |
| 1149 | struct socket *sock = xprt->sock; | 1163 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 1164 | struct socket *sock = transport->sock; | ||
| 1150 | int err, status = -EIO; | 1165 | int err, status = -EIO; |
| 1151 | 1166 | ||
| 1152 | if (xprt->shutdown || !xprt_bound(xprt)) | 1167 | if (xprt->shutdown || !xprt_bound(xprt)) |
| 1153 | goto out; | 1168 | goto out; |
| 1154 | 1169 | ||
| 1155 | if (!xprt->sock) { | 1170 | if (!sock) { |
| 1156 | /* start from scratch */ | 1171 | /* start from scratch */ |
| 1157 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { | 1172 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { |
| 1158 | dprintk("RPC: can't create TCP transport socket (%d).\n", -err); | 1173 | dprintk("RPC: can't create TCP transport socket (%d).\n", -err); |
| @@ -1170,7 +1185,7 @@ static void xs_tcp_connect_worker(void *args) | |||
| 1170 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | 1185 | dprintk("RPC: worker connecting xprt %p to address: %s\n", |
| 1171 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | 1186 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); |
| 1172 | 1187 | ||
| 1173 | if (!xprt->inet) { | 1188 | if (!transport->inet) { |
| 1174 | struct sock *sk = sock->sk; | 1189 | struct sock *sk = sock->sk; |
| 1175 | 1190 | ||
| 1176 | write_lock_bh(&sk->sk_callback_lock); | 1191 | write_lock_bh(&sk->sk_callback_lock); |
| @@ -1193,8 +1208,8 @@ static void xs_tcp_connect_worker(void *args) | |||
| 1193 | xprt_clear_connected(xprt); | 1208 | xprt_clear_connected(xprt); |
| 1194 | 1209 | ||
| 1195 | /* Reset to new socket */ | 1210 | /* Reset to new socket */ |
| 1196 | xprt->sock = sock; | 1211 | transport->sock = sock; |
| 1197 | xprt->inet = sk; | 1212 | transport->inet = sk; |
| 1198 | 1213 | ||
| 1199 | write_unlock_bh(&sk->sk_callback_lock); | 1214 | write_unlock_bh(&sk->sk_callback_lock); |
| 1200 | } | 1215 | } |
| @@ -1243,11 +1258,12 @@ out_clear: | |||
| 1243 | static void xs_connect(struct rpc_task *task) | 1258 | static void xs_connect(struct rpc_task *task) |
| 1244 | { | 1259 | { |
| 1245 | struct rpc_xprt *xprt = task->tk_xprt; | 1260 | struct rpc_xprt *xprt = task->tk_xprt; |
| 1261 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
| 1246 | 1262 | ||
| 1247 | if (xprt_test_and_set_connecting(xprt)) | 1263 | if (xprt_test_and_set_connecting(xprt)) |
| 1248 | return; | 1264 | return; |
| 1249 | 1265 | ||
| 1250 | if (xprt->sock != NULL) { | 1266 | if (transport->sock != NULL) { |
| 1251 | dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", | 1267 | dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", |
| 1252 | xprt, xprt->reestablish_timeout / HZ); | 1268 | xprt, xprt->reestablish_timeout / HZ); |
| 1253 | schedule_delayed_work(&xprt->connect_worker, | 1269 | schedule_delayed_work(&xprt->connect_worker, |
