diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 2 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 3 | ||||
-rw-r--r-- | net/core/pktgen.c | 146 | ||||
-rw-r--r-- | net/core/utils.c | 24 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 4 | ||||
-rw-r--r-- | net/ipv4/route.c | 2 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 7 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_sync.c | 3 | ||||
-rw-r--r-- | net/mac80211/status.c | 4 | ||||
-rw-r--r-- | net/mac80211/tx.c | 22 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 233 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 157 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 4 |
15 files changed, 273 insertions, 343 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 9d49ee6d7219..ba033f09196e 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -591,7 +591,7 @@ static int bt_seq_show(struct seq_file *seq, void *v) | |||
591 | atomic_read(&sk->sk_refcnt), | 591 | atomic_read(&sk->sk_refcnt), |
592 | sk_rmem_alloc_get(sk), | 592 | sk_rmem_alloc_get(sk), |
593 | sk_wmem_alloc_get(sk), | 593 | sk_wmem_alloc_get(sk), |
594 | sock_i_uid(sk), | 594 | from_kuid(seq_user_ns(seq), sock_i_uid(sk)), |
595 | sock_i_ino(sk), | 595 | sock_i_ino(sk), |
596 | &src_baswapped, | 596 | &src_baswapped, |
597 | &dst_baswapped, | 597 | &dst_baswapped, |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 68e8f364bbf8..fe43bc7b063f 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -265,6 +265,9 @@ static int br_parse_ip_options(struct sk_buff *skb) | |||
265 | struct net_device *dev = skb->dev; | 265 | struct net_device *dev = skb->dev; |
266 | u32 len; | 266 | u32 len; |
267 | 267 | ||
268 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
269 | goto inhdr_error; | ||
270 | |||
268 | iph = ip_hdr(skb); | 271 | iph = ip_hdr(skb); |
269 | opt = &(IPCB(skb)->opt); | 272 | opt = &(IPCB(skb)->opt); |
270 | 273 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 148e73d2c451..d1dc14c2aac4 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -248,8 +248,8 @@ struct pktgen_dev { | |||
248 | int removal_mark; /* non-zero => the device is marked for | 248 | int removal_mark; /* non-zero => the device is marked for |
249 | * removal by worker thread */ | 249 | * removal by worker thread */ |
250 | 250 | ||
251 | int min_pkt_size; /* = ETH_ZLEN; */ | 251 | int min_pkt_size; |
252 | int max_pkt_size; /* = ETH_ZLEN; */ | 252 | int max_pkt_size; |
253 | int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */ | 253 | int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */ |
254 | int nfrags; | 254 | int nfrags; |
255 | struct page *page; | 255 | struct page *page; |
@@ -449,8 +449,6 @@ static void pktgen_stop_all_threads_ifs(void); | |||
449 | static void pktgen_stop(struct pktgen_thread *t); | 449 | static void pktgen_stop(struct pktgen_thread *t); |
450 | static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); | 450 | static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); |
451 | 451 | ||
452 | static unsigned int scan_ip6(const char *s, char ip[16]); | ||
453 | |||
454 | /* Module parameters, defaults. */ | 452 | /* Module parameters, defaults. */ |
455 | static int pg_count_d __read_mostly = 1000; | 453 | static int pg_count_d __read_mostly = 1000; |
456 | static int pg_delay_d __read_mostly; | 454 | static int pg_delay_d __read_mostly; |
@@ -702,8 +700,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
702 | &pkt_dev->cur_in6_saddr, | 700 | &pkt_dev->cur_in6_saddr, |
703 | &pkt_dev->cur_in6_daddr); | 701 | &pkt_dev->cur_in6_daddr); |
704 | } else | 702 | } else |
705 | seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n", | 703 | seq_printf(seq, " cur_saddr: %pI4 cur_daddr: %pI4\n", |
706 | pkt_dev->cur_saddr, pkt_dev->cur_daddr); | 704 | &pkt_dev->cur_saddr, &pkt_dev->cur_daddr); |
707 | 705 | ||
708 | seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n", | 706 | seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n", |
709 | pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); | 707 | pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); |
@@ -1299,7 +1297,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1299 | return -EFAULT; | 1297 | return -EFAULT; |
1300 | buf[len] = 0; | 1298 | buf[len] = 0; |
1301 | 1299 | ||
1302 | scan_ip6(buf, pkt_dev->in6_daddr.s6_addr); | 1300 | in6_pton(buf, -1, pkt_dev->in6_daddr.s6_addr, -1, NULL); |
1303 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr); | 1301 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr); |
1304 | 1302 | ||
1305 | pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr; | 1303 | pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr; |
@@ -1322,7 +1320,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1322 | return -EFAULT; | 1320 | return -EFAULT; |
1323 | buf[len] = 0; | 1321 | buf[len] = 0; |
1324 | 1322 | ||
1325 | scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr); | 1323 | in6_pton(buf, -1, pkt_dev->min_in6_daddr.s6_addr, -1, NULL); |
1326 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr); | 1324 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr); |
1327 | 1325 | ||
1328 | pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr; | 1326 | pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr; |
@@ -1344,7 +1342,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1344 | return -EFAULT; | 1342 | return -EFAULT; |
1345 | buf[len] = 0; | 1343 | buf[len] = 0; |
1346 | 1344 | ||
1347 | scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr); | 1345 | in6_pton(buf, -1, pkt_dev->max_in6_daddr.s6_addr, -1, NULL); |
1348 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr); | 1346 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr); |
1349 | 1347 | ||
1350 | if (debug) | 1348 | if (debug) |
@@ -1365,7 +1363,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1365 | return -EFAULT; | 1363 | return -EFAULT; |
1366 | buf[len] = 0; | 1364 | buf[len] = 0; |
1367 | 1365 | ||
1368 | scan_ip6(buf, pkt_dev->in6_saddr.s6_addr); | 1366 | in6_pton(buf, -1, pkt_dev->in6_saddr.s6_addr, -1, NULL); |
1369 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr); | 1367 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr); |
1370 | 1368 | ||
1371 | pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr; | 1369 | pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr; |
@@ -2036,19 +2034,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2036 | /* Set up Dest MAC */ | 2034 | /* Set up Dest MAC */ |
2037 | memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN); | 2035 | memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN); |
2038 | 2036 | ||
2039 | /* Set up pkt size */ | ||
2040 | pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size; | ||
2041 | |||
2042 | if (pkt_dev->flags & F_IPV6) { | 2037 | if (pkt_dev->flags & F_IPV6) { |
2043 | /* | ||
2044 | * Skip this automatic address setting until locks or functions | ||
2045 | * gets exported | ||
2046 | */ | ||
2047 | |||
2048 | #ifdef NOTNOW | ||
2049 | int i, set = 0, err = 1; | 2038 | int i, set = 0, err = 1; |
2050 | struct inet6_dev *idev; | 2039 | struct inet6_dev *idev; |
2051 | 2040 | ||
2041 | if (pkt_dev->min_pkt_size == 0) { | ||
2042 | pkt_dev->min_pkt_size = 14 + sizeof(struct ipv6hdr) | ||
2043 | + sizeof(struct udphdr) | ||
2044 | + sizeof(struct pktgen_hdr) | ||
2045 | + pkt_dev->pkt_overhead; | ||
2046 | } | ||
2047 | |||
2052 | for (i = 0; i < IN6_ADDR_HSIZE; i++) | 2048 | for (i = 0; i < IN6_ADDR_HSIZE; i++) |
2053 | if (pkt_dev->cur_in6_saddr.s6_addr[i]) { | 2049 | if (pkt_dev->cur_in6_saddr.s6_addr[i]) { |
2054 | set = 1; | 2050 | set = 1; |
@@ -2069,9 +2065,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2069 | struct inet6_ifaddr *ifp; | 2065 | struct inet6_ifaddr *ifp; |
2070 | 2066 | ||
2071 | read_lock_bh(&idev->lock); | 2067 | read_lock_bh(&idev->lock); |
2072 | for (ifp = idev->addr_list; ifp; | 2068 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
2073 | ifp = ifp->if_next) { | 2069 | if ((ifp->scope & IFA_LINK) && |
2074 | if (ifp->scope == IFA_LINK && | ||
2075 | !(ifp->flags & IFA_F_TENTATIVE)) { | 2070 | !(ifp->flags & IFA_F_TENTATIVE)) { |
2076 | pkt_dev->cur_in6_saddr = ifp->addr; | 2071 | pkt_dev->cur_in6_saddr = ifp->addr; |
2077 | err = 0; | 2072 | err = 0; |
@@ -2084,8 +2079,14 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2084 | if (err) | 2079 | if (err) |
2085 | pr_err("ERROR: IPv6 link address not available\n"); | 2080 | pr_err("ERROR: IPv6 link address not available\n"); |
2086 | } | 2081 | } |
2087 | #endif | ||
2088 | } else { | 2082 | } else { |
2083 | if (pkt_dev->min_pkt_size == 0) { | ||
2084 | pkt_dev->min_pkt_size = 14 + sizeof(struct iphdr) | ||
2085 | + sizeof(struct udphdr) | ||
2086 | + sizeof(struct pktgen_hdr) | ||
2087 | + pkt_dev->pkt_overhead; | ||
2088 | } | ||
2089 | |||
2089 | pkt_dev->saddr_min = 0; | 2090 | pkt_dev->saddr_min = 0; |
2090 | pkt_dev->saddr_max = 0; | 2091 | pkt_dev->saddr_max = 0; |
2091 | if (strlen(pkt_dev->src_min) == 0) { | 2092 | if (strlen(pkt_dev->src_min) == 0) { |
@@ -2111,6 +2112,10 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2111 | pkt_dev->daddr_max = in_aton(pkt_dev->dst_max); | 2112 | pkt_dev->daddr_max = in_aton(pkt_dev->dst_max); |
2112 | } | 2113 | } |
2113 | /* Initialize current values. */ | 2114 | /* Initialize current values. */ |
2115 | pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size; | ||
2116 | if (pkt_dev->min_pkt_size > pkt_dev->max_pkt_size) | ||
2117 | pkt_dev->max_pkt_size = pkt_dev->min_pkt_size; | ||
2118 | |||
2114 | pkt_dev->cur_dst_mac_offset = 0; | 2119 | pkt_dev->cur_dst_mac_offset = 0; |
2115 | pkt_dev->cur_src_mac_offset = 0; | 2120 | pkt_dev->cur_src_mac_offset = 0; |
2116 | pkt_dev->cur_saddr = pkt_dev->saddr_min; | 2121 | pkt_dev->cur_saddr = pkt_dev->saddr_min; |
@@ -2758,97 +2763,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2758 | return skb; | 2763 | return skb; |
2759 | } | 2764 | } |
2760 | 2765 | ||
2761 | /* | ||
2762 | * scan_ip6, fmt_ip taken from dietlibc-0.21 | ||
2763 | * Author Felix von Leitner <felix-dietlibc@fefe.de> | ||
2764 | * | ||
2765 | * Slightly modified for kernel. | ||
2766 | * Should be candidate for net/ipv4/utils.c | ||
2767 | * --ro | ||
2768 | */ | ||
2769 | |||
2770 | static unsigned int scan_ip6(const char *s, char ip[16]) | ||
2771 | { | ||
2772 | unsigned int i; | ||
2773 | unsigned int len = 0; | ||
2774 | unsigned long u; | ||
2775 | char suffix[16]; | ||
2776 | unsigned int prefixlen = 0; | ||
2777 | unsigned int suffixlen = 0; | ||
2778 | __be32 tmp; | ||
2779 | char *pos; | ||
2780 | |||
2781 | for (i = 0; i < 16; i++) | ||
2782 | ip[i] = 0; | ||
2783 | |||
2784 | for (;;) { | ||
2785 | if (*s == ':') { | ||
2786 | len++; | ||
2787 | if (s[1] == ':') { /* Found "::", skip to part 2 */ | ||
2788 | s += 2; | ||
2789 | len++; | ||
2790 | break; | ||
2791 | } | ||
2792 | s++; | ||
2793 | } | ||
2794 | |||
2795 | u = simple_strtoul(s, &pos, 16); | ||
2796 | i = pos - s; | ||
2797 | if (!i) | ||
2798 | return 0; | ||
2799 | if (prefixlen == 12 && s[i] == '.') { | ||
2800 | |||
2801 | /* the last 4 bytes may be written as IPv4 address */ | ||
2802 | |||
2803 | tmp = in_aton(s); | ||
2804 | memcpy((struct in_addr *)(ip + 12), &tmp, sizeof(tmp)); | ||
2805 | return i + len; | ||
2806 | } | ||
2807 | ip[prefixlen++] = (u >> 8); | ||
2808 | ip[prefixlen++] = (u & 255); | ||
2809 | s += i; | ||
2810 | len += i; | ||
2811 | if (prefixlen == 16) | ||
2812 | return len; | ||
2813 | } | ||
2814 | |||
2815 | /* part 2, after "::" */ | ||
2816 | for (;;) { | ||
2817 | if (*s == ':') { | ||
2818 | if (suffixlen == 0) | ||
2819 | break; | ||
2820 | s++; | ||
2821 | len++; | ||
2822 | } else if (suffixlen != 0) | ||
2823 | break; | ||
2824 | |||
2825 | u = simple_strtol(s, &pos, 16); | ||
2826 | i = pos - s; | ||
2827 | if (!i) { | ||
2828 | if (*s) | ||
2829 | len--; | ||
2830 | break; | ||
2831 | } | ||
2832 | if (suffixlen + prefixlen <= 12 && s[i] == '.') { | ||
2833 | tmp = in_aton(s); | ||
2834 | memcpy((struct in_addr *)(suffix + suffixlen), &tmp, | ||
2835 | sizeof(tmp)); | ||
2836 | suffixlen += 4; | ||
2837 | len += strlen(s); | ||
2838 | break; | ||
2839 | } | ||
2840 | suffix[suffixlen++] = (u >> 8); | ||
2841 | suffix[suffixlen++] = (u & 255); | ||
2842 | s += i; | ||
2843 | len += i; | ||
2844 | if (prefixlen + suffixlen == 16) | ||
2845 | break; | ||
2846 | } | ||
2847 | for (i = 0; i < suffixlen; i++) | ||
2848 | ip[16 - suffixlen + i] = suffix[i]; | ||
2849 | return len; | ||
2850 | } | ||
2851 | |||
2852 | static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | 2766 | static struct sk_buff *fill_packet_ipv6(struct net_device *odev, |
2853 | struct pktgen_dev *pkt_dev) | 2767 | struct pktgen_dev *pkt_dev) |
2854 | { | 2768 | { |
@@ -2927,7 +2841,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2927 | sizeof(struct ipv6hdr) - sizeof(struct udphdr) - | 2841 | sizeof(struct ipv6hdr) - sizeof(struct udphdr) - |
2928 | pkt_dev->pkt_overhead; | 2842 | pkt_dev->pkt_overhead; |
2929 | 2843 | ||
2930 | if (datalen < sizeof(struct pktgen_hdr)) { | 2844 | if (datalen < 0 || datalen < sizeof(struct pktgen_hdr)) { |
2931 | datalen = sizeof(struct pktgen_hdr); | 2845 | datalen = sizeof(struct pktgen_hdr); |
2932 | net_info_ratelimited("increased datalen to %d\n", datalen); | 2846 | net_info_ratelimited("increased datalen to %d\n", datalen); |
2933 | } | 2847 | } |
@@ -3548,8 +3462,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3548 | } | 3462 | } |
3549 | 3463 | ||
3550 | pkt_dev->removal_mark = 0; | 3464 | pkt_dev->removal_mark = 0; |
3551 | pkt_dev->min_pkt_size = ETH_ZLEN; | ||
3552 | pkt_dev->max_pkt_size = ETH_ZLEN; | ||
3553 | pkt_dev->nfrags = 0; | 3465 | pkt_dev->nfrags = 0; |
3554 | pkt_dev->delay = pg_delay_d; | 3466 | pkt_dev->delay = pg_delay_d; |
3555 | pkt_dev->count = pg_count_d; | 3467 | pkt_dev->count = pg_count_d; |
diff --git a/net/core/utils.c b/net/core/utils.c index f5613d569c23..e3487e461939 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -107,6 +107,18 @@ static inline int xdigit2bin(char c, int delim) | |||
107 | return IN6PTON_UNKNOWN; | 107 | return IN6PTON_UNKNOWN; |
108 | } | 108 | } |
109 | 109 | ||
110 | /** | ||
111 | * in4_pton - convert an IPv4 address from literal to binary representation | ||
112 | * @src: the start of the IPv4 address string | ||
113 | * @srclen: the length of the string, -1 means strlen(src) | ||
114 | * @dst: the binary (u8[4] array) representation of the IPv4 address | ||
115 | * @delim: the delimiter of the IPv4 address in @src, -1 means no delimiter | ||
116 | * @end: A pointer to the end of the parsed string will be placed here | ||
117 | * | ||
118 | * Return one on success, return zero when any error occurs | ||
119 | * and @end will point to the end of the parsed string. | ||
120 | * | ||
121 | */ | ||
110 | int in4_pton(const char *src, int srclen, | 122 | int in4_pton(const char *src, int srclen, |
111 | u8 *dst, | 123 | u8 *dst, |
112 | int delim, const char **end) | 124 | int delim, const char **end) |
@@ -161,6 +173,18 @@ out: | |||
161 | } | 173 | } |
162 | EXPORT_SYMBOL(in4_pton); | 174 | EXPORT_SYMBOL(in4_pton); |
163 | 175 | ||
176 | /** | ||
177 | * in6_pton - convert an IPv6 address from literal to binary representation | ||
178 | * @src: the start of the IPv6 address string | ||
179 | * @srclen: the length of the string, -1 means strlen(src) | ||
180 | * @dst: the binary (u8[16] array) representation of the IPv6 address | ||
181 | * @delim: the delimiter of the IPv6 address in @src, -1 means no delimiter | ||
182 | * @end: A pointer to the end of the parsed string will be placed here | ||
183 | * | ||
184 | * Return one on success, return zero when any error occurs | ||
185 | * and @end will point to the end of the parsed string. | ||
186 | * | ||
187 | */ | ||
164 | int in6_pton(const char *src, int srclen, | 188 | int in6_pton(const char *src, int srclen, |
165 | u8 *dst, | 189 | u8 *dst, |
166 | int delim, const char **end) | 190 | int delim, const char **end) |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 978bca4818ae..1831092f999f 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -374,7 +374,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
374 | 374 | ||
375 | memset(&fl4, 0, sizeof(fl4)); | 375 | memset(&fl4, 0, sizeof(fl4)); |
376 | flowi4_init_output(&fl4, tunnel->parms.link, | 376 | flowi4_init_output(&fl4, tunnel->parms.link, |
377 | htonl(tunnel->parms.i_key), RT_TOS(tos), | 377 | be32_to_cpu(tunnel->parms.i_key), RT_TOS(tos), |
378 | RT_SCOPE_UNIVERSE, | 378 | RT_SCOPE_UNIVERSE, |
379 | IPPROTO_IPIP, 0, | 379 | IPPROTO_IPIP, 0, |
380 | dst, tiph->saddr, 0, 0); | 380 | dst, tiph->saddr, 0, 0); |
@@ -441,7 +441,7 @@ static int vti_tunnel_bind_dev(struct net_device *dev) | |||
441 | struct flowi4 fl4; | 441 | struct flowi4 fl4; |
442 | memset(&fl4, 0, sizeof(fl4)); | 442 | memset(&fl4, 0, sizeof(fl4)); |
443 | flowi4_init_output(&fl4, tunnel->parms.link, | 443 | flowi4_init_output(&fl4, tunnel->parms.link, |
444 | htonl(tunnel->parms.i_key), | 444 | be32_to_cpu(tunnel->parms.i_key), |
445 | RT_TOS(iph->tos), RT_SCOPE_UNIVERSE, | 445 | RT_TOS(iph->tos), RT_SCOPE_UNIVERSE, |
446 | IPPROTO_IPIP, 0, | 446 | IPPROTO_IPIP, 0, |
447 | iph->daddr, iph->saddr, 0, 0); | 447 | iph->daddr, iph->saddr, 0, 0); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1a0da8dc8180..432f4bb77238 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2220,7 +2220,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, | |||
2220 | goto nla_put_failure; | 2220 | goto nla_put_failure; |
2221 | 2221 | ||
2222 | if (fl4->flowi4_mark && | 2222 | if (fl4->flowi4_mark && |
2223 | nla_put_be32(skb, RTA_MARK, fl4->flowi4_mark)) | 2223 | nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark)) |
2224 | goto nla_put_failure; | 2224 | goto nla_put_failure; |
2225 | 2225 | ||
2226 | error = rt->dst.error; | 2226 | error = rt->dst.error; |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 9205e492dc9d..63d4eccc674d 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -248,6 +248,8 @@ int proc_tcp_fastopen_key(ctl_table *ctl, int write, void __user *buffer, | |||
248 | ctxt = rcu_dereference(tcp_fastopen_ctx); | 248 | ctxt = rcu_dereference(tcp_fastopen_ctx); |
249 | if (ctxt) | 249 | if (ctxt) |
250 | memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); | 250 | memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); |
251 | else | ||
252 | memset(user_key, 0, sizeof(user_key)); | ||
251 | rcu_read_unlock(); | 253 | rcu_read_unlock(); |
252 | 254 | ||
253 | snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x", | 255 | snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x", |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 75735c9a6a9d..ef998b008a57 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -708,10 +708,11 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
708 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 708 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
709 | arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; | 709 | arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; |
710 | /* When socket is gone, all binding information is lost. | 710 | /* When socket is gone, all binding information is lost. |
711 | * routing might fail in this case. using iif for oif to | 711 | * routing might fail in this case. No choice here, if we choose to force |
712 | * make sure we can deliver it | 712 | * input interface, we will misroute in case of asymmetric route. |
713 | */ | 713 | */ |
714 | arg.bound_dev_if = sk ? sk->sk_bound_dev_if : inet_iif(skb); | 714 | if (sk) |
715 | arg.bound_dev_if = sk->sk_bound_dev_if; | ||
715 | 716 | ||
716 | net = dev_net(skb_dst(skb)->dev); | 717 | net = dev_net(skb_dst(skb)->dev); |
717 | arg.tos = ip_hdr(skb)->tos; | 718 | arg.tos = ip_hdr(skb)->tos; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 49c890386ce9..26175bffbaa0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -877,7 +877,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
877 | __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr); | 877 | __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr); |
878 | 878 | ||
879 | fl6.flowi6_proto = IPPROTO_TCP; | 879 | fl6.flowi6_proto = IPPROTO_TCP; |
880 | fl6.flowi6_oif = inet6_iif(skb); | 880 | if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL) |
881 | fl6.flowi6_oif = inet6_iif(skb); | ||
881 | fl6.fl6_dport = t1->dest; | 882 | fl6.fl6_dport = t1->dest; |
882 | fl6.fl6_sport = t1->source; | 883 | fl6.fl6_sport = t1->source; |
883 | security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); | 884 | security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); |
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index accfa00ffcdf..a16b7b4b1e02 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c | |||
@@ -56,7 +56,6 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | |||
56 | u64 tsfdelta; | 56 | u64 tsfdelta; |
57 | 57 | ||
58 | spin_lock_bh(&ifmsh->sync_offset_lock); | 58 | spin_lock_bh(&ifmsh->sync_offset_lock); |
59 | |||
60 | if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { | 59 | if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { |
61 | msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n", | 60 | msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n", |
62 | (long long) ifmsh->sync_offset_clockdrift_max); | 61 | (long long) ifmsh->sync_offset_clockdrift_max); |
@@ -69,11 +68,11 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | |||
69 | tsfdelta = -beacon_int_fraction; | 68 | tsfdelta = -beacon_int_fraction; |
70 | ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction; | 69 | ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction; |
71 | } | 70 | } |
71 | spin_unlock_bh(&ifmsh->sync_offset_lock); | ||
72 | 72 | ||
73 | tsf = drv_get_tsf(local, sdata); | 73 | tsf = drv_get_tsf(local, sdata); |
74 | if (tsf != -1ULL) | 74 | if (tsf != -1ULL) |
75 | drv_set_tsf(local, sdata, tsf + tsfdelta); | 75 | drv_set_tsf(local, sdata, tsf + tsfdelta); |
76 | spin_unlock_bh(&ifmsh->sync_offset_lock); | ||
77 | } | 76 | } |
78 | 77 | ||
79 | static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | 78 | static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 2ce89732d0f2..3af0cc4130f1 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -34,7 +34,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | |||
34 | skb_queue_len(&local->skb_queue_unreliable); | 34 | skb_queue_len(&local->skb_queue_unreliable); |
35 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | 35 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
36 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 36 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
37 | dev_kfree_skb_irq(skb); | 37 | ieee80211_free_txskb(hw, skb); |
38 | tmp--; | 38 | tmp--; |
39 | I802_DEBUG_INC(local->tx_status_drop); | 39 | I802_DEBUG_INC(local->tx_status_drop); |
40 | } | 40 | } |
@@ -159,7 +159,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
159 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", | 159 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", |
160 | skb_queue_len(&sta->tx_filtered[ac]), | 160 | skb_queue_len(&sta->tx_filtered[ac]), |
161 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); | 161 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); |
162 | dev_kfree_skb(skb); | 162 | ieee80211_free_txskb(&local->hw, skb); |
163 | } | 163 | } |
164 | 164 | ||
165 | static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) | 165 | static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e0e0d1d0e830..c9bf83f36657 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -354,7 +354,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
354 | total += skb_queue_len(&sta->ps_tx_buf[ac]); | 354 | total += skb_queue_len(&sta->ps_tx_buf[ac]); |
355 | if (skb) { | 355 | if (skb) { |
356 | purged++; | 356 | purged++; |
357 | dev_kfree_skb(skb); | 357 | ieee80211_free_txskb(&local->hw, skb); |
358 | break; | 358 | break; |
359 | } | 359 | } |
360 | } | 360 | } |
@@ -466,7 +466,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
466 | ps_dbg(tx->sdata, | 466 | ps_dbg(tx->sdata, |
467 | "STA %pM TX buffer for AC %d full - dropping oldest frame\n", | 467 | "STA %pM TX buffer for AC %d full - dropping oldest frame\n", |
468 | sta->sta.addr, ac); | 468 | sta->sta.addr, ac); |
469 | dev_kfree_skb(old); | 469 | ieee80211_free_txskb(&local->hw, old); |
470 | } else | 470 | } else |
471 | tx->local->total_ps_buffered++; | 471 | tx->local->total_ps_buffered++; |
472 | 472 | ||
@@ -1103,7 +1103,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1103 | spin_unlock(&tx->sta->lock); | 1103 | spin_unlock(&tx->sta->lock); |
1104 | 1104 | ||
1105 | if (purge_skb) | 1105 | if (purge_skb) |
1106 | dev_kfree_skb(purge_skb); | 1106 | ieee80211_free_txskb(&tx->local->hw, purge_skb); |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | /* reset session timer */ | 1109 | /* reset session timer */ |
@@ -1214,7 +1214,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, | |||
1214 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1214 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1215 | if (WARN_ON_ONCE(q >= local->hw.queues)) { | 1215 | if (WARN_ON_ONCE(q >= local->hw.queues)) { |
1216 | __skb_unlink(skb, skbs); | 1216 | __skb_unlink(skb, skbs); |
1217 | dev_kfree_skb(skb); | 1217 | ieee80211_free_txskb(&local->hw, skb); |
1218 | continue; | 1218 | continue; |
1219 | } | 1219 | } |
1220 | #endif | 1220 | #endif |
@@ -1356,7 +1356,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1356 | if (unlikely(res == TX_DROP)) { | 1356 | if (unlikely(res == TX_DROP)) { |
1357 | I802_DEBUG_INC(tx->local->tx_handlers_drop); | 1357 | I802_DEBUG_INC(tx->local->tx_handlers_drop); |
1358 | if (tx->skb) | 1358 | if (tx->skb) |
1359 | dev_kfree_skb(tx->skb); | 1359 | ieee80211_free_txskb(&tx->local->hw, tx->skb); |
1360 | else | 1360 | else |
1361 | __skb_queue_purge(&tx->skbs); | 1361 | __skb_queue_purge(&tx->skbs); |
1362 | return -1; | 1362 | return -1; |
@@ -1393,7 +1393,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1393 | res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); | 1393 | res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); |
1394 | 1394 | ||
1395 | if (unlikely(res_prepare == TX_DROP)) { | 1395 | if (unlikely(res_prepare == TX_DROP)) { |
1396 | dev_kfree_skb(skb); | 1396 | ieee80211_free_txskb(&local->hw, skb); |
1397 | goto out; | 1397 | goto out; |
1398 | } else if (unlikely(res_prepare == TX_QUEUED)) { | 1398 | } else if (unlikely(res_prepare == TX_QUEUED)) { |
1399 | goto out; | 1399 | goto out; |
@@ -1465,7 +1465,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
1465 | headroom = max_t(int, 0, headroom); | 1465 | headroom = max_t(int, 0, headroom); |
1466 | 1466 | ||
1467 | if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { | 1467 | if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { |
1468 | dev_kfree_skb(skb); | 1468 | ieee80211_free_txskb(&local->hw, skb); |
1469 | rcu_read_unlock(); | 1469 | rcu_read_unlock(); |
1470 | return; | 1470 | return; |
1471 | } | 1471 | } |
@@ -2050,8 +2050,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2050 | head_need += IEEE80211_ENCRYPT_HEADROOM; | 2050 | head_need += IEEE80211_ENCRYPT_HEADROOM; |
2051 | head_need += local->tx_headroom; | 2051 | head_need += local->tx_headroom; |
2052 | head_need = max_t(int, 0, head_need); | 2052 | head_need = max_t(int, 0, head_need); |
2053 | if (ieee80211_skb_resize(sdata, skb, head_need, true)) | 2053 | if (ieee80211_skb_resize(sdata, skb, head_need, true)) { |
2054 | goto fail; | 2054 | ieee80211_free_txskb(&local->hw, skb); |
2055 | return NETDEV_TX_OK; | ||
2056 | } | ||
2055 | } | 2057 | } |
2056 | 2058 | ||
2057 | if (encaps_data) { | 2059 | if (encaps_data) { |
@@ -2184,7 +2186,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
2184 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 2186 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2185 | 2187 | ||
2186 | if (WARN_ON(!info->control.vif)) { | 2188 | if (WARN_ON(!info->control.vif)) { |
2187 | kfree_skb(skb); | 2189 | ieee80211_free_txskb(&local->hw, skb); |
2188 | continue; | 2190 | continue; |
2189 | } | 2191 | } |
2190 | 2192 | ||
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index bac973a31367..194d865fae72 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -208,6 +208,35 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
208 | return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags); | 208 | return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags); |
209 | } | 209 | } |
210 | 210 | ||
211 | /* | ||
212 | * svc_xprt_received conditionally queues the transport for processing | ||
213 | * by another thread. The caller must hold the XPT_BUSY bit and must | ||
214 | * not thereafter touch transport data. | ||
215 | * | ||
216 | * Note: XPT_DATA only gets cleared when a read-attempt finds no (or | ||
217 | * insufficient) data. | ||
218 | */ | ||
219 | static void svc_xprt_received(struct svc_xprt *xprt) | ||
220 | { | ||
221 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | ||
222 | /* As soon as we clear busy, the xprt could be closed and | ||
223 | * 'put', so we need a reference to call svc_xprt_enqueue with: | ||
224 | */ | ||
225 | svc_xprt_get(xprt); | ||
226 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
227 | svc_xprt_enqueue(xprt); | ||
228 | svc_xprt_put(xprt); | ||
229 | } | ||
230 | |||
231 | void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new) | ||
232 | { | ||
233 | clear_bit(XPT_TEMP, &new->xpt_flags); | ||
234 | spin_lock_bh(&serv->sv_lock); | ||
235 | list_add(&new->xpt_list, &serv->sv_permsocks); | ||
236 | spin_unlock_bh(&serv->sv_lock); | ||
237 | svc_xprt_received(new); | ||
238 | } | ||
239 | |||
211 | int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | 240 | int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, |
212 | struct net *net, const int family, | 241 | struct net *net, const int family, |
213 | const unsigned short port, int flags) | 242 | const unsigned short port, int flags) |
@@ -232,13 +261,8 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
232 | module_put(xcl->xcl_owner); | 261 | module_put(xcl->xcl_owner); |
233 | return PTR_ERR(newxprt); | 262 | return PTR_ERR(newxprt); |
234 | } | 263 | } |
235 | 264 | svc_add_new_perm_xprt(serv, newxprt); | |
236 | clear_bit(XPT_TEMP, &newxprt->xpt_flags); | ||
237 | spin_lock_bh(&serv->sv_lock); | ||
238 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); | ||
239 | spin_unlock_bh(&serv->sv_lock); | ||
240 | newport = svc_xprt_local_port(newxprt); | 265 | newport = svc_xprt_local_port(newxprt); |
241 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); | ||
242 | return newport; | 266 | return newport; |
243 | } | 267 | } |
244 | err: | 268 | err: |
@@ -394,27 +418,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | |||
394 | return xprt; | 418 | return xprt; |
395 | } | 419 | } |
396 | 420 | ||
397 | /* | ||
398 | * svc_xprt_received conditionally queues the transport for processing | ||
399 | * by another thread. The caller must hold the XPT_BUSY bit and must | ||
400 | * not thereafter touch transport data. | ||
401 | * | ||
402 | * Note: XPT_DATA only gets cleared when a read-attempt finds no (or | ||
403 | * insufficient) data. | ||
404 | */ | ||
405 | void svc_xprt_received(struct svc_xprt *xprt) | ||
406 | { | ||
407 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | ||
408 | /* As soon as we clear busy, the xprt could be closed and | ||
409 | * 'put', so we need a reference to call svc_xprt_enqueue with: | ||
410 | */ | ||
411 | svc_xprt_get(xprt); | ||
412 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
413 | svc_xprt_enqueue(xprt); | ||
414 | svc_xprt_put(xprt); | ||
415 | } | ||
416 | EXPORT_SYMBOL_GPL(svc_xprt_received); | ||
417 | |||
418 | /** | 421 | /** |
419 | * svc_reserve - change the space reserved for the reply to a request. | 422 | * svc_reserve - change the space reserved for the reply to a request. |
420 | * @rqstp: The request in question | 423 | * @rqstp: The request in question |
@@ -565,33 +568,12 @@ static void svc_check_conn_limits(struct svc_serv *serv) | |||
565 | } | 568 | } |
566 | } | 569 | } |
567 | 570 | ||
568 | /* | 571 | int svc_alloc_arg(struct svc_rqst *rqstp) |
569 | * Receive the next request on any transport. This code is carefully | ||
570 | * organised not to touch any cachelines in the shared svc_serv | ||
571 | * structure, only cachelines in the local svc_pool. | ||
572 | */ | ||
573 | int svc_recv(struct svc_rqst *rqstp, long timeout) | ||
574 | { | 572 | { |
575 | struct svc_xprt *xprt = NULL; | 573 | struct svc_serv *serv = rqstp->rq_server; |
576 | struct svc_serv *serv = rqstp->rq_server; | 574 | struct xdr_buf *arg; |
577 | struct svc_pool *pool = rqstp->rq_pool; | 575 | int pages; |
578 | int len, i; | 576 | int i; |
579 | int pages; | ||
580 | struct xdr_buf *arg; | ||
581 | DECLARE_WAITQUEUE(wait, current); | ||
582 | long time_left; | ||
583 | |||
584 | dprintk("svc: server %p waiting for data (to = %ld)\n", | ||
585 | rqstp, timeout); | ||
586 | |||
587 | if (rqstp->rq_xprt) | ||
588 | printk(KERN_ERR | ||
589 | "svc_recv: service %p, transport not NULL!\n", | ||
590 | rqstp); | ||
591 | if (waitqueue_active(&rqstp->rq_wait)) | ||
592 | printk(KERN_ERR | ||
593 | "svc_recv: service %p, wait queue active!\n", | ||
594 | rqstp); | ||
595 | 577 | ||
596 | /* now allocate needed pages. If we get a failure, sleep briefly */ | 578 | /* now allocate needed pages. If we get a failure, sleep briefly */ |
597 | pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; | 579 | pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; |
@@ -621,11 +603,15 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
621 | arg->page_len = (pages-2)*PAGE_SIZE; | 603 | arg->page_len = (pages-2)*PAGE_SIZE; |
622 | arg->len = (pages-1)*PAGE_SIZE; | 604 | arg->len = (pages-1)*PAGE_SIZE; |
623 | arg->tail[0].iov_len = 0; | 605 | arg->tail[0].iov_len = 0; |
606 | return 0; | ||
607 | } | ||
624 | 608 | ||
625 | try_to_freeze(); | 609 | struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) |
626 | cond_resched(); | 610 | { |
627 | if (signalled() || kthread_should_stop()) | 611 | struct svc_xprt *xprt; |
628 | return -EINTR; | 612 | struct svc_pool *pool = rqstp->rq_pool; |
613 | DECLARE_WAITQUEUE(wait, current); | ||
614 | long time_left; | ||
629 | 615 | ||
630 | /* Normally we will wait up to 5 seconds for any required | 616 | /* Normally we will wait up to 5 seconds for any required |
631 | * cache information to be provided. | 617 | * cache information to be provided. |
@@ -663,7 +649,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
663 | if (kthread_should_stop()) { | 649 | if (kthread_should_stop()) { |
664 | set_current_state(TASK_RUNNING); | 650 | set_current_state(TASK_RUNNING); |
665 | spin_unlock_bh(&pool->sp_lock); | 651 | spin_unlock_bh(&pool->sp_lock); |
666 | return -EINTR; | 652 | return ERR_PTR(-EINTR); |
667 | } | 653 | } |
668 | 654 | ||
669 | add_wait_queue(&rqstp->rq_wait, &wait); | 655 | add_wait_queue(&rqstp->rq_wait, &wait); |
@@ -684,48 +670,58 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
684 | spin_unlock_bh(&pool->sp_lock); | 670 | spin_unlock_bh(&pool->sp_lock); |
685 | dprintk("svc: server %p, no data yet\n", rqstp); | 671 | dprintk("svc: server %p, no data yet\n", rqstp); |
686 | if (signalled() || kthread_should_stop()) | 672 | if (signalled() || kthread_should_stop()) |
687 | return -EINTR; | 673 | return ERR_PTR(-EINTR); |
688 | else | 674 | else |
689 | return -EAGAIN; | 675 | return ERR_PTR(-EAGAIN); |
690 | } | 676 | } |
691 | } | 677 | } |
692 | spin_unlock_bh(&pool->sp_lock); | 678 | spin_unlock_bh(&pool->sp_lock); |
679 | return xprt; | ||
680 | } | ||
681 | |||
682 | void svc_add_new_temp_xprt(struct svc_serv *serv, struct svc_xprt *newxpt) | ||
683 | { | ||
684 | spin_lock_bh(&serv->sv_lock); | ||
685 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | ||
686 | list_add(&newxpt->xpt_list, &serv->sv_tempsocks); | ||
687 | serv->sv_tmpcnt++; | ||
688 | if (serv->sv_temptimer.function == NULL) { | ||
689 | /* setup timer to age temp transports */ | ||
690 | setup_timer(&serv->sv_temptimer, svc_age_temp_xprts, | ||
691 | (unsigned long)serv); | ||
692 | mod_timer(&serv->sv_temptimer, | ||
693 | jiffies + svc_conn_age_period * HZ); | ||
694 | } | ||
695 | spin_unlock_bh(&serv->sv_lock); | ||
696 | svc_xprt_received(newxpt); | ||
697 | } | ||
698 | |||
699 | static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) | ||
700 | { | ||
701 | struct svc_serv *serv = rqstp->rq_server; | ||
702 | int len = 0; | ||
693 | 703 | ||
694 | len = 0; | ||
695 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 704 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
696 | dprintk("svc_recv: found XPT_CLOSE\n"); | 705 | dprintk("svc_recv: found XPT_CLOSE\n"); |
697 | svc_delete_xprt(xprt); | 706 | svc_delete_xprt(xprt); |
698 | /* Leave XPT_BUSY set on the dead xprt: */ | 707 | /* Leave XPT_BUSY set on the dead xprt: */ |
699 | goto out; | 708 | return 0; |
700 | } | 709 | } |
701 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | 710 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { |
702 | struct svc_xprt *newxpt; | 711 | struct svc_xprt *newxpt; |
712 | /* | ||
713 | * We know this module_get will succeed because the | ||
714 | * listener holds a reference too | ||
715 | */ | ||
716 | __module_get(xprt->xpt_class->xcl_owner); | ||
717 | svc_check_conn_limits(xprt->xpt_server); | ||
703 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 718 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
704 | if (newxpt) { | 719 | if (newxpt) |
705 | /* | 720 | svc_add_new_temp_xprt(serv, newxpt); |
706 | * We know this module_get will succeed because the | ||
707 | * listener holds a reference too | ||
708 | */ | ||
709 | __module_get(newxpt->xpt_class->xcl_owner); | ||
710 | svc_check_conn_limits(xprt->xpt_server); | ||
711 | spin_lock_bh(&serv->sv_lock); | ||
712 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | ||
713 | list_add(&newxpt->xpt_list, &serv->sv_tempsocks); | ||
714 | serv->sv_tmpcnt++; | ||
715 | if (serv->sv_temptimer.function == NULL) { | ||
716 | /* setup timer to age temp transports */ | ||
717 | setup_timer(&serv->sv_temptimer, | ||
718 | svc_age_temp_xprts, | ||
719 | (unsigned long)serv); | ||
720 | mod_timer(&serv->sv_temptimer, | ||
721 | jiffies + svc_conn_age_period * HZ); | ||
722 | } | ||
723 | spin_unlock_bh(&serv->sv_lock); | ||
724 | svc_xprt_received(newxpt); | ||
725 | } | ||
726 | } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { | 721 | } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { |
722 | /* XPT_DATA|XPT_DEFERRED case: */ | ||
727 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 723 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
728 | rqstp, pool->sp_id, xprt, | 724 | rqstp, rqstp->rq_pool->sp_id, xprt, |
729 | atomic_read(&xprt->xpt_ref.refcount)); | 725 | atomic_read(&xprt->xpt_ref.refcount)); |
730 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | 726 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); |
731 | if (rqstp->rq_deferred) | 727 | if (rqstp->rq_deferred) |
@@ -736,10 +732,51 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
736 | rqstp->rq_reserved = serv->sv_max_mesg; | 732 | rqstp->rq_reserved = serv->sv_max_mesg; |
737 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | 733 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); |
738 | } | 734 | } |
735 | /* clear XPT_BUSY: */ | ||
739 | svc_xprt_received(xprt); | 736 | svc_xprt_received(xprt); |
737 | return len; | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * Receive the next request on any transport. This code is carefully | ||
742 | * organised not to touch any cachelines in the shared svc_serv | ||
743 | * structure, only cachelines in the local svc_pool. | ||
744 | */ | ||
745 | int svc_recv(struct svc_rqst *rqstp, long timeout) | ||
746 | { | ||
747 | struct svc_xprt *xprt = NULL; | ||
748 | struct svc_serv *serv = rqstp->rq_server; | ||
749 | int len, err; | ||
750 | |||
751 | dprintk("svc: server %p waiting for data (to = %ld)\n", | ||
752 | rqstp, timeout); | ||
753 | |||
754 | if (rqstp->rq_xprt) | ||
755 | printk(KERN_ERR | ||
756 | "svc_recv: service %p, transport not NULL!\n", | ||
757 | rqstp); | ||
758 | if (waitqueue_active(&rqstp->rq_wait)) | ||
759 | printk(KERN_ERR | ||
760 | "svc_recv: service %p, wait queue active!\n", | ||
761 | rqstp); | ||
762 | |||
763 | err = svc_alloc_arg(rqstp); | ||
764 | if (err) | ||
765 | return err; | ||
766 | |||
767 | try_to_freeze(); | ||
768 | cond_resched(); | ||
769 | if (signalled() || kthread_should_stop()) | ||
770 | return -EINTR; | ||
771 | |||
772 | xprt = svc_get_next_xprt(rqstp, timeout); | ||
773 | if (IS_ERR(xprt)) | ||
774 | return PTR_ERR(xprt); | ||
775 | |||
776 | len = svc_handle_xprt(rqstp, xprt); | ||
740 | 777 | ||
741 | /* No data, incomplete (TCP) read, or accept() */ | 778 | /* No data, incomplete (TCP) read, or accept() */ |
742 | if (len == 0 || len == -EAGAIN) | 779 | if (len <= 0) |
743 | goto out; | 780 | goto out; |
744 | 781 | ||
745 | clear_bit(XPT_OLD, &xprt->xpt_flags); | 782 | clear_bit(XPT_OLD, &xprt->xpt_flags); |
@@ -917,16 +954,18 @@ void svc_close_xprt(struct svc_xprt *xprt) | |||
917 | } | 954 | } |
918 | EXPORT_SYMBOL_GPL(svc_close_xprt); | 955 | EXPORT_SYMBOL_GPL(svc_close_xprt); |
919 | 956 | ||
920 | static void svc_close_list(struct list_head *xprt_list, struct net *net) | 957 | static void svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) |
921 | { | 958 | { |
922 | struct svc_xprt *xprt; | 959 | struct svc_xprt *xprt; |
923 | 960 | ||
961 | spin_lock(&serv->sv_lock); | ||
924 | list_for_each_entry(xprt, xprt_list, xpt_list) { | 962 | list_for_each_entry(xprt, xprt_list, xpt_list) { |
925 | if (xprt->xpt_net != net) | 963 | if (xprt->xpt_net != net) |
926 | continue; | 964 | continue; |
927 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | 965 | set_bit(XPT_CLOSE, &xprt->xpt_flags); |
928 | set_bit(XPT_BUSY, &xprt->xpt_flags); | 966 | set_bit(XPT_BUSY, &xprt->xpt_flags); |
929 | } | 967 | } |
968 | spin_unlock(&serv->sv_lock); | ||
930 | } | 969 | } |
931 | 970 | ||
932 | static void svc_clear_pools(struct svc_serv *serv, struct net *net) | 971 | static void svc_clear_pools(struct svc_serv *serv, struct net *net) |
@@ -949,24 +988,28 @@ static void svc_clear_pools(struct svc_serv *serv, struct net *net) | |||
949 | } | 988 | } |
950 | } | 989 | } |
951 | 990 | ||
952 | static void svc_clear_list(struct list_head *xprt_list, struct net *net) | 991 | static void svc_clear_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) |
953 | { | 992 | { |
954 | struct svc_xprt *xprt; | 993 | struct svc_xprt *xprt; |
955 | struct svc_xprt *tmp; | 994 | struct svc_xprt *tmp; |
995 | LIST_HEAD(victims); | ||
956 | 996 | ||
997 | spin_lock(&serv->sv_lock); | ||
957 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | 998 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { |
958 | if (xprt->xpt_net != net) | 999 | if (xprt->xpt_net != net) |
959 | continue; | 1000 | continue; |
960 | svc_delete_xprt(xprt); | 1001 | list_move(&xprt->xpt_list, &victims); |
961 | } | 1002 | } |
962 | list_for_each_entry(xprt, xprt_list, xpt_list) | 1003 | spin_unlock(&serv->sv_lock); |
963 | BUG_ON(xprt->xpt_net == net); | 1004 | |
1005 | list_for_each_entry_safe(xprt, tmp, &victims, xpt_list) | ||
1006 | svc_delete_xprt(xprt); | ||
964 | } | 1007 | } |
965 | 1008 | ||
966 | void svc_close_net(struct svc_serv *serv, struct net *net) | 1009 | void svc_close_net(struct svc_serv *serv, struct net *net) |
967 | { | 1010 | { |
968 | svc_close_list(&serv->sv_tempsocks, net); | 1011 | svc_close_list(serv, &serv->sv_tempsocks, net); |
969 | svc_close_list(&serv->sv_permsocks, net); | 1012 | svc_close_list(serv, &serv->sv_permsocks, net); |
970 | 1013 | ||
971 | svc_clear_pools(serv, net); | 1014 | svc_clear_pools(serv, net); |
972 | /* | 1015 | /* |
@@ -974,8 +1017,8 @@ void svc_close_net(struct svc_serv *serv, struct net *net) | |||
974 | * svc_xprt_enqueue will not add new entries without taking the | 1017 | * svc_xprt_enqueue will not add new entries without taking the |
975 | * sp_lock and checking XPT_BUSY. | 1018 | * sp_lock and checking XPT_BUSY. |
976 | */ | 1019 | */ |
977 | svc_clear_list(&serv->sv_tempsocks, net); | 1020 | svc_clear_list(serv, &serv->sv_tempsocks, net); |
978 | svc_clear_list(&serv->sv_permsocks, net); | 1021 | svc_clear_list(serv, &serv->sv_permsocks, net); |
979 | } | 1022 | } |
980 | 1023 | ||
981 | /* | 1024 | /* |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 998aa8c1807c..03827cef1fa7 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -59,7 +59,7 @@ | |||
59 | 59 | ||
60 | 60 | ||
61 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, | 61 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, |
62 | int *errp, int flags); | 62 | int flags); |
63 | static void svc_udp_data_ready(struct sock *, int); | 63 | static void svc_udp_data_ready(struct sock *, int); |
64 | static int svc_udp_recvfrom(struct svc_rqst *); | 64 | static int svc_udp_recvfrom(struct svc_rqst *); |
65 | static int svc_udp_sendto(struct svc_rqst *); | 65 | static int svc_udp_sendto(struct svc_rqst *); |
@@ -305,57 +305,6 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining) | |||
305 | return len; | 305 | return len; |
306 | } | 306 | } |
307 | 307 | ||
308 | /** | ||
309 | * svc_sock_names - construct a list of listener names in a string | ||
310 | * @serv: pointer to RPC service | ||
311 | * @buf: pointer to a buffer to fill in with socket names | ||
312 | * @buflen: size of the buffer to be filled | ||
313 | * @toclose: pointer to '\0'-terminated C string containing the name | ||
314 | * of a listener to be closed | ||
315 | * | ||
316 | * Fills in @buf with a '\n'-separated list of names of listener | ||
317 | * sockets. If @toclose is not NULL, the socket named by @toclose | ||
318 | * is closed, and is not included in the output list. | ||
319 | * | ||
320 | * Returns positive length of the socket name string, or a negative | ||
321 | * errno value on error. | ||
322 | */ | ||
323 | int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen, | ||
324 | const char *toclose) | ||
325 | { | ||
326 | struct svc_sock *svsk, *closesk = NULL; | ||
327 | int len = 0; | ||
328 | |||
329 | if (!serv) | ||
330 | return 0; | ||
331 | |||
332 | spin_lock_bh(&serv->sv_lock); | ||
333 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list) { | ||
334 | int onelen = svc_one_sock_name(svsk, buf + len, buflen - len); | ||
335 | if (onelen < 0) { | ||
336 | len = onelen; | ||
337 | break; | ||
338 | } | ||
339 | if (toclose && strcmp(toclose, buf + len) == 0) { | ||
340 | closesk = svsk; | ||
341 | svc_xprt_get(&closesk->sk_xprt); | ||
342 | } else | ||
343 | len += onelen; | ||
344 | } | ||
345 | spin_unlock_bh(&serv->sv_lock); | ||
346 | |||
347 | if (closesk) { | ||
348 | /* Should unregister with portmap, but you cannot | ||
349 | * unregister just one protocol... | ||
350 | */ | ||
351 | svc_close_xprt(&closesk->sk_xprt); | ||
352 | svc_xprt_put(&closesk->sk_xprt); | ||
353 | } else if (toclose) | ||
354 | return -ENOENT; | ||
355 | return len; | ||
356 | } | ||
357 | EXPORT_SYMBOL_GPL(svc_sock_names); | ||
358 | |||
359 | /* | 308 | /* |
360 | * Check input queue length | 309 | * Check input queue length |
361 | */ | 310 | */ |
@@ -598,11 +547,9 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
598 | dprintk("svc: recvfrom returned error %d\n", -err); | 547 | dprintk("svc: recvfrom returned error %d\n", -err); |
599 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 548 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
600 | } | 549 | } |
601 | return -EAGAIN; | 550 | return 0; |
602 | } | 551 | } |
603 | len = svc_addr_len(svc_addr(rqstp)); | 552 | len = svc_addr_len(svc_addr(rqstp)); |
604 | if (len == 0) | ||
605 | return -EAFNOSUPPORT; | ||
606 | rqstp->rq_addrlen = len; | 553 | rqstp->rq_addrlen = len; |
607 | if (skb->tstamp.tv64 == 0) { | 554 | if (skb->tstamp.tv64 == 0) { |
608 | skb->tstamp = ktime_get_real(); | 555 | skb->tstamp = ktime_get_real(); |
@@ -620,10 +567,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
620 | if (!svc_udp_get_dest_address(rqstp, cmh)) { | 567 | if (!svc_udp_get_dest_address(rqstp, cmh)) { |
621 | net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", | 568 | net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", |
622 | cmh->cmsg_level, cmh->cmsg_type); | 569 | cmh->cmsg_level, cmh->cmsg_type); |
623 | out_free: | 570 | goto out_free; |
624 | trace_kfree_skb(skb, svc_udp_recvfrom); | ||
625 | skb_free_datagram_locked(svsk->sk_sk, skb); | ||
626 | return 0; | ||
627 | } | 571 | } |
628 | rqstp->rq_daddrlen = svc_addr_len(svc_daddr(rqstp)); | 572 | rqstp->rq_daddrlen = svc_addr_len(svc_daddr(rqstp)); |
629 | 573 | ||
@@ -662,6 +606,10 @@ out_free: | |||
662 | serv->sv_stats->netudpcnt++; | 606 | serv->sv_stats->netudpcnt++; |
663 | 607 | ||
664 | return len; | 608 | return len; |
609 | out_free: | ||
610 | trace_kfree_skb(skb, svc_udp_recvfrom); | ||
611 | skb_free_datagram_locked(svsk->sk_sk, skb); | ||
612 | return 0; | ||
665 | } | 613 | } |
666 | 614 | ||
667 | static int | 615 | static int |
@@ -900,8 +848,9 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) | |||
900 | */ | 848 | */ |
901 | newsock->sk->sk_sndtimeo = HZ*30; | 849 | newsock->sk->sk_sndtimeo = HZ*30; |
902 | 850 | ||
903 | if (!(newsvsk = svc_setup_socket(serv, newsock, &err, | 851 | newsvsk = svc_setup_socket(serv, newsock, |
904 | (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY)))) | 852 | (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY)); |
853 | if (IS_ERR(newsvsk)) | ||
905 | goto failed; | 854 | goto failed; |
906 | svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen); | 855 | svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen); |
907 | err = kernel_getsockname(newsock, sin, &slen); | 856 | err = kernel_getsockname(newsock, sin, &slen); |
@@ -1174,13 +1123,13 @@ error: | |||
1174 | if (len != -EAGAIN) | 1123 | if (len != -EAGAIN) |
1175 | goto err_other; | 1124 | goto err_other; |
1176 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); | 1125 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); |
1177 | return -EAGAIN; | 1126 | return 0; |
1178 | err_other: | 1127 | err_other: |
1179 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", | 1128 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", |
1180 | svsk->sk_xprt.xpt_server->sv_name, -len); | 1129 | svsk->sk_xprt.xpt_server->sv_name, -len); |
1181 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 1130 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
1182 | err_noclose: | 1131 | err_noclose: |
1183 | return -EAGAIN; /* record not complete */ | 1132 | return 0; /* record not complete */ |
1184 | } | 1133 | } |
1185 | 1134 | ||
1186 | /* | 1135 | /* |
@@ -1383,29 +1332,29 @@ EXPORT_SYMBOL_GPL(svc_sock_update_bufs); | |||
1383 | */ | 1332 | */ |
1384 | static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | 1333 | static struct svc_sock *svc_setup_socket(struct svc_serv *serv, |
1385 | struct socket *sock, | 1334 | struct socket *sock, |
1386 | int *errp, int flags) | 1335 | int flags) |
1387 | { | 1336 | { |
1388 | struct svc_sock *svsk; | 1337 | struct svc_sock *svsk; |
1389 | struct sock *inet; | 1338 | struct sock *inet; |
1390 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); | 1339 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); |
1340 | int err = 0; | ||
1391 | 1341 | ||
1392 | dprintk("svc: svc_setup_socket %p\n", sock); | 1342 | dprintk("svc: svc_setup_socket %p\n", sock); |
1393 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { | 1343 | svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); |
1394 | *errp = -ENOMEM; | 1344 | if (!svsk) |
1395 | return NULL; | 1345 | return ERR_PTR(-ENOMEM); |
1396 | } | ||
1397 | 1346 | ||
1398 | inet = sock->sk; | 1347 | inet = sock->sk; |
1399 | 1348 | ||
1400 | /* Register socket with portmapper */ | 1349 | /* Register socket with portmapper */ |
1401 | if (*errp >= 0 && pmap_register) | 1350 | if (pmap_register) |
1402 | *errp = svc_register(serv, sock_net(sock->sk), inet->sk_family, | 1351 | err = svc_register(serv, sock_net(sock->sk), inet->sk_family, |
1403 | inet->sk_protocol, | 1352 | inet->sk_protocol, |
1404 | ntohs(inet_sk(inet)->inet_sport)); | 1353 | ntohs(inet_sk(inet)->inet_sport)); |
1405 | 1354 | ||
1406 | if (*errp < 0) { | 1355 | if (err < 0) { |
1407 | kfree(svsk); | 1356 | kfree(svsk); |
1408 | return NULL; | 1357 | return ERR_PTR(err); |
1409 | } | 1358 | } |
1410 | 1359 | ||
1411 | inet->sk_user_data = svsk; | 1360 | inet->sk_user_data = svsk; |
@@ -1450,42 +1399,38 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, | |||
1450 | int err = 0; | 1399 | int err = 0; |
1451 | struct socket *so = sockfd_lookup(fd, &err); | 1400 | struct socket *so = sockfd_lookup(fd, &err); |
1452 | struct svc_sock *svsk = NULL; | 1401 | struct svc_sock *svsk = NULL; |
1402 | struct sockaddr_storage addr; | ||
1403 | struct sockaddr *sin = (struct sockaddr *)&addr; | ||
1404 | int salen; | ||
1453 | 1405 | ||
1454 | if (!so) | 1406 | if (!so) |
1455 | return err; | 1407 | return err; |
1408 | err = -EAFNOSUPPORT; | ||
1456 | if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6)) | 1409 | if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6)) |
1457 | err = -EAFNOSUPPORT; | 1410 | goto out; |
1458 | else if (so->sk->sk_protocol != IPPROTO_TCP && | 1411 | err = -EPROTONOSUPPORT; |
1412 | if (so->sk->sk_protocol != IPPROTO_TCP && | ||
1459 | so->sk->sk_protocol != IPPROTO_UDP) | 1413 | so->sk->sk_protocol != IPPROTO_UDP) |
1460 | err = -EPROTONOSUPPORT; | 1414 | goto out; |
1461 | else if (so->state > SS_UNCONNECTED) | 1415 | err = -EISCONN; |
1462 | err = -EISCONN; | 1416 | if (so->state > SS_UNCONNECTED) |
1463 | else { | 1417 | goto out; |
1464 | if (!try_module_get(THIS_MODULE)) | 1418 | err = -ENOENT; |
1465 | err = -ENOENT; | 1419 | if (!try_module_get(THIS_MODULE)) |
1466 | else | 1420 | goto out; |
1467 | svsk = svc_setup_socket(serv, so, &err, | 1421 | svsk = svc_setup_socket(serv, so, SVC_SOCK_DEFAULTS); |
1468 | SVC_SOCK_DEFAULTS); | 1422 | if (IS_ERR(svsk)) { |
1469 | if (svsk) { | 1423 | module_put(THIS_MODULE); |
1470 | struct sockaddr_storage addr; | 1424 | err = PTR_ERR(svsk); |
1471 | struct sockaddr *sin = (struct sockaddr *)&addr; | 1425 | goto out; |
1472 | int salen; | ||
1473 | if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) | ||
1474 | svc_xprt_set_local(&svsk->sk_xprt, sin, salen); | ||
1475 | clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); | ||
1476 | spin_lock_bh(&serv->sv_lock); | ||
1477 | list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks); | ||
1478 | spin_unlock_bh(&serv->sv_lock); | ||
1479 | svc_xprt_received(&svsk->sk_xprt); | ||
1480 | err = 0; | ||
1481 | } else | ||
1482 | module_put(THIS_MODULE); | ||
1483 | } | ||
1484 | if (err) { | ||
1485 | sockfd_put(so); | ||
1486 | return err; | ||
1487 | } | 1426 | } |
1427 | if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) | ||
1428 | svc_xprt_set_local(&svsk->sk_xprt, sin, salen); | ||
1429 | svc_add_new_perm_xprt(serv, &svsk->sk_xprt); | ||
1488 | return svc_one_sock_name(svsk, name_return, len); | 1430 | return svc_one_sock_name(svsk, name_return, len); |
1431 | out: | ||
1432 | sockfd_put(so); | ||
1433 | return err; | ||
1489 | } | 1434 | } |
1490 | EXPORT_SYMBOL_GPL(svc_addsock); | 1435 | EXPORT_SYMBOL_GPL(svc_addsock); |
1491 | 1436 | ||
@@ -1563,11 +1508,13 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, | |||
1563 | goto bummer; | 1508 | goto bummer; |
1564 | } | 1509 | } |
1565 | 1510 | ||
1566 | if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { | 1511 | svsk = svc_setup_socket(serv, sock, flags); |
1567 | svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen); | 1512 | if (IS_ERR(svsk)) { |
1568 | return (struct svc_xprt *)svsk; | 1513 | error = PTR_ERR(svsk); |
1514 | goto bummer; | ||
1569 | } | 1515 | } |
1570 | 1516 | svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen); | |
1517 | return (struct svc_xprt *)svsk; | ||
1571 | bummer: | 1518 | bummer: |
1572 | dprintk("svc: svc_create_socket error = %d\n", -error); | 1519 | dprintk("svc: svc_create_socket error = %d\n", -error); |
1573 | sock_release(sock); | 1520 | sock_release(sock); |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 73b428bef598..62e4f9bcc387 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -578,10 +578,6 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird) | |||
578 | list_add_tail(&newxprt->sc_accept_q, &listen_xprt->sc_accept_q); | 578 | list_add_tail(&newxprt->sc_accept_q, &listen_xprt->sc_accept_q); |
579 | spin_unlock_bh(&listen_xprt->sc_lock); | 579 | spin_unlock_bh(&listen_xprt->sc_lock); |
580 | 580 | ||
581 | /* | ||
582 | * Can't use svc_xprt_received here because we are not on a | ||
583 | * rqstp thread | ||
584 | */ | ||
585 | set_bit(XPT_CONN, &listen_xprt->sc_xprt.xpt_flags); | 581 | set_bit(XPT_CONN, &listen_xprt->sc_xprt.xpt_flags); |
586 | svc_xprt_enqueue(&listen_xprt->sc_xprt); | 582 | svc_xprt_enqueue(&listen_xprt->sc_xprt); |
587 | } | 583 | } |