diff options
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r-- | net/sunrpc/svcsock.c | 407 |
1 files changed, 279 insertions, 128 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index ff1f8bf680aa..63ae94771b8e 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -36,11 +36,13 @@ | |||
36 | #include <net/sock.h> | 36 | #include <net/sock.h> |
37 | #include <net/checksum.h> | 37 | #include <net/checksum.h> |
38 | #include <net/ip.h> | 38 | #include <net/ip.h> |
39 | #include <net/ipv6.h> | ||
39 | #include <net/tcp_states.h> | 40 | #include <net/tcp_states.h> |
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | #include <asm/ioctls.h> | 42 | #include <asm/ioctls.h> |
42 | 43 | ||
43 | #include <linux/sunrpc/types.h> | 44 | #include <linux/sunrpc/types.h> |
45 | #include <linux/sunrpc/clnt.h> | ||
44 | #include <linux/sunrpc/xdr.h> | 46 | #include <linux/sunrpc/xdr.h> |
45 | #include <linux/sunrpc/svcsock.h> | 47 | #include <linux/sunrpc/svcsock.h> |
46 | #include <linux/sunrpc/stats.h> | 48 | #include <linux/sunrpc/stats.h> |
@@ -58,10 +60,16 @@ | |||
58 | * providing that certain rules are followed: | 60 | * providing that certain rules are followed: |
59 | * | 61 | * |
60 | * SK_CONN, SK_DATA, can be set or cleared at any time. | 62 | * SK_CONN, SK_DATA, can be set or cleared at any time. |
61 | * after a set, svc_sock_enqueue must be called. | 63 | * after a set, svc_sock_enqueue must be called. |
62 | * after a clear, the socket must be read/accepted | 64 | * after a clear, the socket must be read/accepted |
63 | * if this succeeds, it must be set again. | 65 | * if this succeeds, it must be set again. |
64 | * SK_CLOSE can set at any time. It is never cleared. | 66 | * SK_CLOSE can set at any time. It is never cleared. |
67 | * sk_inuse contains a bias of '1' until SK_DEAD is set. | ||
68 | * so when sk_inuse hits zero, we know the socket is dead | ||
69 | * and no-one is using it. | ||
70 | * SK_DEAD can only be set while SK_BUSY is held which ensures | ||
71 | * no other thread will be using the socket or will try to | ||
72 | * set SK_DEAD. | ||
65 | * | 73 | * |
66 | */ | 74 | */ |
67 | 75 | ||
@@ -69,7 +77,8 @@ | |||
69 | 77 | ||
70 | 78 | ||
71 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, | 79 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, |
72 | int *errp, int pmap_reg); | 80 | int *errp, int flags); |
81 | static void svc_delete_socket(struct svc_sock *svsk); | ||
73 | static void svc_udp_data_ready(struct sock *, int); | 82 | static void svc_udp_data_ready(struct sock *, int); |
74 | static int svc_udp_recvfrom(struct svc_rqst *); | 83 | static int svc_udp_recvfrom(struct svc_rqst *); |
75 | static int svc_udp_sendto(struct svc_rqst *); | 84 | static int svc_udp_sendto(struct svc_rqst *); |
@@ -114,6 +123,41 @@ static inline void svc_reclassify_socket(struct socket *sock) | |||
114 | } | 123 | } |
115 | #endif | 124 | #endif |
116 | 125 | ||
126 | static char *__svc_print_addr(struct sockaddr *addr, char *buf, size_t len) | ||
127 | { | ||
128 | switch (addr->sa_family) { | ||
129 | case AF_INET: | ||
130 | snprintf(buf, len, "%u.%u.%u.%u, port=%u", | ||
131 | NIPQUAD(((struct sockaddr_in *) addr)->sin_addr), | ||
132 | htons(((struct sockaddr_in *) addr)->sin_port)); | ||
133 | break; | ||
134 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
135 | case AF_INET6: | ||
136 | snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u", | ||
137 | NIP6(((struct sockaddr_in6 *) addr)->sin6_addr), | ||
138 | htons(((struct sockaddr_in6 *) addr)->sin6_port)); | ||
139 | break; | ||
140 | #endif | ||
141 | default: | ||
142 | snprintf(buf, len, "unknown address type: %d", addr->sa_family); | ||
143 | break; | ||
144 | } | ||
145 | return buf; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * svc_print_addr - Format rq_addr field for printing | ||
150 | * @rqstp: svc_rqst struct containing address to print | ||
151 | * @buf: target buffer for formatted address | ||
152 | * @len: length of target buffer | ||
153 | * | ||
154 | */ | ||
155 | char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len) | ||
156 | { | ||
157 | return __svc_print_addr(svc_addr(rqstp), buf, len); | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(svc_print_addr); | ||
160 | |||
117 | /* | 161 | /* |
118 | * Queue up an idle server thread. Must have pool->sp_lock held. | 162 | * Queue up an idle server thread. Must have pool->sp_lock held. |
119 | * Note: this is really a stack rather than a queue, so that we only | 163 | * Note: this is really a stack rather than a queue, so that we only |
@@ -245,7 +289,7 @@ svc_sock_enqueue(struct svc_sock *svsk) | |||
245 | svsk->sk_sk, rqstp); | 289 | svsk->sk_sk, rqstp); |
246 | svc_thread_dequeue(pool, rqstp); | 290 | svc_thread_dequeue(pool, rqstp); |
247 | if (rqstp->rq_sock) | 291 | if (rqstp->rq_sock) |
248 | printk(KERN_ERR | 292 | printk(KERN_ERR |
249 | "svc_sock_enqueue: server %p, rq_sock=%p!\n", | 293 | "svc_sock_enqueue: server %p, rq_sock=%p!\n", |
250 | rqstp, rqstp->rq_sock); | 294 | rqstp, rqstp->rq_sock); |
251 | rqstp->rq_sock = svsk; | 295 | rqstp->rq_sock = svsk; |
@@ -329,8 +373,9 @@ void svc_reserve(struct svc_rqst *rqstp, int space) | |||
329 | static inline void | 373 | static inline void |
330 | svc_sock_put(struct svc_sock *svsk) | 374 | svc_sock_put(struct svc_sock *svsk) |
331 | { | 375 | { |
332 | if (atomic_dec_and_test(&svsk->sk_inuse) && | 376 | if (atomic_dec_and_test(&svsk->sk_inuse)) { |
333 | test_bit(SK_DEAD, &svsk->sk_flags)) { | 377 | BUG_ON(! test_bit(SK_DEAD, &svsk->sk_flags)); |
378 | |||
334 | dprintk("svc: releasing dead socket\n"); | 379 | dprintk("svc: releasing dead socket\n"); |
335 | if (svsk->sk_sock->file) | 380 | if (svsk->sk_sock->file) |
336 | sockfd_put(svsk->sk_sock); | 381 | sockfd_put(svsk->sk_sock); |
@@ -402,6 +447,43 @@ svc_wake_up(struct svc_serv *serv) | |||
402 | } | 447 | } |
403 | } | 448 | } |
404 | 449 | ||
450 | union svc_pktinfo_u { | ||
451 | struct in_pktinfo pkti; | ||
452 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
453 | struct in6_pktinfo pkti6; | ||
454 | #endif | ||
455 | }; | ||
456 | |||
457 | static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) | ||
458 | { | ||
459 | switch (rqstp->rq_sock->sk_sk->sk_family) { | ||
460 | case AF_INET: { | ||
461 | struct in_pktinfo *pki = CMSG_DATA(cmh); | ||
462 | |||
463 | cmh->cmsg_level = SOL_IP; | ||
464 | cmh->cmsg_type = IP_PKTINFO; | ||
465 | pki->ipi_ifindex = 0; | ||
466 | pki->ipi_spec_dst.s_addr = rqstp->rq_daddr.addr.s_addr; | ||
467 | cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); | ||
468 | } | ||
469 | break; | ||
470 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
471 | case AF_INET6: { | ||
472 | struct in6_pktinfo *pki = CMSG_DATA(cmh); | ||
473 | |||
474 | cmh->cmsg_level = SOL_IPV6; | ||
475 | cmh->cmsg_type = IPV6_PKTINFO; | ||
476 | pki->ipi6_ifindex = 0; | ||
477 | ipv6_addr_copy(&pki->ipi6_addr, | ||
478 | &rqstp->rq_daddr.addr6); | ||
479 | cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); | ||
480 | } | ||
481 | break; | ||
482 | #endif | ||
483 | } | ||
484 | return; | ||
485 | } | ||
486 | |||
405 | /* | 487 | /* |
406 | * Generic sendto routine | 488 | * Generic sendto routine |
407 | */ | 489 | */ |
@@ -411,9 +493,8 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
411 | struct svc_sock *svsk = rqstp->rq_sock; | 493 | struct svc_sock *svsk = rqstp->rq_sock; |
412 | struct socket *sock = svsk->sk_sock; | 494 | struct socket *sock = svsk->sk_sock; |
413 | int slen; | 495 | int slen; |
414 | char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))]; | 496 | char buffer[CMSG_SPACE(sizeof(union svc_pktinfo_u))]; |
415 | struct cmsghdr *cmh = (struct cmsghdr *)buffer; | 497 | struct cmsghdr *cmh = (struct cmsghdr *)buffer; |
416 | struct in_pktinfo *pki = (struct in_pktinfo *)CMSG_DATA(cmh); | ||
417 | int len = 0; | 498 | int len = 0; |
418 | int result; | 499 | int result; |
419 | int size; | 500 | int size; |
@@ -421,25 +502,20 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
421 | size_t base = xdr->page_base; | 502 | size_t base = xdr->page_base; |
422 | unsigned int pglen = xdr->page_len; | 503 | unsigned int pglen = xdr->page_len; |
423 | unsigned int flags = MSG_MORE; | 504 | unsigned int flags = MSG_MORE; |
505 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
424 | 506 | ||
425 | slen = xdr->len; | 507 | slen = xdr->len; |
426 | 508 | ||
427 | if (rqstp->rq_prot == IPPROTO_UDP) { | 509 | if (rqstp->rq_prot == IPPROTO_UDP) { |
428 | /* set the source and destination */ | 510 | struct msghdr msg = { |
429 | struct msghdr msg; | 511 | .msg_name = &rqstp->rq_addr, |
430 | msg.msg_name = &rqstp->rq_addr; | 512 | .msg_namelen = rqstp->rq_addrlen, |
431 | msg.msg_namelen = sizeof(rqstp->rq_addr); | 513 | .msg_control = cmh, |
432 | msg.msg_iov = NULL; | 514 | .msg_controllen = sizeof(buffer), |
433 | msg.msg_iovlen = 0; | 515 | .msg_flags = MSG_MORE, |
434 | msg.msg_flags = MSG_MORE; | 516 | }; |
435 | 517 | ||
436 | msg.msg_control = cmh; | 518 | svc_set_cmsg_data(rqstp, cmh); |
437 | msg.msg_controllen = sizeof(buffer); | ||
438 | cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); | ||
439 | cmh->cmsg_level = SOL_IP; | ||
440 | cmh->cmsg_type = IP_PKTINFO; | ||
441 | pki->ipi_ifindex = 0; | ||
442 | pki->ipi_spec_dst.s_addr = rqstp->rq_daddr; | ||
443 | 519 | ||
444 | if (sock_sendmsg(sock, &msg, 0) < 0) | 520 | if (sock_sendmsg(sock, &msg, 0) < 0) |
445 | goto out; | 521 | goto out; |
@@ -476,16 +552,16 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
476 | if (xdr->tail[0].iov_len) { | 552 | if (xdr->tail[0].iov_len) { |
477 | result = kernel_sendpage(sock, rqstp->rq_respages[0], | 553 | result = kernel_sendpage(sock, rqstp->rq_respages[0], |
478 | ((unsigned long)xdr->tail[0].iov_base) | 554 | ((unsigned long)xdr->tail[0].iov_base) |
479 | & (PAGE_SIZE-1), | 555 | & (PAGE_SIZE-1), |
480 | xdr->tail[0].iov_len, 0); | 556 | xdr->tail[0].iov_len, 0); |
481 | 557 | ||
482 | if (result > 0) | 558 | if (result > 0) |
483 | len += result; | 559 | len += result; |
484 | } | 560 | } |
485 | out: | 561 | out: |
486 | dprintk("svc: socket %p sendto([%p %Zu... ], %d) = %d (addr %x)\n", | 562 | dprintk("svc: socket %p sendto([%p %Zu... ], %d) = %d (addr %s)\n", |
487 | rqstp->rq_sock, xdr->head[0].iov_base, xdr->head[0].iov_len, xdr->len, len, | 563 | rqstp->rq_sock, xdr->head[0].iov_base, xdr->head[0].iov_len, |
488 | rqstp->rq_addr.sin_addr.s_addr); | 564 | xdr->len, len, svc_print_addr(rqstp, buf, sizeof(buf))); |
489 | 565 | ||
490 | return len; | 566 | return len; |
491 | } | 567 | } |
@@ -520,7 +596,7 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose) | |||
520 | 596 | ||
521 | if (!serv) | 597 | if (!serv) |
522 | return 0; | 598 | return 0; |
523 | spin_lock(&serv->sv_lock); | 599 | spin_lock_bh(&serv->sv_lock); |
524 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) { | 600 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) { |
525 | int onelen = one_sock_name(buf+len, svsk); | 601 | int onelen = one_sock_name(buf+len, svsk); |
526 | if (toclose && strcmp(toclose, buf+len) == 0) | 602 | if (toclose && strcmp(toclose, buf+len) == 0) |
@@ -528,12 +604,12 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose) | |||
528 | else | 604 | else |
529 | len += onelen; | 605 | len += onelen; |
530 | } | 606 | } |
531 | spin_unlock(&serv->sv_lock); | 607 | spin_unlock_bh(&serv->sv_lock); |
532 | if (closesk) | 608 | if (closesk) |
533 | /* Should unregister with portmap, but you cannot | 609 | /* Should unregister with portmap, but you cannot |
534 | * unregister just one protocol... | 610 | * unregister just one protocol... |
535 | */ | 611 | */ |
536 | svc_delete_socket(closesk); | 612 | svc_close_socket(closesk); |
537 | else if (toclose) | 613 | else if (toclose) |
538 | return -ENOENT; | 614 | return -ENOENT; |
539 | return len; | 615 | return len; |
@@ -560,31 +636,22 @@ svc_recv_available(struct svc_sock *svsk) | |||
560 | static int | 636 | static int |
561 | svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen) | 637 | svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen) |
562 | { | 638 | { |
563 | struct msghdr msg; | 639 | struct svc_sock *svsk = rqstp->rq_sock; |
564 | struct socket *sock; | 640 | struct msghdr msg = { |
565 | int len, alen; | 641 | .msg_flags = MSG_DONTWAIT, |
566 | 642 | }; | |
567 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); | 643 | int len; |
568 | sock = rqstp->rq_sock->sk_sock; | ||
569 | |||
570 | msg.msg_name = &rqstp->rq_addr; | ||
571 | msg.msg_namelen = sizeof(rqstp->rq_addr); | ||
572 | msg.msg_control = NULL; | ||
573 | msg.msg_controllen = 0; | ||
574 | |||
575 | msg.msg_flags = MSG_DONTWAIT; | ||
576 | 644 | ||
577 | len = kernel_recvmsg(sock, &msg, iov, nr, buflen, MSG_DONTWAIT); | 645 | len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, |
646 | msg.msg_flags); | ||
578 | 647 | ||
579 | /* sock_recvmsg doesn't fill in the name/namelen, so we must.. | 648 | /* sock_recvmsg doesn't fill in the name/namelen, so we must.. |
580 | * possibly we should cache this in the svc_sock structure | ||
581 | * at accept time. FIXME | ||
582 | */ | 649 | */ |
583 | alen = sizeof(rqstp->rq_addr); | 650 | memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen); |
584 | kernel_getpeername(sock, (struct sockaddr *)&rqstp->rq_addr, &alen); | 651 | rqstp->rq_addrlen = svsk->sk_remotelen; |
585 | 652 | ||
586 | dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", | 653 | dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", |
587 | rqstp->rq_sock, iov[0].iov_base, iov[0].iov_len, len); | 654 | svsk, iov[0].iov_base, iov[0].iov_len, len); |
588 | 655 | ||
589 | return len; | 656 | return len; |
590 | } | 657 | } |
@@ -654,6 +721,47 @@ svc_write_space(struct sock *sk) | |||
654 | } | 721 | } |
655 | } | 722 | } |
656 | 723 | ||
724 | static void svc_udp_get_sender_address(struct svc_rqst *rqstp, | ||
725 | struct sk_buff *skb) | ||
726 | { | ||
727 | switch (rqstp->rq_sock->sk_sk->sk_family) { | ||
728 | case AF_INET: { | ||
729 | /* this seems to come from net/ipv4/udp.c:udp_recvmsg */ | ||
730 | struct sockaddr_in *sin = svc_addr_in(rqstp); | ||
731 | |||
732 | sin->sin_family = AF_INET; | ||
733 | sin->sin_port = skb->h.uh->source; | ||
734 | sin->sin_addr.s_addr = skb->nh.iph->saddr; | ||
735 | rqstp->rq_addrlen = sizeof(struct sockaddr_in); | ||
736 | /* Remember which interface received this request */ | ||
737 | rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr; | ||
738 | } | ||
739 | break; | ||
740 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
741 | case AF_INET6: { | ||
742 | /* this is derived from net/ipv6/udp.c:udpv6_recvmesg */ | ||
743 | struct sockaddr_in6 *sin6 = svc_addr_in6(rqstp); | ||
744 | |||
745 | sin6->sin6_family = AF_INET6; | ||
746 | sin6->sin6_port = skb->h.uh->source; | ||
747 | sin6->sin6_flowinfo = 0; | ||
748 | sin6->sin6_scope_id = 0; | ||
749 | if (ipv6_addr_type(&sin6->sin6_addr) & | ||
750 | IPV6_ADDR_LINKLOCAL) | ||
751 | sin6->sin6_scope_id = IP6CB(skb)->iif; | ||
752 | ipv6_addr_copy(&sin6->sin6_addr, | ||
753 | &skb->nh.ipv6h->saddr); | ||
754 | rqstp->rq_addrlen = sizeof(struct sockaddr_in); | ||
755 | /* Remember which interface received this request */ | ||
756 | ipv6_addr_copy(&rqstp->rq_daddr.addr6, | ||
757 | &skb->nh.ipv6h->saddr); | ||
758 | } | ||
759 | break; | ||
760 | #endif | ||
761 | } | ||
762 | return; | ||
763 | } | ||
764 | |||
657 | /* | 765 | /* |
658 | * Receive a datagram from a UDP socket. | 766 | * Receive a datagram from a UDP socket. |
659 | */ | 767 | */ |
@@ -683,6 +791,11 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
683 | return svc_deferred_recv(rqstp); | 791 | return svc_deferred_recv(rqstp); |
684 | } | 792 | } |
685 | 793 | ||
794 | if (test_bit(SK_CLOSE, &svsk->sk_flags)) { | ||
795 | svc_delete_socket(svsk); | ||
796 | return 0; | ||
797 | } | ||
798 | |||
686 | clear_bit(SK_DATA, &svsk->sk_flags); | 799 | clear_bit(SK_DATA, &svsk->sk_flags); |
687 | while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { | 800 | while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { |
688 | if (err == -EAGAIN) { | 801 | if (err == -EAGAIN) { |
@@ -698,7 +811,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
698 | tv.tv_sec = xtime.tv_sec; | 811 | tv.tv_sec = xtime.tv_sec; |
699 | tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC; | 812 | tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC; |
700 | skb_set_timestamp(skb, &tv); | 813 | skb_set_timestamp(skb, &tv); |
701 | /* Don't enable netstamp, sunrpc doesn't | 814 | /* Don't enable netstamp, sunrpc doesn't |
702 | need that much accuracy */ | 815 | need that much accuracy */ |
703 | } | 816 | } |
704 | skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp); | 817 | skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp); |
@@ -712,13 +825,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
712 | len = skb->len - sizeof(struct udphdr); | 825 | len = skb->len - sizeof(struct udphdr); |
713 | rqstp->rq_arg.len = len; | 826 | rqstp->rq_arg.len = len; |
714 | 827 | ||
715 | rqstp->rq_prot = IPPROTO_UDP; | 828 | rqstp->rq_prot = IPPROTO_UDP; |
716 | 829 | ||
717 | /* Get sender address */ | 830 | svc_udp_get_sender_address(rqstp, skb); |
718 | rqstp->rq_addr.sin_family = AF_INET; | ||
719 | rqstp->rq_addr.sin_port = skb->h.uh->source; | ||
720 | rqstp->rq_addr.sin_addr.s_addr = skb->nh.iph->saddr; | ||
721 | rqstp->rq_daddr = skb->nh.iph->daddr; | ||
722 | 831 | ||
723 | if (skb_is_nonlinear(skb)) { | 832 | if (skb_is_nonlinear(skb)) { |
724 | /* we have to copy */ | 833 | /* we have to copy */ |
@@ -730,7 +839,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
730 | return 0; | 839 | return 0; |
731 | } | 840 | } |
732 | local_bh_enable(); | 841 | local_bh_enable(); |
733 | skb_free_datagram(svsk->sk_sk, skb); | 842 | skb_free_datagram(svsk->sk_sk, skb); |
734 | } else { | 843 | } else { |
735 | /* we can use it in-place */ | 844 | /* we can use it in-place */ |
736 | rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); | 845 | rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); |
@@ -781,7 +890,7 @@ svc_udp_init(struct svc_sock *svsk) | |||
781 | svsk->sk_sendto = svc_udp_sendto; | 890 | svsk->sk_sendto = svc_udp_sendto; |
782 | 891 | ||
783 | /* initialise setting must have enough space to | 892 | /* initialise setting must have enough space to |
784 | * receive and respond to one request. | 893 | * receive and respond to one request. |
785 | * svc_udp_recvfrom will re-adjust if necessary | 894 | * svc_udp_recvfrom will re-adjust if necessary |
786 | */ | 895 | */ |
787 | svc_sock_setbufsize(svsk->sk_sock, | 896 | svc_sock_setbufsize(svsk->sk_sock, |
@@ -862,18 +971,36 @@ svc_tcp_data_ready(struct sock *sk, int count) | |||
862 | wake_up_interruptible(sk->sk_sleep); | 971 | wake_up_interruptible(sk->sk_sleep); |
863 | } | 972 | } |
864 | 973 | ||
974 | static inline int svc_port_is_privileged(struct sockaddr *sin) | ||
975 | { | ||
976 | switch (sin->sa_family) { | ||
977 | case AF_INET: | ||
978 | return ntohs(((struct sockaddr_in *)sin)->sin_port) | ||
979 | < PROT_SOCK; | ||
980 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
981 | case AF_INET6: | ||
982 | return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) | ||
983 | < PROT_SOCK; | ||
984 | #endif | ||
985 | default: | ||
986 | return 0; | ||
987 | } | ||
988 | } | ||
989 | |||
865 | /* | 990 | /* |
866 | * Accept a TCP connection | 991 | * Accept a TCP connection |
867 | */ | 992 | */ |
868 | static void | 993 | static void |
869 | svc_tcp_accept(struct svc_sock *svsk) | 994 | svc_tcp_accept(struct svc_sock *svsk) |
870 | { | 995 | { |
871 | struct sockaddr_in sin; | 996 | struct sockaddr_storage addr; |
997 | struct sockaddr *sin = (struct sockaddr *) &addr; | ||
872 | struct svc_serv *serv = svsk->sk_server; | 998 | struct svc_serv *serv = svsk->sk_server; |
873 | struct socket *sock = svsk->sk_sock; | 999 | struct socket *sock = svsk->sk_sock; |
874 | struct socket *newsock; | 1000 | struct socket *newsock; |
875 | struct svc_sock *newsvsk; | 1001 | struct svc_sock *newsvsk; |
876 | int err, slen; | 1002 | int err, slen; |
1003 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
877 | 1004 | ||
878 | dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); | 1005 | dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); |
879 | if (!sock) | 1006 | if (!sock) |
@@ -894,8 +1021,7 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
894 | set_bit(SK_CONN, &svsk->sk_flags); | 1021 | set_bit(SK_CONN, &svsk->sk_flags); |
895 | svc_sock_enqueue(svsk); | 1022 | svc_sock_enqueue(svsk); |
896 | 1023 | ||
897 | slen = sizeof(sin); | 1024 | err = kernel_getpeername(newsock, sin, &slen); |
898 | err = kernel_getpeername(newsock, (struct sockaddr *) &sin, &slen); | ||
899 | if (err < 0) { | 1025 | if (err < 0) { |
900 | if (net_ratelimit()) | 1026 | if (net_ratelimit()) |
901 | printk(KERN_WARNING "%s: peername failed (err %d)!\n", | 1027 | printk(KERN_WARNING "%s: peername failed (err %d)!\n", |
@@ -904,27 +1030,30 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
904 | } | 1030 | } |
905 | 1031 | ||
906 | /* Ideally, we would want to reject connections from unauthorized | 1032 | /* Ideally, we would want to reject connections from unauthorized |
907 | * hosts here, but when we get encription, the IP of the host won't | 1033 | * hosts here, but when we get encryption, the IP of the host won't |
908 | * tell us anything. For now just warn about unpriv connections. | 1034 | * tell us anything. For now just warn about unpriv connections. |
909 | */ | 1035 | */ |
910 | if (ntohs(sin.sin_port) >= 1024) { | 1036 | if (!svc_port_is_privileged(sin)) { |
911 | dprintk(KERN_WARNING | 1037 | dprintk(KERN_WARNING |
912 | "%s: connect from unprivileged port: %u.%u.%u.%u:%d\n", | 1038 | "%s: connect from unprivileged port: %s\n", |
913 | serv->sv_name, | 1039 | serv->sv_name, |
914 | NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port)); | 1040 | __svc_print_addr(sin, buf, sizeof(buf))); |
915 | } | 1041 | } |
916 | 1042 | dprintk("%s: connect from %s\n", serv->sv_name, | |
917 | dprintk("%s: connect from %u.%u.%u.%u:%04x\n", serv->sv_name, | 1043 | __svc_print_addr(sin, buf, sizeof(buf))); |
918 | NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port)); | ||
919 | 1044 | ||
920 | /* make sure that a write doesn't block forever when | 1045 | /* make sure that a write doesn't block forever when |
921 | * low on memory | 1046 | * low on memory |
922 | */ | 1047 | */ |
923 | newsock->sk->sk_sndtimeo = HZ*30; | 1048 | newsock->sk->sk_sndtimeo = HZ*30; |
924 | 1049 | ||
925 | if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0))) | 1050 | if (!(newsvsk = svc_setup_socket(serv, newsock, &err, |
1051 | (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY)))) | ||
926 | goto failed; | 1052 | goto failed; |
1053 | memcpy(&newsvsk->sk_remote, sin, slen); | ||
1054 | newsvsk->sk_remotelen = slen; | ||
927 | 1055 | ||
1056 | svc_sock_received(newsvsk); | ||
928 | 1057 | ||
929 | /* make sure that we don't have too many active connections. | 1058 | /* make sure that we don't have too many active connections. |
930 | * If we have, something must be dropped. | 1059 | * If we have, something must be dropped. |
@@ -947,11 +1076,9 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
947 | "sockets, consider increasing the " | 1076 | "sockets, consider increasing the " |
948 | "number of nfsd threads\n", | 1077 | "number of nfsd threads\n", |
949 | serv->sv_name); | 1078 | serv->sv_name); |
950 | printk(KERN_NOTICE "%s: last TCP connect from " | 1079 | printk(KERN_NOTICE |
951 | "%u.%u.%u.%u:%d\n", | 1080 | "%s: last TCP connect from %s\n", |
952 | serv->sv_name, | 1081 | serv->sv_name, buf); |
953 | NIPQUAD(sin.sin_addr.s_addr), | ||
954 | ntohs(sin.sin_port)); | ||
955 | } | 1082 | } |
956 | /* | 1083 | /* |
957 | * Always select the oldest socket. It's not fair, | 1084 | * Always select the oldest socket. It's not fair, |
@@ -1025,7 +1152,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1025 | * on the number of threads which will access the socket. | 1152 | * on the number of threads which will access the socket. |
1026 | * | 1153 | * |
1027 | * rcvbuf just needs to be able to hold a few requests. | 1154 | * rcvbuf just needs to be able to hold a few requests. |
1028 | * Normally they will be removed from the queue | 1155 | * Normally they will be removed from the queue |
1029 | * as soon a a complete request arrives. | 1156 | * as soon a a complete request arrives. |
1030 | */ | 1157 | */ |
1031 | svc_sock_setbufsize(svsk->sk_sock, | 1158 | svc_sock_setbufsize(svsk->sk_sock, |
@@ -1050,7 +1177,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1050 | 1177 | ||
1051 | if (len < want) { | 1178 | if (len < want) { |
1052 | dprintk("svc: short recvfrom while reading record length (%d of %lu)\n", | 1179 | dprintk("svc: short recvfrom while reading record length (%d of %lu)\n", |
1053 | len, want); | 1180 | len, want); |
1054 | svc_sock_received(svsk); | 1181 | svc_sock_received(svsk); |
1055 | return -EAGAIN; /* record header not complete */ | 1182 | return -EAGAIN; /* record header not complete */ |
1056 | } | 1183 | } |
@@ -1176,7 +1303,8 @@ svc_tcp_sendto(struct svc_rqst *rqstp) | |||
1176 | rqstp->rq_sock->sk_server->sv_name, | 1303 | rqstp->rq_sock->sk_server->sv_name, |
1177 | (sent<0)?"got error":"sent only", | 1304 | (sent<0)?"got error":"sent only", |
1178 | sent, xbufp->len); | 1305 | sent, xbufp->len); |
1179 | svc_delete_socket(rqstp->rq_sock); | 1306 | set_bit(SK_CLOSE, &rqstp->rq_sock->sk_flags); |
1307 | svc_sock_enqueue(rqstp->rq_sock); | ||
1180 | sent = -EAGAIN; | 1308 | sent = -EAGAIN; |
1181 | } | 1309 | } |
1182 | return sent; | 1310 | return sent; |
@@ -1207,7 +1335,7 @@ svc_tcp_init(struct svc_sock *svsk) | |||
1207 | tp->nonagle = 1; /* disable Nagle's algorithm */ | 1335 | tp->nonagle = 1; /* disable Nagle's algorithm */ |
1208 | 1336 | ||
1209 | /* initialise setting must have enough space to | 1337 | /* initialise setting must have enough space to |
1210 | * receive and respond to one request. | 1338 | * receive and respond to one request. |
1211 | * svc_tcp_recvfrom will re-adjust if necessary | 1339 | * svc_tcp_recvfrom will re-adjust if necessary |
1212 | */ | 1340 | */ |
1213 | svc_sock_setbufsize(svsk->sk_sock, | 1341 | svc_sock_setbufsize(svsk->sk_sock, |
@@ -1216,7 +1344,7 @@ svc_tcp_init(struct svc_sock *svsk) | |||
1216 | 1344 | ||
1217 | set_bit(SK_CHNGBUF, &svsk->sk_flags); | 1345 | set_bit(SK_CHNGBUF, &svsk->sk_flags); |
1218 | set_bit(SK_DATA, &svsk->sk_flags); | 1346 | set_bit(SK_DATA, &svsk->sk_flags); |
1219 | if (sk->sk_state != TCP_ESTABLISHED) | 1347 | if (sk->sk_state != TCP_ESTABLISHED) |
1220 | set_bit(SK_CLOSE, &svsk->sk_flags); | 1348 | set_bit(SK_CLOSE, &svsk->sk_flags); |
1221 | } | 1349 | } |
1222 | } | 1350 | } |
@@ -1232,7 +1360,7 @@ svc_sock_update_bufs(struct svc_serv *serv) | |||
1232 | 1360 | ||
1233 | spin_lock_bh(&serv->sv_lock); | 1361 | spin_lock_bh(&serv->sv_lock); |
1234 | list_for_each(le, &serv->sv_permsocks) { | 1362 | list_for_each(le, &serv->sv_permsocks) { |
1235 | struct svc_sock *svsk = | 1363 | struct svc_sock *svsk = |
1236 | list_entry(le, struct svc_sock, sk_list); | 1364 | list_entry(le, struct svc_sock, sk_list); |
1237 | set_bit(SK_CHNGBUF, &svsk->sk_flags); | 1365 | set_bit(SK_CHNGBUF, &svsk->sk_flags); |
1238 | } | 1366 | } |
@@ -1252,7 +1380,7 @@ svc_sock_update_bufs(struct svc_serv *serv) | |||
1252 | int | 1380 | int |
1253 | svc_recv(struct svc_rqst *rqstp, long timeout) | 1381 | svc_recv(struct svc_rqst *rqstp, long timeout) |
1254 | { | 1382 | { |
1255 | struct svc_sock *svsk =NULL; | 1383 | struct svc_sock *svsk = NULL; |
1256 | struct svc_serv *serv = rqstp->rq_server; | 1384 | struct svc_serv *serv = rqstp->rq_server; |
1257 | struct svc_pool *pool = rqstp->rq_pool; | 1385 | struct svc_pool *pool = rqstp->rq_pool; |
1258 | int len, i; | 1386 | int len, i; |
@@ -1264,11 +1392,11 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
1264 | rqstp, timeout); | 1392 | rqstp, timeout); |
1265 | 1393 | ||
1266 | if (rqstp->rq_sock) | 1394 | if (rqstp->rq_sock) |
1267 | printk(KERN_ERR | 1395 | printk(KERN_ERR |
1268 | "svc_recv: service %p, socket not NULL!\n", | 1396 | "svc_recv: service %p, socket not NULL!\n", |
1269 | rqstp); | 1397 | rqstp); |
1270 | if (waitqueue_active(&rqstp->rq_wait)) | 1398 | if (waitqueue_active(&rqstp->rq_wait)) |
1271 | printk(KERN_ERR | 1399 | printk(KERN_ERR |
1272 | "svc_recv: service %p, wait queue active!\n", | 1400 | "svc_recv: service %p, wait queue active!\n", |
1273 | rqstp); | 1401 | rqstp); |
1274 | 1402 | ||
@@ -1349,7 +1477,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
1349 | svsk->sk_lastrecv = get_seconds(); | 1477 | svsk->sk_lastrecv = get_seconds(); |
1350 | clear_bit(SK_OLD, &svsk->sk_flags); | 1478 | clear_bit(SK_OLD, &svsk->sk_flags); |
1351 | 1479 | ||
1352 | rqstp->rq_secure = ntohs(rqstp->rq_addr.sin_port) < 1024; | 1480 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); |
1353 | rqstp->rq_chandle.defer = svc_defer; | 1481 | rqstp->rq_chandle.defer = svc_defer; |
1354 | 1482 | ||
1355 | if (serv->sv_stats) | 1483 | if (serv->sv_stats) |
@@ -1357,7 +1485,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
1357 | return len; | 1485 | return len; |
1358 | } | 1486 | } |
1359 | 1487 | ||
1360 | /* | 1488 | /* |
1361 | * Drop request | 1489 | * Drop request |
1362 | */ | 1490 | */ |
1363 | void | 1491 | void |
@@ -1462,12 +1590,14 @@ svc_age_temp_sockets(unsigned long closure) | |||
1462 | * Initialize socket for RPC use and create svc_sock struct | 1590 | * Initialize socket for RPC use and create svc_sock struct |
1463 | * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. | 1591 | * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. |
1464 | */ | 1592 | */ |
1465 | static struct svc_sock * | 1593 | static struct svc_sock *svc_setup_socket(struct svc_serv *serv, |
1466 | svc_setup_socket(struct svc_serv *serv, struct socket *sock, | 1594 | struct socket *sock, |
1467 | int *errp, int pmap_register) | 1595 | int *errp, int flags) |
1468 | { | 1596 | { |
1469 | struct svc_sock *svsk; | 1597 | struct svc_sock *svsk; |
1470 | struct sock *inet; | 1598 | struct sock *inet; |
1599 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); | ||
1600 | int is_temporary = flags & SVC_SOCK_TEMPORARY; | ||
1471 | 1601 | ||
1472 | dprintk("svc: svc_setup_socket %p\n", sock); | 1602 | dprintk("svc: svc_setup_socket %p\n", sock); |
1473 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { | 1603 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { |
@@ -1495,7 +1625,7 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock, | |||
1495 | svsk->sk_odata = inet->sk_data_ready; | 1625 | svsk->sk_odata = inet->sk_data_ready; |
1496 | svsk->sk_owspace = inet->sk_write_space; | 1626 | svsk->sk_owspace = inet->sk_write_space; |
1497 | svsk->sk_server = serv; | 1627 | svsk->sk_server = serv; |
1498 | atomic_set(&svsk->sk_inuse, 0); | 1628 | atomic_set(&svsk->sk_inuse, 1); |
1499 | svsk->sk_lastrecv = get_seconds(); | 1629 | svsk->sk_lastrecv = get_seconds(); |
1500 | spin_lock_init(&svsk->sk_defer_lock); | 1630 | spin_lock_init(&svsk->sk_defer_lock); |
1501 | INIT_LIST_HEAD(&svsk->sk_deferred); | 1631 | INIT_LIST_HEAD(&svsk->sk_deferred); |
@@ -1509,7 +1639,7 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock, | |||
1509 | svc_tcp_init(svsk); | 1639 | svc_tcp_init(svsk); |
1510 | 1640 | ||
1511 | spin_lock_bh(&serv->sv_lock); | 1641 | spin_lock_bh(&serv->sv_lock); |
1512 | if (!pmap_register) { | 1642 | if (is_temporary) { |
1513 | set_bit(SK_TEMP, &svsk->sk_flags); | 1643 | set_bit(SK_TEMP, &svsk->sk_flags); |
1514 | list_add(&svsk->sk_list, &serv->sv_tempsocks); | 1644 | list_add(&svsk->sk_list, &serv->sv_tempsocks); |
1515 | serv->sv_tmpcnt++; | 1645 | serv->sv_tmpcnt++; |
@@ -1529,8 +1659,6 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock, | |||
1529 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", | 1659 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", |
1530 | svsk, svsk->sk_sk); | 1660 | svsk, svsk->sk_sk); |
1531 | 1661 | ||
1532 | clear_bit(SK_BUSY, &svsk->sk_flags); | ||
1533 | svc_sock_enqueue(svsk); | ||
1534 | return svsk; | 1662 | return svsk; |
1535 | } | 1663 | } |
1536 | 1664 | ||
@@ -1553,9 +1681,11 @@ int svc_addsock(struct svc_serv *serv, | |||
1553 | else if (so->state > SS_UNCONNECTED) | 1681 | else if (so->state > SS_UNCONNECTED) |
1554 | err = -EISCONN; | 1682 | err = -EISCONN; |
1555 | else { | 1683 | else { |
1556 | svsk = svc_setup_socket(serv, so, &err, 1); | 1684 | svsk = svc_setup_socket(serv, so, &err, SVC_SOCK_DEFAULTS); |
1557 | if (svsk) | 1685 | if (svsk) { |
1686 | svc_sock_received(svsk); | ||
1558 | err = 0; | 1687 | err = 0; |
1688 | } | ||
1559 | } | 1689 | } |
1560 | if (err) { | 1690 | if (err) { |
1561 | sockfd_put(so); | 1691 | sockfd_put(so); |
@@ -1569,18 +1699,18 @@ EXPORT_SYMBOL_GPL(svc_addsock); | |||
1569 | /* | 1699 | /* |
1570 | * Create socket for RPC service. | 1700 | * Create socket for RPC service. |
1571 | */ | 1701 | */ |
1572 | static int | 1702 | static int svc_create_socket(struct svc_serv *serv, int protocol, |
1573 | svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin) | 1703 | struct sockaddr *sin, int len, int flags) |
1574 | { | 1704 | { |
1575 | struct svc_sock *svsk; | 1705 | struct svc_sock *svsk; |
1576 | struct socket *sock; | 1706 | struct socket *sock; |
1577 | int error; | 1707 | int error; |
1578 | int type; | 1708 | int type; |
1709 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
1579 | 1710 | ||
1580 | dprintk("svc: svc_create_socket(%s, %d, %u.%u.%u.%u:%d)\n", | 1711 | dprintk("svc: svc_create_socket(%s, %d, %s)\n", |
1581 | serv->sv_program->pg_name, protocol, | 1712 | serv->sv_program->pg_name, protocol, |
1582 | NIPQUAD(sin->sin_addr.s_addr), | 1713 | __svc_print_addr(sin, buf, sizeof(buf))); |
1583 | ntohs(sin->sin_port)); | ||
1584 | 1714 | ||
1585 | if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) { | 1715 | if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) { |
1586 | printk(KERN_WARNING "svc: only UDP and TCP " | 1716 | printk(KERN_WARNING "svc: only UDP and TCP " |
@@ -1589,15 +1719,15 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin) | |||
1589 | } | 1719 | } |
1590 | type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; | 1720 | type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; |
1591 | 1721 | ||
1592 | if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0) | 1722 | error = sock_create_kern(sin->sa_family, type, protocol, &sock); |
1723 | if (error < 0) | ||
1593 | return error; | 1724 | return error; |
1594 | 1725 | ||
1595 | svc_reclassify_socket(sock); | 1726 | svc_reclassify_socket(sock); |
1596 | 1727 | ||
1597 | if (type == SOCK_STREAM) | 1728 | if (type == SOCK_STREAM) |
1598 | sock->sk->sk_reuse = 1; /* allow address reuse */ | 1729 | sock->sk->sk_reuse = 1; /* allow address reuse */ |
1599 | error = kernel_bind(sock, (struct sockaddr *) sin, | 1730 | error = kernel_bind(sock, sin, len); |
1600 | sizeof(*sin)); | ||
1601 | if (error < 0) | 1731 | if (error < 0) |
1602 | goto bummer; | 1732 | goto bummer; |
1603 | 1733 | ||
@@ -1606,8 +1736,10 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin) | |||
1606 | goto bummer; | 1736 | goto bummer; |
1607 | } | 1737 | } |
1608 | 1738 | ||
1609 | if ((svsk = svc_setup_socket(serv, sock, &error, 1)) != NULL) | 1739 | if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { |
1610 | return 0; | 1740 | svc_sock_received(svsk); |
1741 | return ntohs(inet_sk(svsk->sk_sk)->sport); | ||
1742 | } | ||
1611 | 1743 | ||
1612 | bummer: | 1744 | bummer: |
1613 | dprintk("svc: svc_create_socket error = %d\n", -error); | 1745 | dprintk("svc: svc_create_socket error = %d\n", -error); |
@@ -1618,7 +1750,7 @@ bummer: | |||
1618 | /* | 1750 | /* |
1619 | * Remove a dead socket | 1751 | * Remove a dead socket |
1620 | */ | 1752 | */ |
1621 | void | 1753 | static void |
1622 | svc_delete_socket(struct svc_sock *svsk) | 1754 | svc_delete_socket(struct svc_sock *svsk) |
1623 | { | 1755 | { |
1624 | struct svc_serv *serv; | 1756 | struct svc_serv *serv; |
@@ -1637,43 +1769,60 @@ svc_delete_socket(struct svc_sock *svsk) | |||
1637 | 1769 | ||
1638 | if (!test_and_set_bit(SK_DETACHED, &svsk->sk_flags)) | 1770 | if (!test_and_set_bit(SK_DETACHED, &svsk->sk_flags)) |
1639 | list_del_init(&svsk->sk_list); | 1771 | list_del_init(&svsk->sk_list); |
1640 | /* | 1772 | /* |
1641 | * We used to delete the svc_sock from whichever list | 1773 | * We used to delete the svc_sock from whichever list |
1642 | * it's sk_ready node was on, but we don't actually | 1774 | * it's sk_ready node was on, but we don't actually |
1643 | * need to. This is because the only time we're called | 1775 | * need to. This is because the only time we're called |
1644 | * while still attached to a queue, the queue itself | 1776 | * while still attached to a queue, the queue itself |
1645 | * is about to be destroyed (in svc_destroy). | 1777 | * is about to be destroyed (in svc_destroy). |
1646 | */ | 1778 | */ |
1647 | if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags)) | 1779 | if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags)) { |
1780 | BUG_ON(atomic_read(&svsk->sk_inuse)<2); | ||
1781 | atomic_dec(&svsk->sk_inuse); | ||
1648 | if (test_bit(SK_TEMP, &svsk->sk_flags)) | 1782 | if (test_bit(SK_TEMP, &svsk->sk_flags)) |
1649 | serv->sv_tmpcnt--; | 1783 | serv->sv_tmpcnt--; |
1784 | } | ||
1650 | 1785 | ||
1651 | /* This atomic_inc should be needed - svc_delete_socket | ||
1652 | * should have the semantic of dropping a reference. | ||
1653 | * But it doesn't yet.... | ||
1654 | */ | ||
1655 | atomic_inc(&svsk->sk_inuse); | ||
1656 | spin_unlock_bh(&serv->sv_lock); | 1786 | spin_unlock_bh(&serv->sv_lock); |
1787 | } | ||
1788 | |||
1789 | void svc_close_socket(struct svc_sock *svsk) | ||
1790 | { | ||
1791 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
1792 | if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) | ||
1793 | /* someone else will have to effect the close */ | ||
1794 | return; | ||
1795 | |||
1796 | atomic_inc(&svsk->sk_inuse); | ||
1797 | svc_delete_socket(svsk); | ||
1798 | clear_bit(SK_BUSY, &svsk->sk_flags); | ||
1657 | svc_sock_put(svsk); | 1799 | svc_sock_put(svsk); |
1658 | } | 1800 | } |
1659 | 1801 | ||
1660 | /* | 1802 | /** |
1661 | * Make a socket for nfsd and lockd | 1803 | * svc_makesock - Make a socket for nfsd and lockd |
1804 | * @serv: RPC server structure | ||
1805 | * @protocol: transport protocol to use | ||
1806 | * @port: port to use | ||
1807 | * @flags: requested socket characteristics | ||
1808 | * | ||
1662 | */ | 1809 | */ |
1663 | int | 1810 | int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port, |
1664 | svc_makesock(struct svc_serv *serv, int protocol, unsigned short port) | 1811 | int flags) |
1665 | { | 1812 | { |
1666 | struct sockaddr_in sin; | 1813 | struct sockaddr_in sin = { |
1814 | .sin_family = AF_INET, | ||
1815 | .sin_addr.s_addr = INADDR_ANY, | ||
1816 | .sin_port = htons(port), | ||
1817 | }; | ||
1667 | 1818 | ||
1668 | dprintk("svc: creating socket proto = %d\n", protocol); | 1819 | dprintk("svc: creating socket proto = %d\n", protocol); |
1669 | sin.sin_family = AF_INET; | 1820 | return svc_create_socket(serv, protocol, (struct sockaddr *) &sin, |
1670 | sin.sin_addr.s_addr = INADDR_ANY; | 1821 | sizeof(sin), flags); |
1671 | sin.sin_port = htons(port); | ||
1672 | return svc_create_socket(serv, protocol, &sin); | ||
1673 | } | 1822 | } |
1674 | 1823 | ||
1675 | /* | 1824 | /* |
1676 | * Handle defer and revisit of requests | 1825 | * Handle defer and revisit of requests |
1677 | */ | 1826 | */ |
1678 | 1827 | ||
1679 | static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | 1828 | static void svc_revisit(struct cache_deferred_req *dreq, int too_many) |
@@ -1718,7 +1867,8 @@ svc_defer(struct cache_req *req) | |||
1718 | 1867 | ||
1719 | dr->handle.owner = rqstp->rq_server; | 1868 | dr->handle.owner = rqstp->rq_server; |
1720 | dr->prot = rqstp->rq_prot; | 1869 | dr->prot = rqstp->rq_prot; |
1721 | dr->addr = rqstp->rq_addr; | 1870 | memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen); |
1871 | dr->addrlen = rqstp->rq_addrlen; | ||
1722 | dr->daddr = rqstp->rq_daddr; | 1872 | dr->daddr = rqstp->rq_daddr; |
1723 | dr->argslen = rqstp->rq_arg.len >> 2; | 1873 | dr->argslen = rqstp->rq_arg.len >> 2; |
1724 | memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2); | 1874 | memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2); |
@@ -1742,7 +1892,8 @@ static int svc_deferred_recv(struct svc_rqst *rqstp) | |||
1742 | rqstp->rq_arg.page_len = 0; | 1892 | rqstp->rq_arg.page_len = 0; |
1743 | rqstp->rq_arg.len = dr->argslen<<2; | 1893 | rqstp->rq_arg.len = dr->argslen<<2; |
1744 | rqstp->rq_prot = dr->prot; | 1894 | rqstp->rq_prot = dr->prot; |
1745 | rqstp->rq_addr = dr->addr; | 1895 | memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen); |
1896 | rqstp->rq_addrlen = dr->addrlen; | ||
1746 | rqstp->rq_daddr = dr->daddr; | 1897 | rqstp->rq_daddr = dr->daddr; |
1747 | rqstp->rq_respages = rqstp->rq_pages; | 1898 | rqstp->rq_respages = rqstp->rq_pages; |
1748 | return dr->argslen<<2; | 1899 | return dr->argslen<<2; |
@@ -1752,7 +1903,7 @@ static int svc_deferred_recv(struct svc_rqst *rqstp) | |||
1752 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) | 1903 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) |
1753 | { | 1904 | { |
1754 | struct svc_deferred_req *dr = NULL; | 1905 | struct svc_deferred_req *dr = NULL; |
1755 | 1906 | ||
1756 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) | 1907 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) |
1757 | return NULL; | 1908 | return NULL; |
1758 | spin_lock_bh(&svsk->sk_defer_lock); | 1909 | spin_lock_bh(&svsk->sk_defer_lock); |