aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r--net/dccp/proto.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index a156319fd0ac..a0e38d8018f5 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -20,6 +20,7 @@
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/random.h> 22#include <linux/random.h>
23#include <linux/slab.h>
23#include <net/checksum.h> 24#include <net/checksum.h>
24 25
25#include <net/inet_sock.h> 26#include <net/inet_sock.h>
@@ -278,7 +279,7 @@ int dccp_disconnect(struct sock *sk, int flags)
278 sk->sk_send_head = NULL; 279 sk->sk_send_head = NULL;
279 } 280 }
280 281
281 inet->dport = 0; 282 inet->inet_dport = 0;
282 283
283 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) 284 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
284 inet_reset_saddr(sk); 285 inet_reset_saddr(sk);
@@ -290,7 +291,7 @@ int dccp_disconnect(struct sock *sk, int flags)
290 inet_csk_delack_init(sk); 291 inet_csk_delack_init(sk);
291 __sk_dst_reset(sk); 292 __sk_dst_reset(sk);
292 293
293 WARN_ON(inet->num && !icsk->icsk_bind_hash); 294 WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
294 295
295 sk->sk_error_report(sk); 296 sk->sk_error_report(sk);
296 return err; 297 return err;
@@ -835,6 +836,8 @@ verify_sock_status:
835 len = -EFAULT; 836 len = -EFAULT;
836 break; 837 break;
837 } 838 }
839 if (flags & MSG_TRUNC)
840 len = skb->len;
838 found_fin_ok: 841 found_fin_ok:
839 if (!(flags & MSG_PEEK)) 842 if (!(flags & MSG_PEEK))
840 sk_eat_skb(sk, skb, 0); 843 sk_eat_skb(sk, skb, 0);
@@ -1003,12 +1006,13 @@ EXPORT_SYMBOL_GPL(dccp_shutdown);
1003 1006
1004static inline int dccp_mib_init(void) 1007static inline int dccp_mib_init(void)
1005{ 1008{
1006 return snmp_mib_init((void**)dccp_statistics, sizeof(struct dccp_mib)); 1009 return snmp_mib_init((void __percpu **)dccp_statistics,
1010 sizeof(struct dccp_mib));
1007} 1011}
1008 1012
1009static inline void dccp_mib_exit(void) 1013static inline void dccp_mib_exit(void)
1010{ 1014{
1011 snmp_mib_free((void**)dccp_statistics); 1015 snmp_mib_free((void __percpu **)dccp_statistics);
1012} 1016}
1013 1017
1014static int thash_entries; 1018static int thash_entries;
@@ -1033,7 +1037,7 @@ static int __init dccp_init(void)
1033 FIELD_SIZEOF(struct sk_buff, cb)); 1037 FIELD_SIZEOF(struct sk_buff, cb));
1034 rc = percpu_counter_init(&dccp_orphan_count, 0); 1038 rc = percpu_counter_init(&dccp_orphan_count, 0);
1035 if (rc) 1039 if (rc)
1036 goto out; 1040 goto out_fail;
1037 rc = -ENOBUFS; 1041 rc = -ENOBUFS;
1038 inet_hashinfo_init(&dccp_hashinfo); 1042 inet_hashinfo_init(&dccp_hashinfo);
1039 dccp_hashinfo.bind_bucket_cachep = 1043 dccp_hashinfo.bind_bucket_cachep =
@@ -1060,11 +1064,12 @@ static int __init dccp_init(void)
1060 for (ehash_order = 0; (1UL << ehash_order) < goal; ehash_order++) 1064 for (ehash_order = 0; (1UL << ehash_order) < goal; ehash_order++)
1061 ; 1065 ;
1062 do { 1066 do {
1063 dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE / 1067 unsigned long hash_size = (1UL << ehash_order) * PAGE_SIZE /
1064 sizeof(struct inet_ehash_bucket); 1068 sizeof(struct inet_ehash_bucket);
1065 while (dccp_hashinfo.ehash_size & 1069
1066 (dccp_hashinfo.ehash_size - 1)) 1070 while (hash_size & (hash_size - 1))
1067 dccp_hashinfo.ehash_size--; 1071 hash_size--;
1072 dccp_hashinfo.ehash_mask = hash_size - 1;
1068 dccp_hashinfo.ehash = (struct inet_ehash_bucket *) 1073 dccp_hashinfo.ehash = (struct inet_ehash_bucket *)
1069 __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, ehash_order); 1074 __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, ehash_order);
1070 } while (!dccp_hashinfo.ehash && --ehash_order > 0); 1075 } while (!dccp_hashinfo.ehash && --ehash_order > 0);
@@ -1074,7 +1079,7 @@ static int __init dccp_init(void)
1074 goto out_free_bind_bucket_cachep; 1079 goto out_free_bind_bucket_cachep;
1075 } 1080 }
1076 1081
1077 for (i = 0; i < dccp_hashinfo.ehash_size; i++) { 1082 for (i = 0; i <= dccp_hashinfo.ehash_mask; i++) {
1078 INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].chain, i); 1083 INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].chain, i);
1079 INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].twchain, i); 1084 INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].twchain, i);
1080 } 1085 }
@@ -1121,8 +1126,9 @@ static int __init dccp_init(void)
1121 goto out_sysctl_exit; 1126 goto out_sysctl_exit;
1122 1127
1123 dccp_timestamping_init(); 1128 dccp_timestamping_init();
1124out: 1129
1125 return rc; 1130 return 0;
1131
1126out_sysctl_exit: 1132out_sysctl_exit:
1127 dccp_sysctl_exit(); 1133 dccp_sysctl_exit();
1128out_ackvec_exit: 1134out_ackvec_exit:
@@ -1131,18 +1137,19 @@ out_free_dccp_mib:
1131 dccp_mib_exit(); 1137 dccp_mib_exit();
1132out_free_dccp_bhash: 1138out_free_dccp_bhash:
1133 free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order); 1139 free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
1134 dccp_hashinfo.bhash = NULL;
1135out_free_dccp_locks: 1140out_free_dccp_locks:
1136 inet_ehash_locks_free(&dccp_hashinfo); 1141 inet_ehash_locks_free(&dccp_hashinfo);
1137out_free_dccp_ehash: 1142out_free_dccp_ehash:
1138 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order); 1143 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
1139 dccp_hashinfo.ehash = NULL;
1140out_free_bind_bucket_cachep: 1144out_free_bind_bucket_cachep:
1141 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); 1145 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
1142 dccp_hashinfo.bind_bucket_cachep = NULL;
1143out_free_percpu: 1146out_free_percpu:
1144 percpu_counter_destroy(&dccp_orphan_count); 1147 percpu_counter_destroy(&dccp_orphan_count);
1145 goto out; 1148out_fail:
1149 dccp_hashinfo.bhash = NULL;
1150 dccp_hashinfo.ehash = NULL;
1151 dccp_hashinfo.bind_bucket_cachep = NULL;
1152 return rc;
1146} 1153}
1147 1154
1148static void __exit dccp_fini(void) 1155static void __exit dccp_fini(void)
@@ -1153,7 +1160,7 @@ static void __exit dccp_fini(void)
1153 get_order(dccp_hashinfo.bhash_size * 1160 get_order(dccp_hashinfo.bhash_size *
1154 sizeof(struct inet_bind_hashbucket))); 1161 sizeof(struct inet_bind_hashbucket)));
1155 free_pages((unsigned long)dccp_hashinfo.ehash, 1162 free_pages((unsigned long)dccp_hashinfo.ehash,
1156 get_order(dccp_hashinfo.ehash_size * 1163 get_order((dccp_hashinfo.ehash_mask + 1) *
1157 sizeof(struct inet_ehash_bucket))); 1164 sizeof(struct inet_ehash_bucket)));
1158 inet_ehash_locks_free(&dccp_hashinfo); 1165 inet_ehash_locks_free(&dccp_hashinfo);
1159 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); 1166 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);