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, |