diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-06 14:31:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-06 14:31:38 -0500 |
commit | 05c5cb31ec47cacf38db56d9efaa37ca9d473132 (patch) | |
tree | 03f900679819abd8700d5ea93c22e3a59d3af7ca /net/sunrpc | |
parent | 4582a30c2fdca5d2b40f63a20ea082b93230ff2b (diff) | |
parent | 4ea41e2de5bba756858bb40f964e3490b6d1a25c (diff) |
Merge branch 'for-2.6.34' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.34' of git://linux-nfs.org/~bfields/linux: (22 commits)
nfsd4: fix minor memory leak
svcrpc: treat uid's as unsigned
nfsd: ensure sockets are closed on error
Revert "sunrpc: move the close processing after do recvfrom method"
Revert "sunrpc: fix peername failed on closed listener"
sunrpc: remove unnecessary svc_xprt_put
NFSD: NFSv4 callback client should use RPC_TASK_SOFTCONN
xfs_export_operations.commit_metadata
commit_metadata export operation replacing nfsd_sync_dir
lockd: don't clear sm_monitored on nsm_reboot_lookup
lockd: release reference to nsm_handle in nlm_host_rebooted
nfsd: Use vfs_fsync_range() in nfsd_commit
NFSD: Create PF_INET6 listener in write_ports
SUNRPC: NFS kernel APIs shouldn't return ENOENT for "transport not found"
SUNRPC: Bury "#ifdef IPV6" in svc_create_xprt()
NFSD: Support AF_INET6 in svc_addsock() function
SUNRPC: Use rpc_pton() in ip_map_parse()
nfsd: 4.1 has an rfc number
nfsd41: Create the recovery entry for the NFSv4.1 client
nfsd: use vfs_fsync for non-directories
...
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 27 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 49 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 3 |
3 files changed, 43 insertions, 36 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 7d1f9e928f69..8f0f1fb3dc52 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -173,11 +173,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
173 | .sin_addr.s_addr = htonl(INADDR_ANY), | 173 | .sin_addr.s_addr = htonl(INADDR_ANY), |
174 | .sin_port = htons(port), | 174 | .sin_port = htons(port), |
175 | }; | 175 | }; |
176 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
176 | struct sockaddr_in6 sin6 = { | 177 | struct sockaddr_in6 sin6 = { |
177 | .sin6_family = AF_INET6, | 178 | .sin6_family = AF_INET6, |
178 | .sin6_addr = IN6ADDR_ANY_INIT, | 179 | .sin6_addr = IN6ADDR_ANY_INIT, |
179 | .sin6_port = htons(port), | 180 | .sin6_port = htons(port), |
180 | }; | 181 | }; |
182 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
181 | struct sockaddr *sap; | 183 | struct sockaddr *sap; |
182 | size_t len; | 184 | size_t len; |
183 | 185 | ||
@@ -186,10 +188,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
186 | sap = (struct sockaddr *)&sin; | 188 | sap = (struct sockaddr *)&sin; |
187 | len = sizeof(sin); | 189 | len = sizeof(sin); |
188 | break; | 190 | break; |
191 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
189 | case PF_INET6: | 192 | case PF_INET6: |
190 | sap = (struct sockaddr *)&sin6; | 193 | sap = (struct sockaddr *)&sin6; |
191 | len = sizeof(sin6); | 194 | len = sizeof(sin6); |
192 | break; | 195 | break; |
196 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
193 | default: | 197 | default: |
194 | return ERR_PTR(-EAFNOSUPPORT); | 198 | return ERR_PTR(-EAFNOSUPPORT); |
195 | } | 199 | } |
@@ -231,7 +235,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
231 | err: | 235 | err: |
232 | spin_unlock(&svc_xprt_class_lock); | 236 | spin_unlock(&svc_xprt_class_lock); |
233 | dprintk("svc: transport %s not found\n", xprt_name); | 237 | dprintk("svc: transport %s not found\n", xprt_name); |
234 | return -ENOENT; | 238 | |
239 | /* This errno is exposed to user space. Provide a reasonable | ||
240 | * perror msg for a bad transport. */ | ||
241 | return -EPROTONOSUPPORT; | ||
235 | } | 242 | } |
236 | EXPORT_SYMBOL_GPL(svc_create_xprt); | 243 | EXPORT_SYMBOL_GPL(svc_create_xprt); |
237 | 244 | ||
@@ -699,8 +706,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
699 | spin_unlock_bh(&pool->sp_lock); | 706 | spin_unlock_bh(&pool->sp_lock); |
700 | 707 | ||
701 | len = 0; | 708 | len = 0; |
702 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags) && | 709 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
703 | !test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 710 | dprintk("svc_recv: found XPT_CLOSE\n"); |
711 | svc_delete_xprt(xprt); | ||
712 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
704 | struct svc_xprt *newxpt; | 713 | struct svc_xprt *newxpt; |
705 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 714 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
706 | if (newxpt) { | 715 | if (newxpt) { |
@@ -726,7 +735,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
726 | svc_xprt_received(newxpt); | 735 | svc_xprt_received(newxpt); |
727 | } | 736 | } |
728 | svc_xprt_received(xprt); | 737 | svc_xprt_received(xprt); |
729 | } else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 738 | } else { |
730 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 739 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
731 | rqstp, pool->sp_id, xprt, | 740 | rqstp, pool->sp_id, xprt, |
732 | atomic_read(&xprt->xpt_ref.refcount)); | 741 | atomic_read(&xprt->xpt_ref.refcount)); |
@@ -739,11 +748,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
739 | dprintk("svc: got len=%d\n", len); | 748 | dprintk("svc: got len=%d\n", len); |
740 | } | 749 | } |
741 | 750 | ||
742 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | ||
743 | dprintk("svc_recv: found XPT_CLOSE\n"); | ||
744 | svc_delete_xprt(xprt); | ||
745 | } | ||
746 | |||
747 | /* No data, incomplete (TCP) read, or accept() */ | 751 | /* No data, incomplete (TCP) read, or accept() */ |
748 | if (len == 0 || len == -EAGAIN) { | 752 | if (len == 0 || len == -EAGAIN) { |
749 | rqstp->rq_res.len = 0; | 753 | rqstp->rq_res.len = 0; |
@@ -889,11 +893,8 @@ void svc_delete_xprt(struct svc_xprt *xprt) | |||
889 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | 893 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
890 | serv->sv_tmpcnt--; | 894 | serv->sv_tmpcnt--; |
891 | 895 | ||
892 | for (dr = svc_deferred_dequeue(xprt); dr; | 896 | while ((dr = svc_deferred_dequeue(xprt)) != NULL) |
893 | dr = svc_deferred_dequeue(xprt)) { | ||
894 | svc_xprt_put(xprt); | ||
895 | kfree(dr); | 897 | kfree(dr); |
896 | } | ||
897 | 898 | ||
898 | svc_xprt_put(xprt); | 899 | svc_xprt_put(xprt); |
899 | spin_unlock_bh(&serv->sv_lock); | 900 | spin_unlock_bh(&serv->sv_lock); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index d8c041114497..afdcb0459a83 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #define RPCDBG_FACILITY RPCDBG_AUTH | 16 | #define RPCDBG_FACILITY RPCDBG_AUTH |
17 | 17 | ||
18 | #include <linux/sunrpc/clnt.h> | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * AUTHUNIX and AUTHNULL credentials are both handled here. | 21 | * AUTHUNIX and AUTHNULL credentials are both handled here. |
@@ -187,10 +188,13 @@ static int ip_map_parse(struct cache_detail *cd, | |||
187 | * for scratch: */ | 188 | * for scratch: */ |
188 | char *buf = mesg; | 189 | char *buf = mesg; |
189 | int len; | 190 | int len; |
190 | int b1, b2, b3, b4, b5, b6, b7, b8; | ||
191 | char c; | ||
192 | char class[8]; | 191 | char class[8]; |
193 | struct in6_addr addr; | 192 | union { |
193 | struct sockaddr sa; | ||
194 | struct sockaddr_in s4; | ||
195 | struct sockaddr_in6 s6; | ||
196 | } address; | ||
197 | struct sockaddr_in6 sin6; | ||
194 | int err; | 198 | int err; |
195 | 199 | ||
196 | struct ip_map *ipmp; | 200 | struct ip_map *ipmp; |
@@ -209,24 +213,24 @@ static int ip_map_parse(struct cache_detail *cd, | |||
209 | len = qword_get(&mesg, buf, mlen); | 213 | len = qword_get(&mesg, buf, mlen); |
210 | if (len <= 0) return -EINVAL; | 214 | if (len <= 0) return -EINVAL; |
211 | 215 | ||
212 | if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) { | 216 | if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) |
213 | addr.s6_addr32[0] = 0; | ||
214 | addr.s6_addr32[1] = 0; | ||
215 | addr.s6_addr32[2] = htonl(0xffff); | ||
216 | addr.s6_addr32[3] = | ||
217 | htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); | ||
218 | } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c", | ||
219 | &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) { | ||
220 | addr.s6_addr16[0] = htons(b1); | ||
221 | addr.s6_addr16[1] = htons(b2); | ||
222 | addr.s6_addr16[2] = htons(b3); | ||
223 | addr.s6_addr16[3] = htons(b4); | ||
224 | addr.s6_addr16[4] = htons(b5); | ||
225 | addr.s6_addr16[5] = htons(b6); | ||
226 | addr.s6_addr16[6] = htons(b7); | ||
227 | addr.s6_addr16[7] = htons(b8); | ||
228 | } else | ||
229 | return -EINVAL; | 217 | return -EINVAL; |
218 | switch (address.sa.sa_family) { | ||
219 | case AF_INET: | ||
220 | /* Form a mapped IPv4 address in sin6 */ | ||
221 | memset(&sin6, 0, sizeof(sin6)); | ||
222 | sin6.sin6_family = AF_INET6; | ||
223 | sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | ||
224 | sin6.sin6_addr.s6_addr32[3] = address.s4.sin_addr.s_addr; | ||
225 | break; | ||
226 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
227 | case AF_INET6: | ||
228 | memcpy(&sin6, &address.s6, sizeof(sin6)); | ||
229 | break; | ||
230 | #endif | ||
231 | default: | ||
232 | return -EINVAL; | ||
233 | } | ||
230 | 234 | ||
231 | expiry = get_expiry(&mesg); | 235 | expiry = get_expiry(&mesg); |
232 | if (expiry ==0) | 236 | if (expiry ==0) |
@@ -243,7 +247,8 @@ static int ip_map_parse(struct cache_detail *cd, | |||
243 | } else | 247 | } else |
244 | dom = NULL; | 248 | dom = NULL; |
245 | 249 | ||
246 | ipmp = ip_map_lookup(class, &addr); | 250 | /* IPv6 scope IDs are ignored for now */ |
251 | ipmp = ip_map_lookup(class, &sin6.sin6_addr); | ||
247 | if (ipmp) { | 252 | if (ipmp) { |
248 | err = ip_map_update(ipmp, | 253 | err = ip_map_update(ipmp, |
249 | container_of(dom, struct unix_domain, h), | 254 | container_of(dom, struct unix_domain, h), |
@@ -619,7 +624,7 @@ static int unix_gid_show(struct seq_file *m, | |||
619 | else | 624 | else |
620 | glen = 0; | 625 | glen = 0; |
621 | 626 | ||
622 | seq_printf(m, "%d %d:", ug->uid, glen); | 627 | seq_printf(m, "%u %d:", ug->uid, glen); |
623 | for (i = 0; i < glen; i++) | 628 | for (i = 0; i < glen; i++) |
624 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); | 629 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); |
625 | seq_printf(m, "\n"); | 630 | seq_printf(m, "\n"); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 870929e08e5d..a29f259204e6 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -968,6 +968,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
968 | return len; | 968 | return len; |
969 | err_delete: | 969 | err_delete: |
970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
971 | svc_xprt_received(&svsk->sk_xprt); | ||
971 | err_again: | 972 | err_again: |
972 | return -EAGAIN; | 973 | return -EAGAIN; |
973 | } | 974 | } |
@@ -1357,7 +1358,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, | |||
1357 | 1358 | ||
1358 | if (!so) | 1359 | if (!so) |
1359 | return err; | 1360 | return err; |
1360 | if (so->sk->sk_family != AF_INET) | 1361 | if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6)) |
1361 | err = -EAFNOSUPPORT; | 1362 | err = -EAFNOSUPPORT; |
1362 | else if (so->sk->sk_protocol != IPPROTO_TCP && | 1363 | else if (so->sk->sk_protocol != IPPROTO_TCP && |
1363 | so->sk->sk_protocol != IPPROTO_UDP) | 1364 | so->sk->sk_protocol != IPPROTO_UDP) |