diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-23 19:58:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-23 19:58:40 -0400 |
commit | 9f261e011340bcd22c1dd48b465153bd78caa8c8 (patch) | |
tree | b1c266ea746a0e8591e6af781aef22854e652ff9 /net/sunrpc/xprtsock.c | |
parent | a4c12d6c5dde48c69464baf7c703e425ee511433 (diff) | |
parent | 026ed5c9185dcc4b2df92e98c3d61a01cea19cbf (diff) |
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: (74 commits)
NFS: unmark NFS direct I/O as experimental
NFS: add comments clarifying the use of nfs_post_op_update()
NFSv4: rpc_mkpipe creating socket inodes w/out sk buffers
NFS: Use SEEK_END instead of hardcoded value
NFSv4: When mounting with a port=0 argument, substitute port=2049
NFSv4: Poll more aggressively when handling NFS4ERR_DELAY
NFSv4: Handle the condition NFS4ERR_FILE_OPEN
NFSv4: Retry lease recovery if it failed during a synchronous operation.
NFS: Don't invalidate the symlink we just stuffed into the cache
NFS: Make read() return an ESTALE if the file has been deleted
NFSv4: It's perfectly legal for clp to be NULL here....
NFS: nfs_lookup - don't hash dentry when optimising away the lookup
SUNRPC: Fix Oops in pmap_getport_done
SUNRPC: Add refcounting to the struct rpc_xprt
SUNRPC: Clean up soft task error handling
SUNRPC: Handle ENETUNREACH, EHOSTUNREACH and EHOSTDOWN socket errors
SUNRPC: rpc_delay() should not clobber the rpc_task->tk_status
Fix a referral error Oops
NFS: NFS_ROOT should use the new rpc_create API
NFS: Fix up compiler warnings on 64-bit platforms in client.c
...
Manually resolved conflict in net/sunrpc/xprtsock.c
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 108 |
1 files changed, 91 insertions, 17 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 897bdd982315..9b62923a9c06 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) |
@@ -295,7 +336,7 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
295 | 336 | ||
296 | req->rq_xtime = jiffies; | 337 | req->rq_xtime = jiffies; |
297 | status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr, | 338 | status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr, |
298 | sizeof(xprt->addr), xdr, req->rq_bytes_sent); | 339 | xprt->addrlen, xdr, req->rq_bytes_sent); |
299 | 340 | ||
300 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", | 341 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", |
301 | xdr->len - req->rq_bytes_sent, status); | 342 | xdr->len - req->rq_bytes_sent, status); |
@@ -485,6 +526,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
485 | 526 | ||
486 | xprt_disconnect(xprt); | 527 | xprt_disconnect(xprt); |
487 | xs_close(xprt); | 528 | xs_close(xprt); |
529 | xs_free_peer_addresses(xprt); | ||
488 | kfree(xprt->slot); | 530 | kfree(xprt->slot); |
489 | } | 531 | } |
490 | 532 | ||
@@ -960,6 +1002,19 @@ static unsigned short xs_get_random_port(void) | |||
960 | } | 1002 | } |
961 | 1003 | ||
962 | /** | 1004 | /** |
1005 | * xs_print_peer_address - format an IPv4 address for printing | ||
1006 | * @xprt: generic transport | ||
1007 | * @format: flags field indicating which parts of the address to render | ||
1008 | */ | ||
1009 | static char *xs_print_peer_address(struct rpc_xprt *xprt, enum rpc_display_format_t format) | ||
1010 | { | ||
1011 | if (xprt->address_strings[format] != NULL) | ||
1012 | return xprt->address_strings[format]; | ||
1013 | else | ||
1014 | return "unprintable"; | ||
1015 | } | ||
1016 | |||
1017 | /** | ||
963 | * xs_set_port - reset the port number in the remote endpoint address | 1018 | * xs_set_port - reset the port number in the remote endpoint address |
964 | * @xprt: generic transport | 1019 | * @xprt: generic transport |
965 | * @port: new port number | 1020 | * @port: new port number |
@@ -967,8 +1022,11 @@ static unsigned short xs_get_random_port(void) | |||
967 | */ | 1022 | */ |
968 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | 1023 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) |
969 | { | 1024 | { |
1025 | struct sockaddr_in *sap = (struct sockaddr_in *) &xprt->addr; | ||
1026 | |||
970 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); | 1027 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); |
971 | xprt->addr.sin_port = htons(port); | 1028 | |
1029 | sap->sin_port = htons(port); | ||
972 | } | 1030 | } |
973 | 1031 | ||
974 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | 1032 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) |
@@ -1011,11 +1069,9 @@ static void xs_udp_connect_worker(void *args) | |||
1011 | struct socket *sock = xprt->sock; | 1069 | struct socket *sock = xprt->sock; |
1012 | int err, status = -EIO; | 1070 | int err, status = -EIO; |
1013 | 1071 | ||
1014 | if (xprt->shutdown || xprt->addr.sin_port == 0) | 1072 | if (xprt->shutdown || !xprt_bound(xprt)) |
1015 | goto out; | 1073 | goto out; |
1016 | 1074 | ||
1017 | dprintk("RPC: xs_udp_connect_worker for xprt %p\n", xprt); | ||
1018 | |||
1019 | /* Start by resetting any existing state */ | 1075 | /* Start by resetting any existing state */ |
1020 | xs_close(xprt); | 1076 | xs_close(xprt); |
1021 | 1077 | ||
@@ -1029,6 +1085,9 @@ static void xs_udp_connect_worker(void *args) | |||
1029 | goto out; | 1085 | goto out; |
1030 | } | 1086 | } |
1031 | 1087 | ||
1088 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | ||
1089 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1090 | |||
1032 | if (!xprt->inet) { | 1091 | if (!xprt->inet) { |
1033 | struct sock *sk = sock->sk; | 1092 | struct sock *sk = sock->sk; |
1034 | 1093 | ||
@@ -1094,11 +1153,9 @@ static void xs_tcp_connect_worker(void *args) | |||
1094 | struct socket *sock = xprt->sock; | 1153 | struct socket *sock = xprt->sock; |
1095 | int err, status = -EIO; | 1154 | int err, status = -EIO; |
1096 | 1155 | ||
1097 | if (xprt->shutdown || xprt->addr.sin_port == 0) | 1156 | if (xprt->shutdown || !xprt_bound(xprt)) |
1098 | goto out; | 1157 | goto out; |
1099 | 1158 | ||
1100 | dprintk("RPC: xs_tcp_connect_worker for xprt %p\n", xprt); | ||
1101 | |||
1102 | if (!xprt->sock) { | 1159 | if (!xprt->sock) { |
1103 | /* start from scratch */ | 1160 | /* start from scratch */ |
1104 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { | 1161 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { |
@@ -1114,6 +1171,9 @@ static void xs_tcp_connect_worker(void *args) | |||
1114 | /* "close" the socket, preserving the local port */ | 1171 | /* "close" the socket, preserving the local port */ |
1115 | xs_tcp_reuse_connection(xprt); | 1172 | xs_tcp_reuse_connection(xprt); |
1116 | 1173 | ||
1174 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | ||
1175 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1176 | |||
1117 | if (!xprt->inet) { | 1177 | if (!xprt->inet) { |
1118 | struct sock *sk = sock->sk; | 1178 | struct sock *sk = sock->sk; |
1119 | 1179 | ||
@@ -1147,7 +1207,7 @@ static void xs_tcp_connect_worker(void *args) | |||
1147 | xprt->stat.connect_count++; | 1207 | xprt->stat.connect_count++; |
1148 | xprt->stat.connect_start = jiffies; | 1208 | xprt->stat.connect_start = jiffies; |
1149 | status = kernel_connect(sock, (struct sockaddr *) &xprt->addr, | 1209 | status = kernel_connect(sock, (struct sockaddr *) &xprt->addr, |
1150 | sizeof(xprt->addr), O_NONBLOCK); | 1210 | xprt->addrlen, O_NONBLOCK); |
1151 | dprintk("RPC: %p connect status %d connected %d sock state %d\n", | 1211 | dprintk("RPC: %p connect status %d connected %d sock state %d\n", |
1152 | xprt, -status, xprt_connected(xprt), sock->sk->sk_state); | 1212 | xprt, -status, xprt_connected(xprt), sock->sk->sk_state); |
1153 | if (status < 0) { | 1213 | if (status < 0) { |
@@ -1255,8 +1315,10 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
1255 | 1315 | ||
1256 | static struct rpc_xprt_ops xs_udp_ops = { | 1316 | static struct rpc_xprt_ops xs_udp_ops = { |
1257 | .set_buffer_size = xs_udp_set_buffer_size, | 1317 | .set_buffer_size = xs_udp_set_buffer_size, |
1318 | .print_addr = xs_print_peer_address, | ||
1258 | .reserve_xprt = xprt_reserve_xprt_cong, | 1319 | .reserve_xprt = xprt_reserve_xprt_cong, |
1259 | .release_xprt = xprt_release_xprt_cong, | 1320 | .release_xprt = xprt_release_xprt_cong, |
1321 | .rpcbind = rpc_getport, | ||
1260 | .set_port = xs_set_port, | 1322 | .set_port = xs_set_port, |
1261 | .connect = xs_connect, | 1323 | .connect = xs_connect, |
1262 | .buf_alloc = rpc_malloc, | 1324 | .buf_alloc = rpc_malloc, |
@@ -1271,8 +1333,10 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1271 | }; | 1333 | }; |
1272 | 1334 | ||
1273 | static struct rpc_xprt_ops xs_tcp_ops = { | 1335 | static struct rpc_xprt_ops xs_tcp_ops = { |
1336 | .print_addr = xs_print_peer_address, | ||
1274 | .reserve_xprt = xprt_reserve_xprt, | 1337 | .reserve_xprt = xprt_reserve_xprt, |
1275 | .release_xprt = xs_tcp_release_xprt, | 1338 | .release_xprt = xs_tcp_release_xprt, |
1339 | .rpcbind = rpc_getport, | ||
1276 | .set_port = xs_set_port, | 1340 | .set_port = xs_set_port, |
1277 | .connect = xs_connect, | 1341 | .connect = xs_connect, |
1278 | .buf_alloc = rpc_malloc, | 1342 | .buf_alloc = rpc_malloc, |
@@ -1293,8 +1357,7 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
1293 | int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | 1357 | int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) |
1294 | { | 1358 | { |
1295 | size_t slot_table_size; | 1359 | size_t slot_table_size; |
1296 | 1360 | struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; | |
1297 | dprintk("RPC: setting up udp-ipv4 transport...\n"); | ||
1298 | 1361 | ||
1299 | xprt->max_reqs = xprt_udp_slot_table_entries; | 1362 | xprt->max_reqs = xprt_udp_slot_table_entries; |
1300 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); | 1363 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); |
@@ -1302,10 +1365,12 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1302 | if (xprt->slot == NULL) | 1365 | if (xprt->slot == NULL) |
1303 | return -ENOMEM; | 1366 | return -ENOMEM; |
1304 | 1367 | ||
1305 | xprt->prot = IPPROTO_UDP; | 1368 | if (ntohs(addr->sin_port != 0)) |
1369 | xprt_set_bound(xprt); | ||
1306 | xprt->port = xs_get_random_port(); | 1370 | xprt->port = xs_get_random_port(); |
1371 | |||
1372 | xprt->prot = IPPROTO_UDP; | ||
1307 | xprt->tsh_size = 0; | 1373 | xprt->tsh_size = 0; |
1308 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | ||
1309 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 1374 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
1310 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 1375 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
1311 | 1376 | ||
@@ -1322,6 +1387,10 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1322 | else | 1387 | else |
1323 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); | 1388 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); |
1324 | 1389 | ||
1390 | xs_format_peer_addresses(xprt); | ||
1391 | dprintk("RPC: set up transport to address %s\n", | ||
1392 | xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1393 | |||
1325 | return 0; | 1394 | return 0; |
1326 | } | 1395 | } |
1327 | 1396 | ||
@@ -1334,8 +1403,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1334 | int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | 1403 | int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) |
1335 | { | 1404 | { |
1336 | size_t slot_table_size; | 1405 | size_t slot_table_size; |
1337 | 1406 | struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; | |
1338 | dprintk("RPC: setting up tcp-ipv4 transport...\n"); | ||
1339 | 1407 | ||
1340 | xprt->max_reqs = xprt_tcp_slot_table_entries; | 1408 | xprt->max_reqs = xprt_tcp_slot_table_entries; |
1341 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); | 1409 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); |
@@ -1343,10 +1411,12 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1343 | if (xprt->slot == NULL) | 1411 | if (xprt->slot == NULL) |
1344 | return -ENOMEM; | 1412 | return -ENOMEM; |
1345 | 1413 | ||
1346 | xprt->prot = IPPROTO_TCP; | 1414 | if (ntohs(addr->sin_port) != 0) |
1415 | xprt_set_bound(xprt); | ||
1347 | xprt->port = xs_get_random_port(); | 1416 | xprt->port = xs_get_random_port(); |
1417 | |||
1418 | xprt->prot = IPPROTO_TCP; | ||
1348 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | 1419 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
1349 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | ||
1350 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1420 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
1351 | 1421 | ||
1352 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); | 1422 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); |
@@ -1362,5 +1432,9 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1362 | else | 1432 | else |
1363 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); | 1433 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); |
1364 | 1434 | ||
1435 | xs_format_peer_addresses(xprt); | ||
1436 | dprintk("RPC: set up transport to address %s\n", | ||
1437 | xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1438 | |||
1365 | return 0; | 1439 | return 0; |
1366 | } | 1440 | } |