diff options
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 9eb895c7a2a9..6ee69c27f806 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -950,6 +950,7 @@ struct netlink_broadcast_data { | |||
950 | u32 pid; | 950 | u32 pid; |
951 | u32 group; | 951 | u32 group; |
952 | int failure; | 952 | int failure; |
953 | int delivery_failure; | ||
953 | int congested; | 954 | int congested; |
954 | int delivered; | 955 | int delivered; |
955 | gfp_t allocation; | 956 | gfp_t allocation; |
@@ -999,6 +1000,7 @@ static inline int do_one_broadcast(struct sock *sk, | |||
999 | p->skb2 = NULL; | 1000 | p->skb2 = NULL; |
1000 | } else if ((val = netlink_broadcast_deliver(sk, p->skb2)) < 0) { | 1001 | } else if ((val = netlink_broadcast_deliver(sk, p->skb2)) < 0) { |
1001 | netlink_overrun(sk); | 1002 | netlink_overrun(sk); |
1003 | p->delivery_failure = 1; | ||
1002 | } else { | 1004 | } else { |
1003 | p->congested |= val; | 1005 | p->congested |= val; |
1004 | p->delivered = 1; | 1006 | p->delivered = 1; |
@@ -1025,6 +1027,7 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
1025 | info.pid = pid; | 1027 | info.pid = pid; |
1026 | info.group = group; | 1028 | info.group = group; |
1027 | info.failure = 0; | 1029 | info.failure = 0; |
1030 | info.delivery_failure = 0; | ||
1028 | info.congested = 0; | 1031 | info.congested = 0; |
1029 | info.delivered = 0; | 1032 | info.delivered = 0; |
1030 | info.allocation = allocation; | 1033 | info.allocation = allocation; |
@@ -1045,13 +1048,14 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
1045 | if (info.skb2) | 1048 | if (info.skb2) |
1046 | kfree_skb(info.skb2); | 1049 | kfree_skb(info.skb2); |
1047 | 1050 | ||
1051 | if (info.delivery_failure || info.failure) | ||
1052 | return -ENOBUFS; | ||
1053 | |||
1048 | if (info.delivered) { | 1054 | if (info.delivered) { |
1049 | if (info.congested && (allocation & __GFP_WAIT)) | 1055 | if (info.congested && (allocation & __GFP_WAIT)) |
1050 | yield(); | 1056 | yield(); |
1051 | return 0; | 1057 | return 0; |
1052 | } | 1058 | } |
1053 | if (info.failure) | ||
1054 | return -ENOBUFS; | ||
1055 | return -ESRCH; | 1059 | return -ESRCH; |
1056 | } | 1060 | } |
1057 | EXPORT_SYMBOL(netlink_broadcast); | 1061 | EXPORT_SYMBOL(netlink_broadcast); |