|
@@ -829,12 +829,19 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
|
|
|
+static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
|
|
|
{
|
|
|
int len = skb->len;
|
|
|
|
|
|
skb_queue_tail(&sk->sk_receive_queue, skb);
|
|
|
sk->sk_data_ready(sk, len);
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ int len = __netlink_sendskb(sk, skb);
|
|
|
+
|
|
|
sock_put(sk);
|
|
|
return len;
|
|
|
}
|
|
@@ -957,8 +964,7 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
|
|
|
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
|
|
|
!test_bit(0, &nlk->state)) {
|
|
|
skb_set_owner_r(skb, sk);
|
|
|
- skb_queue_tail(&sk->sk_receive_queue, skb);
|
|
|
- sk->sk_data_ready(sk, skb->len);
|
|
|
+ __netlink_sendskb(sk, skb);
|
|
|
return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
|
|
|
}
|
|
|
return -1;
|
|
@@ -1698,10 +1704,8 @@ static int netlink_dump(struct sock *sk)
|
|
|
|
|
|
if (sk_filter(sk, skb))
|
|
|
kfree_skb(skb);
|
|
|
- else {
|
|
|
- skb_queue_tail(&sk->sk_receive_queue, skb);
|
|
|
- sk->sk_data_ready(sk, skb->len);
|
|
|
- }
|
|
|
+ else
|
|
|
+ __netlink_sendskb(sk, skb);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1715,10 +1719,8 @@ static int netlink_dump(struct sock *sk)
|
|
|
|
|
|
if (sk_filter(sk, skb))
|
|
|
kfree_skb(skb);
|
|
|
- else {
|
|
|
- skb_queue_tail(&sk->sk_receive_queue, skb);
|
|
|
- sk->sk_data_ready(sk, skb->len);
|
|
|
- }
|
|
|
+ else
|
|
|
+ __netlink_sendskb(sk, skb);
|
|
|
|
|
|
if (cb->done)
|
|
|
cb->done(cb);
|