diff options
author | David S. Miller <davem@davemloft.net> | 2015-10-20 09:08:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-20 09:08:27 -0400 |
commit | 26440c835f8b1a491e2704118ac55bf87334366c (patch) | |
tree | 3c2d23b59fd49b252fdbf6c09efc41b354933fc6 /net/netlink | |
parent | 371f1c7e0d854796adc622cc3bacfcc5fc638db1 (diff) | |
parent | 1099f86044111e9a7807f09523e42d4c9d0fb781 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/usb/asix_common.c
net/ipv4/inet_connection_sock.c
net/switchdev/switchdev.c
In the inet_connection_sock.c case the request socket hashing scheme
is completely different in net-next.
The other two conflicts were overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8f060d7f9a0e..0a49a8c7c564 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -2785,6 +2785,7 @@ static int netlink_dump(struct sock *sk) | |||
2785 | struct sk_buff *skb = NULL; | 2785 | struct sk_buff *skb = NULL; |
2786 | struct nlmsghdr *nlh; | 2786 | struct nlmsghdr *nlh; |
2787 | int len, err = -ENOBUFS; | 2787 | int len, err = -ENOBUFS; |
2788 | int alloc_min_size; | ||
2788 | int alloc_size; | 2789 | int alloc_size; |
2789 | 2790 | ||
2790 | mutex_lock(nlk->cb_mutex); | 2791 | mutex_lock(nlk->cb_mutex); |
@@ -2793,9 +2794,6 @@ static int netlink_dump(struct sock *sk) | |||
2793 | goto errout_skb; | 2794 | goto errout_skb; |
2794 | } | 2795 | } |
2795 | 2796 | ||
2796 | cb = &nlk->cb; | ||
2797 | alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE); | ||
2798 | |||
2799 | if (!netlink_rx_is_mmaped(sk) && | 2797 | if (!netlink_rx_is_mmaped(sk) && |
2800 | atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) | 2798 | atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) |
2801 | goto errout_skb; | 2799 | goto errout_skb; |
@@ -2805,23 +2803,35 @@ static int netlink_dump(struct sock *sk) | |||
2805 | * to reduce number of system calls on dump operations, if user | 2803 | * to reduce number of system calls on dump operations, if user |
2806 | * ever provided a big enough buffer. | 2804 | * ever provided a big enough buffer. |
2807 | */ | 2805 | */ |
2808 | if (alloc_size < nlk->max_recvmsg_len) { | 2806 | cb = &nlk->cb; |
2809 | skb = netlink_alloc_skb(sk, | 2807 | alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE); |
2810 | nlk->max_recvmsg_len, | 2808 | |
2811 | nlk->portid, | 2809 | if (alloc_min_size < nlk->max_recvmsg_len) { |
2810 | alloc_size = nlk->max_recvmsg_len; | ||
2811 | skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, | ||
2812 | GFP_KERNEL | | 2812 | GFP_KERNEL | |
2813 | __GFP_NOWARN | | 2813 | __GFP_NOWARN | |
2814 | __GFP_NORETRY); | 2814 | __GFP_NORETRY); |
2815 | /* available room should be exact amount to avoid MSG_TRUNC */ | ||
2816 | if (skb) | ||
2817 | skb_reserve(skb, skb_tailroom(skb) - | ||
2818 | nlk->max_recvmsg_len); | ||
2819 | } | 2815 | } |
2820 | if (!skb) | 2816 | if (!skb) { |
2817 | alloc_size = alloc_min_size; | ||
2821 | skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, | 2818 | skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, |
2822 | GFP_KERNEL); | 2819 | GFP_KERNEL); |
2820 | } | ||
2823 | if (!skb) | 2821 | if (!skb) |
2824 | goto errout_skb; | 2822 | goto errout_skb; |
2823 | |||
2824 | /* Trim skb to allocated size. User is expected to provide buffer as | ||
2825 | * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at | ||
2826 | * netlink_recvmsg())). dump will pack as many smaller messages as | ||
2827 | * could fit within the allocated skb. skb is typically allocated | ||
2828 | * with larger space than required (could be as much as near 2x the | ||
2829 | * requested size with align to next power of 2 approach). Allowing | ||
2830 | * dump to use the excess space makes it difficult for a user to have a | ||
2831 | * reasonable static buffer based on the expected largest dump of a | ||
2832 | * single netdev. The outcome is MSG_TRUNC error. | ||
2833 | */ | ||
2834 | skb_reserve(skb, skb_tailroom(skb) - alloc_size); | ||
2825 | netlink_skb_set_owner_r(skb, sk); | 2835 | netlink_skb_set_owner_r(skb, sk); |
2826 | 2836 | ||
2827 | len = cb->dump(skb, cb); | 2837 | len = cb->dump(skb, cb); |