diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 720fda6cc2e6..679a22082fcb 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2749,29 +2749,35 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
2749 | struct tipc_sock *tsk; | 2749 | struct tipc_sock *tsk; |
2750 | const struct bucket_table *tbl; | 2750 | const struct bucket_table *tbl; |
2751 | struct rhash_head *pos; | 2751 | struct rhash_head *pos; |
2752 | u32 prev_portid = cb->args[0]; | ||
2753 | u32 portid = prev_portid; | ||
2754 | struct net *net = sock_net(skb->sk); | 2752 | struct net *net = sock_net(skb->sk); |
2755 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 2753 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
2756 | int i; | 2754 | u32 tbl_id = cb->args[0]; |
2755 | u32 prev_portid = cb->args[1]; | ||
2757 | 2756 | ||
2758 | rcu_read_lock(); | 2757 | rcu_read_lock(); |
2759 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | 2758 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); |
2760 | for (i = 0; i < tbl->size; i++) { | 2759 | for (; tbl_id < tbl->size; tbl_id++) { |
2761 | rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { | 2760 | rht_for_each_entry_rcu(tsk, pos, tbl, tbl_id, node) { |
2762 | spin_lock_bh(&tsk->sk.sk_lock.slock); | 2761 | spin_lock_bh(&tsk->sk.sk_lock.slock); |
2763 | portid = tsk->portid; | 2762 | if (prev_portid && prev_portid != tsk->portid) { |
2763 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
2764 | continue; | ||
2765 | } | ||
2766 | |||
2764 | err = __tipc_nl_add_sk(skb, cb, tsk); | 2767 | err = __tipc_nl_add_sk(skb, cb, tsk); |
2768 | if (err) { | ||
2769 | prev_portid = tsk->portid; | ||
2770 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
2771 | goto out; | ||
2772 | } | ||
2773 | prev_portid = 0; | ||
2765 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | 2774 | spin_unlock_bh(&tsk->sk.sk_lock.slock); |
2766 | if (err) | ||
2767 | break; | ||
2768 | |||
2769 | prev_portid = portid; | ||
2770 | } | 2775 | } |
2771 | } | 2776 | } |
2777 | out: | ||
2772 | rcu_read_unlock(); | 2778 | rcu_read_unlock(); |
2773 | 2779 | cb->args[0] = tbl_id; | |
2774 | cb->args[0] = prev_portid; | 2780 | cb->args[1] = prev_portid; |
2775 | 2781 | ||
2776 | return skb->len; | 2782 | return skb->len; |
2777 | } | 2783 | } |