diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/9p/client.c | 18 | ||||
| -rw-r--r-- | net/9p/trans_fd.c | 38 | ||||
| -rw-r--r-- | net/bluetooth/af_bluetooth.c | 2 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 3 | ||||
| -rw-r--r-- | net/ceph/crypto.c | 9 | ||||
| -rw-r--r-- | net/core/pktgen.c | 146 | ||||
| -rw-r--r-- | net/core/utils.c | 24 | ||||
| -rw-r--r-- | net/dns_resolver/dns_key.c | 6 | ||||
| -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/rxrpc/ar-key.c | 40 | ||||
| -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 |
20 files changed, 337 insertions, 390 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 8260f132b32e..34d417670935 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -76,6 +76,20 @@ inline int p9_is_proto_dotu(struct p9_client *clnt) | |||
| 76 | } | 76 | } |
| 77 | EXPORT_SYMBOL(p9_is_proto_dotu); | 77 | EXPORT_SYMBOL(p9_is_proto_dotu); |
| 78 | 78 | ||
| 79 | /* | ||
| 80 | * Some error codes are taken directly from the server replies, | ||
| 81 | * make sure they are valid. | ||
| 82 | */ | ||
| 83 | static int safe_errno(int err) | ||
| 84 | { | ||
| 85 | if ((err > 0) || (err < -MAX_ERRNO)) { | ||
| 86 | p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err); | ||
| 87 | return -EPROTO; | ||
| 88 | } | ||
| 89 | return err; | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 79 | /* Interpret mount option for protocol version */ | 93 | /* Interpret mount option for protocol version */ |
| 80 | static int get_protocol_version(char *s) | 94 | static int get_protocol_version(char *s) |
| 81 | { | 95 | { |
| @@ -782,7 +796,7 @@ again: | |||
| 782 | return req; | 796 | return req; |
| 783 | reterr: | 797 | reterr: |
| 784 | p9_free_req(c, req); | 798 | p9_free_req(c, req); |
| 785 | return ERR_PTR(err); | 799 | return ERR_PTR(safe_errno(err)); |
| 786 | } | 800 | } |
| 787 | 801 | ||
| 788 | /** | 802 | /** |
| @@ -865,7 +879,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, | |||
| 865 | return req; | 879 | return req; |
| 866 | reterr: | 880 | reterr: |
| 867 | p9_free_req(c, req); | 881 | p9_free_req(c, req); |
| 868 | return ERR_PTR(err); | 882 | return ERR_PTR(safe_errno(err)); |
| 869 | } | 883 | } |
| 870 | 884 | ||
| 871 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | 885 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 15656b8573f3..02efb25c2957 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
| @@ -316,8 +316,7 @@ static void p9_read_work(struct work_struct *work) | |||
| 316 | m->rsize - m->rpos); | 316 | m->rsize - m->rpos); |
| 317 | p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err); | 317 | p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err); |
| 318 | if (err == -EAGAIN) { | 318 | if (err == -EAGAIN) { |
| 319 | clear_bit(Rworksched, &m->wsched); | 319 | goto end_clear; |
| 320 | return; | ||
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | if (err <= 0) | 322 | if (err <= 0) |
| @@ -379,19 +378,20 @@ static void p9_read_work(struct work_struct *work) | |||
| 379 | m->req = NULL; | 378 | m->req = NULL; |
| 380 | } | 379 | } |
| 381 | 380 | ||
| 381 | end_clear: | ||
| 382 | clear_bit(Rworksched, &m->wsched); | ||
| 383 | |||
| 382 | if (!list_empty(&m->req_list)) { | 384 | if (!list_empty(&m->req_list)) { |
| 383 | if (test_and_clear_bit(Rpending, &m->wsched)) | 385 | if (test_and_clear_bit(Rpending, &m->wsched)) |
| 384 | n = POLLIN; | 386 | n = POLLIN; |
| 385 | else | 387 | else |
| 386 | n = p9_fd_poll(m->client, NULL); | 388 | n = p9_fd_poll(m->client, NULL); |
| 387 | 389 | ||
| 388 | if (n & POLLIN) { | 390 | if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) { |
| 389 | p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m); | 391 | p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m); |
| 390 | schedule_work(&m->rq); | 392 | schedule_work(&m->rq); |
| 391 | } else | 393 | } |
| 392 | clear_bit(Rworksched, &m->wsched); | 394 | } |
| 393 | } else | ||
| 394 | clear_bit(Rworksched, &m->wsched); | ||
| 395 | 395 | ||
| 396 | return; | 396 | return; |
| 397 | error: | 397 | error: |
| @@ -453,12 +453,13 @@ static void p9_write_work(struct work_struct *work) | |||
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | if (!m->wsize) { | 455 | if (!m->wsize) { |
| 456 | spin_lock(&m->client->lock); | ||
| 456 | if (list_empty(&m->unsent_req_list)) { | 457 | if (list_empty(&m->unsent_req_list)) { |
| 457 | clear_bit(Wworksched, &m->wsched); | 458 | clear_bit(Wworksched, &m->wsched); |
| 459 | spin_unlock(&m->client->lock); | ||
| 458 | return; | 460 | return; |
| 459 | } | 461 | } |
| 460 | 462 | ||
| 461 | spin_lock(&m->client->lock); | ||
| 462 | req = list_entry(m->unsent_req_list.next, struct p9_req_t, | 463 | req = list_entry(m->unsent_req_list.next, struct p9_req_t, |
| 463 | req_list); | 464 | req_list); |
| 464 | req->status = REQ_STATUS_SENT; | 465 | req->status = REQ_STATUS_SENT; |
| @@ -476,10 +477,9 @@ static void p9_write_work(struct work_struct *work) | |||
| 476 | clear_bit(Wpending, &m->wsched); | 477 | clear_bit(Wpending, &m->wsched); |
| 477 | err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos); | 478 | err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos); |
| 478 | p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err); | 479 | p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err); |
| 479 | if (err == -EAGAIN) { | 480 | if (err == -EAGAIN) |
| 480 | clear_bit(Wworksched, &m->wsched); | 481 | goto end_clear; |
| 481 | return; | 482 | |
| 482 | } | ||
| 483 | 483 | ||
| 484 | if (err < 0) | 484 | if (err < 0) |
| 485 | goto error; | 485 | goto error; |
| @@ -492,19 +492,21 @@ static void p9_write_work(struct work_struct *work) | |||
| 492 | if (m->wpos == m->wsize) | 492 | if (m->wpos == m->wsize) |
| 493 | m->wpos = m->wsize = 0; | 493 | m->wpos = m->wsize = 0; |
| 494 | 494 | ||
| 495 | if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) { | 495 | end_clear: |
| 496 | clear_bit(Wworksched, &m->wsched); | ||
| 497 | |||
| 498 | if (m->wsize || !list_empty(&m->unsent_req_list)) { | ||
| 496 | if (test_and_clear_bit(Wpending, &m->wsched)) | 499 | if (test_and_clear_bit(Wpending, &m->wsched)) |
| 497 | n = POLLOUT; | 500 | n = POLLOUT; |
| 498 | else | 501 | else |
| 499 | n = p9_fd_poll(m->client, NULL); | 502 | n = p9_fd_poll(m->client, NULL); |
| 500 | 503 | ||
| 501 | if (n & POLLOUT) { | 504 | if ((n & POLLOUT) && |
| 505 | !test_and_set_bit(Wworksched, &m->wsched)) { | ||
| 502 | p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m); | 506 | p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m); |
| 503 | schedule_work(&m->wq); | 507 | schedule_work(&m->wq); |
| 504 | } else | 508 | } |
| 505 | clear_bit(Wworksched, &m->wsched); | 509 | } |
| 506 | } else | ||
| 507 | clear_bit(Wworksched, &m->wsched); | ||
| 508 | 510 | ||
| 509 | return; | 511 | return; |
| 510 | 512 | ||
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/ceph/crypto.c b/net/ceph/crypto.c index 9da7fdd3cd8a..af14cb425164 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c | |||
| @@ -423,14 +423,15 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, | |||
| 423 | } | 423 | } |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) | 426 | int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep) |
| 427 | { | 427 | { |
| 428 | struct ceph_crypto_key *ckey; | 428 | struct ceph_crypto_key *ckey; |
| 429 | size_t datalen = prep->datalen; | ||
| 429 | int ret; | 430 | int ret; |
| 430 | void *p; | 431 | void *p; |
| 431 | 432 | ||
| 432 | ret = -EINVAL; | 433 | ret = -EINVAL; |
| 433 | if (datalen <= 0 || datalen > 32767 || !data) | 434 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 434 | goto err; | 435 | goto err; |
| 435 | 436 | ||
| 436 | ret = key_payload_reserve(key, datalen); | 437 | ret = key_payload_reserve(key, datalen); |
| @@ -443,8 +444,8 @@ int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) | |||
| 443 | goto err; | 444 | goto err; |
| 444 | 445 | ||
| 445 | /* TODO ceph_crypto_key_decode should really take const input */ | 446 | /* TODO ceph_crypto_key_decode should really take const input */ |
| 446 | p = (void *)data; | 447 | p = (void *)prep->data; |
| 447 | ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); | 448 | ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen); |
| 448 | if (ret < 0) | 449 | if (ret < 0) |
| 449 | goto err_ckey; | 450 | goto err_ckey; |
| 450 | 451 | ||
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/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index 9807945a56d9..8aa4b1115384 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c | |||
| @@ -59,13 +59,13 @@ const struct cred *dns_resolver_cache; | |||
| 59 | * "ip1,ip2,...#foo=bar" | 59 | * "ip1,ip2,...#foo=bar" |
| 60 | */ | 60 | */ |
| 61 | static int | 61 | static int |
| 62 | dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen) | 62 | dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) |
| 63 | { | 63 | { |
| 64 | struct user_key_payload *upayload; | 64 | struct user_key_payload *upayload; |
| 65 | unsigned long derrno; | 65 | unsigned long derrno; |
| 66 | int ret; | 66 | int ret; |
| 67 | size_t result_len = 0; | 67 | size_t datalen = prep->datalen, result_len = 0; |
| 68 | const char *data = _data, *end, *opt; | 68 | const char *data = prep->data, *end, *opt; |
| 69 | 69 | ||
| 70 | kenter("%%%d,%s,'%*.*s',%zu", | 70 | kenter("%%%d,%s,'%*.*s',%zu", |
| 71 | key->serial, key->description, | 71 | key->serial, key->description, |
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/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index 011d2384b115..7633a752c65e 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c | |||
| @@ -26,8 +26,8 @@ | |||
| 26 | #include "ar-internal.h" | 26 | #include "ar-internal.h" |
| 27 | 27 | ||
| 28 | static int rxrpc_vet_description_s(const char *); | 28 | static int rxrpc_vet_description_s(const char *); |
| 29 | static int rxrpc_instantiate(struct key *, const void *, size_t); | 29 | static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *); |
| 30 | static int rxrpc_instantiate_s(struct key *, const void *, size_t); | 30 | static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); |
| 31 | static void rxrpc_destroy(struct key *); | 31 | static void rxrpc_destroy(struct key *); |
| 32 | static void rxrpc_destroy_s(struct key *); | 32 | static void rxrpc_destroy_s(struct key *); |
| 33 | static void rxrpc_describe(const struct key *, struct seq_file *); | 33 | static void rxrpc_describe(const struct key *, struct seq_file *); |
| @@ -678,7 +678,7 @@ error: | |||
| 678 | * | 678 | * |
| 679 | * if no data is provided, then a no-security key is made | 679 | * if no data is provided, then a no-security key is made |
| 680 | */ | 680 | */ |
| 681 | static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) | 681 | static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) |
| 682 | { | 682 | { |
| 683 | const struct rxrpc_key_data_v1 *v1; | 683 | const struct rxrpc_key_data_v1 *v1; |
| 684 | struct rxrpc_key_token *token, **pp; | 684 | struct rxrpc_key_token *token, **pp; |
| @@ -686,26 +686,26 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) | |||
| 686 | u32 kver; | 686 | u32 kver; |
| 687 | int ret; | 687 | int ret; |
| 688 | 688 | ||
| 689 | _enter("{%x},,%zu", key_serial(key), datalen); | 689 | _enter("{%x},,%zu", key_serial(key), prep->datalen); |
| 690 | 690 | ||
| 691 | /* handle a no-security key */ | 691 | /* handle a no-security key */ |
| 692 | if (!data && datalen == 0) | 692 | if (!prep->data && prep->datalen == 0) |
| 693 | return 0; | 693 | return 0; |
| 694 | 694 | ||
| 695 | /* determine if the XDR payload format is being used */ | 695 | /* determine if the XDR payload format is being used */ |
| 696 | if (datalen > 7 * 4) { | 696 | if (prep->datalen > 7 * 4) { |
| 697 | ret = rxrpc_instantiate_xdr(key, data, datalen); | 697 | ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); |
| 698 | if (ret != -EPROTO) | 698 | if (ret != -EPROTO) |
| 699 | return ret; | 699 | return ret; |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | /* get the key interface version number */ | 702 | /* get the key interface version number */ |
| 703 | ret = -EINVAL; | 703 | ret = -EINVAL; |
| 704 | if (datalen <= 4 || !data) | 704 | if (prep->datalen <= 4 || !prep->data) |
| 705 | goto error; | 705 | goto error; |
| 706 | memcpy(&kver, data, sizeof(kver)); | 706 | memcpy(&kver, prep->data, sizeof(kver)); |
| 707 | data += sizeof(kver); | 707 | prep->data += sizeof(kver); |
| 708 | datalen -= sizeof(kver); | 708 | prep->datalen -= sizeof(kver); |
| 709 | 709 | ||
| 710 | _debug("KEY I/F VERSION: %u", kver); | 710 | _debug("KEY I/F VERSION: %u", kver); |
| 711 | 711 | ||
| @@ -715,11 +715,11 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) | |||
| 715 | 715 | ||
| 716 | /* deal with a version 1 key */ | 716 | /* deal with a version 1 key */ |
| 717 | ret = -EINVAL; | 717 | ret = -EINVAL; |
| 718 | if (datalen < sizeof(*v1)) | 718 | if (prep->datalen < sizeof(*v1)) |
| 719 | goto error; | 719 | goto error; |
| 720 | 720 | ||
| 721 | v1 = data; | 721 | v1 = prep->data; |
| 722 | if (datalen != sizeof(*v1) + v1->ticket_length) | 722 | if (prep->datalen != sizeof(*v1) + v1->ticket_length) |
| 723 | goto error; | 723 | goto error; |
| 724 | 724 | ||
| 725 | _debug("SCIX: %u", v1->security_index); | 725 | _debug("SCIX: %u", v1->security_index); |
| @@ -784,17 +784,17 @@ error: | |||
| 784 | * instantiate a server secret key | 784 | * instantiate a server secret key |
| 785 | * data should be a pointer to the 8-byte secret key | 785 | * data should be a pointer to the 8-byte secret key |
| 786 | */ | 786 | */ |
| 787 | static int rxrpc_instantiate_s(struct key *key, const void *data, | 787 | static int rxrpc_instantiate_s(struct key *key, |
| 788 | size_t datalen) | 788 | struct key_preparsed_payload *prep) |
| 789 | { | 789 | { |
| 790 | struct crypto_blkcipher *ci; | 790 | struct crypto_blkcipher *ci; |
| 791 | 791 | ||
| 792 | _enter("{%x},,%zu", key_serial(key), datalen); | 792 | _enter("{%x},,%zu", key_serial(key), prep->datalen); |
| 793 | 793 | ||
| 794 | if (datalen != 8) | 794 | if (prep->datalen != 8) |
| 795 | return -EINVAL; | 795 | return -EINVAL; |
| 796 | 796 | ||
| 797 | memcpy(&key->type_data, data, 8); | 797 | memcpy(&key->type_data, prep->data, 8); |
| 798 | 798 | ||
| 799 | ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); | 799 | ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); |
| 800 | if (IS_ERR(ci)) { | 800 | if (IS_ERR(ci)) { |
| @@ -802,7 +802,7 @@ static int rxrpc_instantiate_s(struct key *key, const void *data, | |||
| 802 | return PTR_ERR(ci); | 802 | return PTR_ERR(ci); |
| 803 | } | 803 | } |
| 804 | 804 | ||
| 805 | if (crypto_blkcipher_setkey(ci, data, 8) < 0) | 805 | if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) |
| 806 | BUG(); | 806 | BUG(); |
| 807 | 807 | ||
| 808 | key->payload.data = ci; | 808 | key->payload.data = ci; |
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 | } |
