aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_diag.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/inet_diag.c')
-rw-r--r--net/ipv4/inet_diag.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 564230dabcb8..588a7796e3e3 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -718,13 +718,15 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
718 if (!(r->idiag_states & (TCPF_LISTEN | TCPF_SYN_RECV))) 718 if (!(r->idiag_states & (TCPF_LISTEN | TCPF_SYN_RECV)))
719 goto skip_listen_ht; 719 goto skip_listen_ht;
720 720
721 inet_listen_lock(hashinfo);
722 for (i = s_i; i < INET_LHTABLE_SIZE; i++) { 721 for (i = s_i; i < INET_LHTABLE_SIZE; i++) {
723 struct sock *sk; 722 struct sock *sk;
724 struct hlist_node *node; 723 struct hlist_nulls_node *node;
724 struct inet_listen_hashbucket *ilb;
725 725
726 num = 0; 726 num = 0;
727 sk_for_each(sk, node, &hashinfo->listening_hash[i]) { 727 ilb = &hashinfo->listening_hash[i];
728 spin_lock_bh(&ilb->lock);
729 sk_nulls_for_each(sk, node, &ilb->head) {
728 struct inet_sock *inet = inet_sk(sk); 730 struct inet_sock *inet = inet_sk(sk);
729 731
730 if (num < s_num) { 732 if (num < s_num) {
@@ -742,7 +744,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
742 goto syn_recv; 744 goto syn_recv;
743 745
744 if (inet_csk_diag_dump(sk, skb, cb) < 0) { 746 if (inet_csk_diag_dump(sk, skb, cb) < 0) {
745 inet_listen_unlock(hashinfo); 747 spin_unlock_bh(&ilb->lock);
746 goto done; 748 goto done;
747 } 749 }
748 750
@@ -751,7 +753,7 @@ syn_recv:
751 goto next_listen; 753 goto next_listen;
752 754
753 if (inet_diag_dump_reqs(skb, sk, cb) < 0) { 755 if (inet_diag_dump_reqs(skb, sk, cb) < 0) {
754 inet_listen_unlock(hashinfo); 756 spin_unlock_bh(&ilb->lock);
755 goto done; 757 goto done;
756 } 758 }
757 759
@@ -760,12 +762,12 @@ next_listen:
760 cb->args[4] = 0; 762 cb->args[4] = 0;
761 ++num; 763 ++num;
762 } 764 }
765 spin_unlock_bh(&ilb->lock);
763 766
764 s_num = 0; 767 s_num = 0;
765 cb->args[3] = 0; 768 cb->args[3] = 0;
766 cb->args[4] = 0; 769 cb->args[4] = 0;
767 } 770 }
768 inet_listen_unlock(hashinfo);
769skip_listen_ht: 771skip_listen_ht:
770 cb->args[0] = 1; 772 cb->args[0] = 1;
771 s_i = num = s_num = 0; 773 s_i = num = s_num = 0;
@@ -776,20 +778,21 @@ skip_listen_ht:
776 778
777 for (i = s_i; i < hashinfo->ehash_size; i++) { 779 for (i = s_i; i < hashinfo->ehash_size; i++) {
778 struct inet_ehash_bucket *head = &hashinfo->ehash[i]; 780 struct inet_ehash_bucket *head = &hashinfo->ehash[i];
779 rwlock_t *lock = inet_ehash_lockp(hashinfo, i); 781 spinlock_t *lock = inet_ehash_lockp(hashinfo, i);
780 struct sock *sk; 782 struct sock *sk;
781 struct hlist_node *node; 783 struct hlist_nulls_node *node;
782 784
783 num = 0; 785 num = 0;
784 786
785 if (hlist_empty(&head->chain) && hlist_empty(&head->twchain)) 787 if (hlist_nulls_empty(&head->chain) &&
788 hlist_nulls_empty(&head->twchain))
786 continue; 789 continue;
787 790
788 if (i > s_i) 791 if (i > s_i)
789 s_num = 0; 792 s_num = 0;
790 793
791 read_lock_bh(lock); 794 spin_lock_bh(lock);
792 sk_for_each(sk, node, &head->chain) { 795 sk_nulls_for_each(sk, node, &head->chain) {
793 struct inet_sock *inet = inet_sk(sk); 796 struct inet_sock *inet = inet_sk(sk);
794 797
795 if (num < s_num) 798 if (num < s_num)
@@ -803,7 +806,7 @@ skip_listen_ht:
803 r->id.idiag_dport) 806 r->id.idiag_dport)
804 goto next_normal; 807 goto next_normal;
805 if (inet_csk_diag_dump(sk, skb, cb) < 0) { 808 if (inet_csk_diag_dump(sk, skb, cb) < 0) {
806 read_unlock_bh(lock); 809 spin_unlock_bh(lock);
807 goto done; 810 goto done;
808 } 811 }
809next_normal: 812next_normal:
@@ -825,14 +828,14 @@ next_normal:
825 r->id.idiag_dport) 828 r->id.idiag_dport)
826 goto next_dying; 829 goto next_dying;
827 if (inet_twsk_diag_dump(tw, skb, cb) < 0) { 830 if (inet_twsk_diag_dump(tw, skb, cb) < 0) {
828 read_unlock_bh(lock); 831 spin_unlock_bh(lock);
829 goto done; 832 goto done;
830 } 833 }
831next_dying: 834next_dying:
832 ++num; 835 ++num;
833 } 836 }
834 } 837 }
835 read_unlock_bh(lock); 838 spin_unlock_bh(lock);
836 } 839 }
837 840
838done: 841done: