diff options
author | Christoph Hellwig <hch@hera.kernel.org> | 2005-05-27 01:16:24 -0700 |
---|---|---|
committer | Christoph Hellwig <hch@melbourne.sgi.com> | 2005-05-27 01:16:24 -0700 |
commit | b19312c4c8f3f84da57bba01d45549df1cf10dcd (patch) | |
tree | 1c34ce89be6b4e257bc03026d0268deb17727044 /net/netlink/af_netlink.c | |
parent | d3870398fafd4911bd84573b78be4b6b762f32b0 (diff) | |
parent | 4ec5240ec367a592834385893200dd4fb369354c (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r-- | net/netlink/af_netlink.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 733bf52cef3..e41ce458c2a 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -735,11 +735,15 @@ static inline int do_one_broadcast(struct sock *sk, sock_hold(sk); if (p->skb2 == NULL) { - if (atomic_read(&p->skb->users) != 1) { + if (skb_shared(p->skb)) { p->skb2 = skb_clone(p->skb, p->allocation); } else { - p->skb2 = p->skb; - atomic_inc(&p->skb->users); + p->skb2 = skb_get(p->skb); + /* + * skb ownership may have been set when + * delivered to a previous socket. + */ + skb_orphan(p->skb2); } } if (p->skb2 == NULL) { @@ -785,11 +789,12 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) do_one_broadcast(sk, &info); + kfree_skb(skb); + netlink_unlock_table(); if (info.skb2) kfree_skb(info.skb2); - kfree_skb(skb); if (info.delivered) { if (info.congested && (allocation & __GFP_WAIT)) |