diff options
Diffstat (limited to 'net/core/sock.c')
-rw-r--r-- | net/core/sock.c | 186 |
1 files changed, 114 insertions, 72 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 7dbf3ffb35cc..76334228ed1c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -155,6 +155,7 @@ static const char *af_family_key_strings[AF_MAX+1] = { | |||
155 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , | 155 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , |
156 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 156 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
157 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 157 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
158 | "sk_lock-AF_IEEE802154", | ||
158 | "sk_lock-AF_MAX" | 159 | "sk_lock-AF_MAX" |
159 | }; | 160 | }; |
160 | static const char *af_family_slock_key_strings[AF_MAX+1] = { | 161 | static const char *af_family_slock_key_strings[AF_MAX+1] = { |
@@ -170,6 +171,7 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = { | |||
170 | "slock-27" , "slock-28" , "slock-AF_CAN" , | 171 | "slock-27" , "slock-28" , "slock-AF_CAN" , |
171 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 172 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
172 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 173 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
174 | "slock-AF_IEEE802154", | ||
173 | "slock-AF_MAX" | 175 | "slock-AF_MAX" |
174 | }; | 176 | }; |
175 | static const char *af_family_clock_key_strings[AF_MAX+1] = { | 177 | static const char *af_family_clock_key_strings[AF_MAX+1] = { |
@@ -185,6 +187,7 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = { | |||
185 | "clock-27" , "clock-28" , "clock-AF_CAN" , | 187 | "clock-27" , "clock-28" , "clock-AF_CAN" , |
186 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 188 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
187 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 189 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
190 | "clock-AF_IEEE802154", | ||
188 | "clock-AF_MAX" | 191 | "clock-AF_MAX" |
189 | }; | 192 | }; |
190 | 193 | ||
@@ -212,6 +215,7 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; | |||
212 | 215 | ||
213 | /* Maximal space eaten by iovec or ancilliary data plus some space */ | 216 | /* Maximal space eaten by iovec or ancilliary data plus some space */ |
214 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); | 217 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); |
218 | EXPORT_SYMBOL(sysctl_optmem_max); | ||
215 | 219 | ||
216 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) | 220 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) |
217 | { | 221 | { |
@@ -444,7 +448,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) | |||
444 | int sock_setsockopt(struct socket *sock, int level, int optname, | 448 | int sock_setsockopt(struct socket *sock, int level, int optname, |
445 | char __user *optval, int optlen) | 449 | char __user *optval, int optlen) |
446 | { | 450 | { |
447 | struct sock *sk=sock->sk; | 451 | struct sock *sk = sock->sk; |
448 | int val; | 452 | int val; |
449 | int valbool; | 453 | int valbool; |
450 | struct linger ling; | 454 | struct linger ling; |
@@ -463,15 +467,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname, | |||
463 | if (get_user(val, (int __user *)optval)) | 467 | if (get_user(val, (int __user *)optval)) |
464 | return -EFAULT; | 468 | return -EFAULT; |
465 | 469 | ||
466 | valbool = val?1:0; | 470 | valbool = val ? 1 : 0; |
467 | 471 | ||
468 | lock_sock(sk); | 472 | lock_sock(sk); |
469 | 473 | ||
470 | switch(optname) { | 474 | switch (optname) { |
471 | case SO_DEBUG: | 475 | case SO_DEBUG: |
472 | if (val && !capable(CAP_NET_ADMIN)) { | 476 | if (val && !capable(CAP_NET_ADMIN)) |
473 | ret = -EACCES; | 477 | ret = -EACCES; |
474 | } else | 478 | else |
475 | sock_valbool_flag(sk, SOCK_DBG, valbool); | 479 | sock_valbool_flag(sk, SOCK_DBG, valbool); |
476 | break; | 480 | break; |
477 | case SO_REUSEADDR: | 481 | case SO_REUSEADDR: |
@@ -582,7 +586,7 @@ set_rcvbuf: | |||
582 | ret = -EINVAL; /* 1003.1g */ | 586 | ret = -EINVAL; /* 1003.1g */ |
583 | break; | 587 | break; |
584 | } | 588 | } |
585 | if (copy_from_user(&ling,optval,sizeof(ling))) { | 589 | if (copy_from_user(&ling, optval, sizeof(ling))) { |
586 | ret = -EFAULT; | 590 | ret = -EFAULT; |
587 | break; | 591 | break; |
588 | } | 592 | } |
@@ -627,7 +631,7 @@ set_rcvbuf: | |||
627 | 631 | ||
628 | case SO_TIMESTAMPING: | 632 | case SO_TIMESTAMPING: |
629 | if (val & ~SOF_TIMESTAMPING_MASK) { | 633 | if (val & ~SOF_TIMESTAMPING_MASK) { |
630 | ret = EINVAL; | 634 | ret = -EINVAL; |
631 | break; | 635 | break; |
632 | } | 636 | } |
633 | sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE, | 637 | sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE, |
@@ -690,9 +694,8 @@ set_rcvbuf: | |||
690 | case SO_MARK: | 694 | case SO_MARK: |
691 | if (!capable(CAP_NET_ADMIN)) | 695 | if (!capable(CAP_NET_ADMIN)) |
692 | ret = -EPERM; | 696 | ret = -EPERM; |
693 | else { | 697 | else |
694 | sk->sk_mark = val; | 698 | sk->sk_mark = val; |
695 | } | ||
696 | break; | 699 | break; |
697 | 700 | ||
698 | /* We implement the SO_SNDLOWAT etc to | 701 | /* We implement the SO_SNDLOWAT etc to |
@@ -704,6 +707,7 @@ set_rcvbuf: | |||
704 | release_sock(sk); | 707 | release_sock(sk); |
705 | return ret; | 708 | return ret; |
706 | } | 709 | } |
710 | EXPORT_SYMBOL(sock_setsockopt); | ||
707 | 711 | ||
708 | 712 | ||
709 | int sock_getsockopt(struct socket *sock, int level, int optname, | 713 | int sock_getsockopt(struct socket *sock, int level, int optname, |
@@ -727,7 +731,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
727 | 731 | ||
728 | memset(&v, 0, sizeof(v)); | 732 | memset(&v, 0, sizeof(v)); |
729 | 733 | ||
730 | switch(optname) { | 734 | switch (optname) { |
731 | case SO_DEBUG: | 735 | case SO_DEBUG: |
732 | v.val = sock_flag(sk, SOCK_DBG); | 736 | v.val = sock_flag(sk, SOCK_DBG); |
733 | break; | 737 | break; |
@@ -762,7 +766,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
762 | 766 | ||
763 | case SO_ERROR: | 767 | case SO_ERROR: |
764 | v.val = -sock_error(sk); | 768 | v.val = -sock_error(sk); |
765 | if (v.val==0) | 769 | if (v.val == 0) |
766 | v.val = xchg(&sk->sk_err_soft, 0); | 770 | v.val = xchg(&sk->sk_err_soft, 0); |
767 | break; | 771 | break; |
768 | 772 | ||
@@ -816,7 +820,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
816 | break; | 820 | break; |
817 | 821 | ||
818 | case SO_RCVTIMEO: | 822 | case SO_RCVTIMEO: |
819 | lv=sizeof(struct timeval); | 823 | lv = sizeof(struct timeval); |
820 | if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) { | 824 | if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) { |
821 | v.tm.tv_sec = 0; | 825 | v.tm.tv_sec = 0; |
822 | v.tm.tv_usec = 0; | 826 | v.tm.tv_usec = 0; |
@@ -827,7 +831,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
827 | break; | 831 | break; |
828 | 832 | ||
829 | case SO_SNDTIMEO: | 833 | case SO_SNDTIMEO: |
830 | lv=sizeof(struct timeval); | 834 | lv = sizeof(struct timeval); |
831 | if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) { | 835 | if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) { |
832 | v.tm.tv_sec = 0; | 836 | v.tm.tv_sec = 0; |
833 | v.tm.tv_usec = 0; | 837 | v.tm.tv_usec = 0; |
@@ -842,7 +846,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
842 | break; | 846 | break; |
843 | 847 | ||
844 | case SO_SNDLOWAT: | 848 | case SO_SNDLOWAT: |
845 | v.val=1; | 849 | v.val = 1; |
846 | break; | 850 | break; |
847 | 851 | ||
848 | case SO_PASSCRED: | 852 | case SO_PASSCRED: |
@@ -915,13 +919,19 @@ static inline void sock_lock_init(struct sock *sk) | |||
915 | af_family_keys + sk->sk_family); | 919 | af_family_keys + sk->sk_family); |
916 | } | 920 | } |
917 | 921 | ||
922 | /* | ||
923 | * Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet, | ||
924 | * even temporarly, because of RCU lookups. sk_node should also be left as is. | ||
925 | */ | ||
918 | static void sock_copy(struct sock *nsk, const struct sock *osk) | 926 | static void sock_copy(struct sock *nsk, const struct sock *osk) |
919 | { | 927 | { |
920 | #ifdef CONFIG_SECURITY_NETWORK | 928 | #ifdef CONFIG_SECURITY_NETWORK |
921 | void *sptr = nsk->sk_security; | 929 | void *sptr = nsk->sk_security; |
922 | #endif | 930 | #endif |
923 | 931 | BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) != | |
924 | memcpy(nsk, osk, osk->sk_prot->obj_size); | 932 | sizeof(osk->sk_node) + sizeof(osk->sk_refcnt)); |
933 | memcpy(&nsk->sk_copy_start, &osk->sk_copy_start, | ||
934 | osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start)); | ||
925 | #ifdef CONFIG_SECURITY_NETWORK | 935 | #ifdef CONFIG_SECURITY_NETWORK |
926 | nsk->sk_security = sptr; | 936 | nsk->sk_security = sptr; |
927 | security_sk_clone(osk, nsk); | 937 | security_sk_clone(osk, nsk); |
@@ -935,12 +945,29 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | |||
935 | struct kmem_cache *slab; | 945 | struct kmem_cache *slab; |
936 | 946 | ||
937 | slab = prot->slab; | 947 | slab = prot->slab; |
938 | if (slab != NULL) | 948 | if (slab != NULL) { |
939 | sk = kmem_cache_alloc(slab, priority); | 949 | sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); |
950 | if (!sk) | ||
951 | return sk; | ||
952 | if (priority & __GFP_ZERO) { | ||
953 | /* | ||
954 | * caches using SLAB_DESTROY_BY_RCU should let | ||
955 | * sk_node.next un-modified. Special care is taken | ||
956 | * when initializing object to zero. | ||
957 | */ | ||
958 | if (offsetof(struct sock, sk_node.next) != 0) | ||
959 | memset(sk, 0, offsetof(struct sock, sk_node.next)); | ||
960 | memset(&sk->sk_node.pprev, 0, | ||
961 | prot->obj_size - offsetof(struct sock, | ||
962 | sk_node.pprev)); | ||
963 | } | ||
964 | } | ||
940 | else | 965 | else |
941 | sk = kmalloc(prot->obj_size, priority); | 966 | sk = kmalloc(prot->obj_size, priority); |
942 | 967 | ||
943 | if (sk != NULL) { | 968 | if (sk != NULL) { |
969 | kmemcheck_annotate_bitfield(sk, flags); | ||
970 | |||
944 | if (security_sk_alloc(sk, family, priority)) | 971 | if (security_sk_alloc(sk, family, priority)) |
945 | goto out_free; | 972 | goto out_free; |
946 | 973 | ||
@@ -998,12 +1025,14 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
998 | sk->sk_prot = sk->sk_prot_creator = prot; | 1025 | sk->sk_prot = sk->sk_prot_creator = prot; |
999 | sock_lock_init(sk); | 1026 | sock_lock_init(sk); |
1000 | sock_net_set(sk, get_net(net)); | 1027 | sock_net_set(sk, get_net(net)); |
1028 | atomic_set(&sk->sk_wmem_alloc, 1); | ||
1001 | } | 1029 | } |
1002 | 1030 | ||
1003 | return sk; | 1031 | return sk; |
1004 | } | 1032 | } |
1033 | EXPORT_SYMBOL(sk_alloc); | ||
1005 | 1034 | ||
1006 | void sk_free(struct sock *sk) | 1035 | static void __sk_free(struct sock *sk) |
1007 | { | 1036 | { |
1008 | struct sk_filter *filter; | 1037 | struct sk_filter *filter; |
1009 | 1038 | ||
@@ -1027,6 +1056,18 @@ void sk_free(struct sock *sk) | |||
1027 | sk_prot_free(sk->sk_prot_creator, sk); | 1056 | sk_prot_free(sk->sk_prot_creator, sk); |
1028 | } | 1057 | } |
1029 | 1058 | ||
1059 | void sk_free(struct sock *sk) | ||
1060 | { | ||
1061 | /* | ||
1062 | * We substract one from sk_wmem_alloc and can know if | ||
1063 | * some packets are still in some tx queue. | ||
1064 | * If not null, sock_wfree() will call __sk_free(sk) later | ||
1065 | */ | ||
1066 | if (atomic_dec_and_test(&sk->sk_wmem_alloc)) | ||
1067 | __sk_free(sk); | ||
1068 | } | ||
1069 | EXPORT_SYMBOL(sk_free); | ||
1070 | |||
1030 | /* | 1071 | /* |
1031 | * Last sock_put should drop referrence to sk->sk_net. It has already | 1072 | * Last sock_put should drop referrence to sk->sk_net. It has already |
1032 | * been dropped in sk_change_net. Taking referrence to stopping namespace | 1073 | * been dropped in sk_change_net. Taking referrence to stopping namespace |
@@ -1065,7 +1106,10 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1065 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; | 1106 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; |
1066 | 1107 | ||
1067 | atomic_set(&newsk->sk_rmem_alloc, 0); | 1108 | atomic_set(&newsk->sk_rmem_alloc, 0); |
1068 | atomic_set(&newsk->sk_wmem_alloc, 0); | 1109 | /* |
1110 | * sk_wmem_alloc set to one (see sk_free() and sock_wfree()) | ||
1111 | */ | ||
1112 | atomic_set(&newsk->sk_wmem_alloc, 1); | ||
1069 | atomic_set(&newsk->sk_omem_alloc, 0); | 1113 | atomic_set(&newsk->sk_omem_alloc, 0); |
1070 | skb_queue_head_init(&newsk->sk_receive_queue); | 1114 | skb_queue_head_init(&newsk->sk_receive_queue); |
1071 | skb_queue_head_init(&newsk->sk_write_queue); | 1115 | skb_queue_head_init(&newsk->sk_write_queue); |
@@ -1103,6 +1147,11 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1103 | 1147 | ||
1104 | newsk->sk_err = 0; | 1148 | newsk->sk_err = 0; |
1105 | newsk->sk_priority = 0; | 1149 | newsk->sk_priority = 0; |
1150 | /* | ||
1151 | * Before updating sk_refcnt, we must commit prior changes to memory | ||
1152 | * (Documentation/RCU/rculist_nulls.txt for details) | ||
1153 | */ | ||
1154 | smp_wmb(); | ||
1106 | atomic_set(&newsk->sk_refcnt, 2); | 1155 | atomic_set(&newsk->sk_refcnt, 2); |
1107 | 1156 | ||
1108 | /* | 1157 | /* |
@@ -1126,7 +1175,6 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1126 | out: | 1175 | out: |
1127 | return newsk; | 1176 | return newsk; |
1128 | } | 1177 | } |
1129 | |||
1130 | EXPORT_SYMBOL_GPL(sk_clone); | 1178 | EXPORT_SYMBOL_GPL(sk_clone); |
1131 | 1179 | ||
1132 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) | 1180 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) |
@@ -1170,13 +1218,20 @@ void __init sk_init(void) | |||
1170 | void sock_wfree(struct sk_buff *skb) | 1218 | void sock_wfree(struct sk_buff *skb) |
1171 | { | 1219 | { |
1172 | struct sock *sk = skb->sk; | 1220 | struct sock *sk = skb->sk; |
1221 | int res; | ||
1173 | 1222 | ||
1174 | /* In case it might be waiting for more memory. */ | 1223 | /* In case it might be waiting for more memory. */ |
1175 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); | 1224 | res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); |
1176 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) | 1225 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) |
1177 | sk->sk_write_space(sk); | 1226 | sk->sk_write_space(sk); |
1178 | sock_put(sk); | 1227 | /* |
1228 | * if sk_wmem_alloc reached 0, we are last user and should | ||
1229 | * free this sock, as sk_free() call could not do it. | ||
1230 | */ | ||
1231 | if (res == 0) | ||
1232 | __sk_free(sk); | ||
1179 | } | 1233 | } |
1234 | EXPORT_SYMBOL(sock_wfree); | ||
1180 | 1235 | ||
1181 | /* | 1236 | /* |
1182 | * Read buffer destructor automatically called from kfree_skb. | 1237 | * Read buffer destructor automatically called from kfree_skb. |
@@ -1188,6 +1243,7 @@ void sock_rfree(struct sk_buff *skb) | |||
1188 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); | 1243 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); |
1189 | sk_mem_uncharge(skb->sk, skb->truesize); | 1244 | sk_mem_uncharge(skb->sk, skb->truesize); |
1190 | } | 1245 | } |
1246 | EXPORT_SYMBOL(sock_rfree); | ||
1191 | 1247 | ||
1192 | 1248 | ||
1193 | int sock_i_uid(struct sock *sk) | 1249 | int sock_i_uid(struct sock *sk) |
@@ -1199,6 +1255,7 @@ int sock_i_uid(struct sock *sk) | |||
1199 | read_unlock(&sk->sk_callback_lock); | 1255 | read_unlock(&sk->sk_callback_lock); |
1200 | return uid; | 1256 | return uid; |
1201 | } | 1257 | } |
1258 | EXPORT_SYMBOL(sock_i_uid); | ||
1202 | 1259 | ||
1203 | unsigned long sock_i_ino(struct sock *sk) | 1260 | unsigned long sock_i_ino(struct sock *sk) |
1204 | { | 1261 | { |
@@ -1209,6 +1266,7 @@ unsigned long sock_i_ino(struct sock *sk) | |||
1209 | read_unlock(&sk->sk_callback_lock); | 1266 | read_unlock(&sk->sk_callback_lock); |
1210 | return ino; | 1267 | return ino; |
1211 | } | 1268 | } |
1269 | EXPORT_SYMBOL(sock_i_ino); | ||
1212 | 1270 | ||
1213 | /* | 1271 | /* |
1214 | * Allocate a skb from the socket's send buffer. | 1272 | * Allocate a skb from the socket's send buffer. |
@@ -1217,7 +1275,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, | |||
1217 | gfp_t priority) | 1275 | gfp_t priority) |
1218 | { | 1276 | { |
1219 | if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { | 1277 | if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { |
1220 | struct sk_buff * skb = alloc_skb(size, priority); | 1278 | struct sk_buff *skb = alloc_skb(size, priority); |
1221 | if (skb) { | 1279 | if (skb) { |
1222 | skb_set_owner_w(skb, sk); | 1280 | skb_set_owner_w(skb, sk); |
1223 | return skb; | 1281 | return skb; |
@@ -1225,6 +1283,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, | |||
1225 | } | 1283 | } |
1226 | return NULL; | 1284 | return NULL; |
1227 | } | 1285 | } |
1286 | EXPORT_SYMBOL(sock_wmalloc); | ||
1228 | 1287 | ||
1229 | /* | 1288 | /* |
1230 | * Allocate a skb from the socket's receive buffer. | 1289 | * Allocate a skb from the socket's receive buffer. |
@@ -1261,6 +1320,7 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) | |||
1261 | } | 1320 | } |
1262 | return NULL; | 1321 | return NULL; |
1263 | } | 1322 | } |
1323 | EXPORT_SYMBOL(sock_kmalloc); | ||
1264 | 1324 | ||
1265 | /* | 1325 | /* |
1266 | * Free an option memory block. | 1326 | * Free an option memory block. |
@@ -1270,11 +1330,12 @@ void sock_kfree_s(struct sock *sk, void *mem, int size) | |||
1270 | kfree(mem); | 1330 | kfree(mem); |
1271 | atomic_sub(size, &sk->sk_omem_alloc); | 1331 | atomic_sub(size, &sk->sk_omem_alloc); |
1272 | } | 1332 | } |
1333 | EXPORT_SYMBOL(sock_kfree_s); | ||
1273 | 1334 | ||
1274 | /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. | 1335 | /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. |
1275 | I think, these locks should be removed for datagram sockets. | 1336 | I think, these locks should be removed for datagram sockets. |
1276 | */ | 1337 | */ |
1277 | static long sock_wait_for_wmem(struct sock * sk, long timeo) | 1338 | static long sock_wait_for_wmem(struct sock *sk, long timeo) |
1278 | { | 1339 | { |
1279 | DEFINE_WAIT(wait); | 1340 | DEFINE_WAIT(wait); |
1280 | 1341 | ||
@@ -1392,6 +1453,7 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, | |||
1392 | { | 1453 | { |
1393 | return sock_alloc_send_pskb(sk, size, 0, noblock, errcode); | 1454 | return sock_alloc_send_pskb(sk, size, 0, noblock, errcode); |
1394 | } | 1455 | } |
1456 | EXPORT_SYMBOL(sock_alloc_send_skb); | ||
1395 | 1457 | ||
1396 | static void __lock_sock(struct sock *sk) | 1458 | static void __lock_sock(struct sock *sk) |
1397 | { | 1459 | { |
@@ -1460,7 +1522,6 @@ int sk_wait_data(struct sock *sk, long *timeo) | |||
1460 | finish_wait(sk->sk_sleep, &wait); | 1522 | finish_wait(sk->sk_sleep, &wait); |
1461 | return rc; | 1523 | return rc; |
1462 | } | 1524 | } |
1463 | |||
1464 | EXPORT_SYMBOL(sk_wait_data); | 1525 | EXPORT_SYMBOL(sk_wait_data); |
1465 | 1526 | ||
1466 | /** | 1527 | /** |
@@ -1541,7 +1602,6 @@ suppress_allocation: | |||
1541 | atomic_sub(amt, prot->memory_allocated); | 1602 | atomic_sub(amt, prot->memory_allocated); |
1542 | return 0; | 1603 | return 0; |
1543 | } | 1604 | } |
1544 | |||
1545 | EXPORT_SYMBOL(__sk_mem_schedule); | 1605 | EXPORT_SYMBOL(__sk_mem_schedule); |
1546 | 1606 | ||
1547 | /** | 1607 | /** |
@@ -1560,7 +1620,6 @@ void __sk_mem_reclaim(struct sock *sk) | |||
1560 | (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) | 1620 | (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) |
1561 | *prot->memory_pressure = 0; | 1621 | *prot->memory_pressure = 0; |
1562 | } | 1622 | } |
1563 | |||
1564 | EXPORT_SYMBOL(__sk_mem_reclaim); | 1623 | EXPORT_SYMBOL(__sk_mem_reclaim); |
1565 | 1624 | ||
1566 | 1625 | ||
@@ -1575,78 +1634,92 @@ int sock_no_bind(struct socket *sock, struct sockaddr *saddr, int len) | |||
1575 | { | 1634 | { |
1576 | return -EOPNOTSUPP; | 1635 | return -EOPNOTSUPP; |
1577 | } | 1636 | } |
1637 | EXPORT_SYMBOL(sock_no_bind); | ||
1578 | 1638 | ||
1579 | int sock_no_connect(struct socket *sock, struct sockaddr *saddr, | 1639 | int sock_no_connect(struct socket *sock, struct sockaddr *saddr, |
1580 | int len, int flags) | 1640 | int len, int flags) |
1581 | { | 1641 | { |
1582 | return -EOPNOTSUPP; | 1642 | return -EOPNOTSUPP; |
1583 | } | 1643 | } |
1644 | EXPORT_SYMBOL(sock_no_connect); | ||
1584 | 1645 | ||
1585 | int sock_no_socketpair(struct socket *sock1, struct socket *sock2) | 1646 | int sock_no_socketpair(struct socket *sock1, struct socket *sock2) |
1586 | { | 1647 | { |
1587 | return -EOPNOTSUPP; | 1648 | return -EOPNOTSUPP; |
1588 | } | 1649 | } |
1650 | EXPORT_SYMBOL(sock_no_socketpair); | ||
1589 | 1651 | ||
1590 | int sock_no_accept(struct socket *sock, struct socket *newsock, int flags) | 1652 | int sock_no_accept(struct socket *sock, struct socket *newsock, int flags) |
1591 | { | 1653 | { |
1592 | return -EOPNOTSUPP; | 1654 | return -EOPNOTSUPP; |
1593 | } | 1655 | } |
1656 | EXPORT_SYMBOL(sock_no_accept); | ||
1594 | 1657 | ||
1595 | int sock_no_getname(struct socket *sock, struct sockaddr *saddr, | 1658 | int sock_no_getname(struct socket *sock, struct sockaddr *saddr, |
1596 | int *len, int peer) | 1659 | int *len, int peer) |
1597 | { | 1660 | { |
1598 | return -EOPNOTSUPP; | 1661 | return -EOPNOTSUPP; |
1599 | } | 1662 | } |
1663 | EXPORT_SYMBOL(sock_no_getname); | ||
1600 | 1664 | ||
1601 | unsigned int sock_no_poll(struct file * file, struct socket *sock, poll_table *pt) | 1665 | unsigned int sock_no_poll(struct file *file, struct socket *sock, poll_table *pt) |
1602 | { | 1666 | { |
1603 | return 0; | 1667 | return 0; |
1604 | } | 1668 | } |
1669 | EXPORT_SYMBOL(sock_no_poll); | ||
1605 | 1670 | ||
1606 | int sock_no_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 1671 | int sock_no_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
1607 | { | 1672 | { |
1608 | return -EOPNOTSUPP; | 1673 | return -EOPNOTSUPP; |
1609 | } | 1674 | } |
1675 | EXPORT_SYMBOL(sock_no_ioctl); | ||
1610 | 1676 | ||
1611 | int sock_no_listen(struct socket *sock, int backlog) | 1677 | int sock_no_listen(struct socket *sock, int backlog) |
1612 | { | 1678 | { |
1613 | return -EOPNOTSUPP; | 1679 | return -EOPNOTSUPP; |
1614 | } | 1680 | } |
1681 | EXPORT_SYMBOL(sock_no_listen); | ||
1615 | 1682 | ||
1616 | int sock_no_shutdown(struct socket *sock, int how) | 1683 | int sock_no_shutdown(struct socket *sock, int how) |
1617 | { | 1684 | { |
1618 | return -EOPNOTSUPP; | 1685 | return -EOPNOTSUPP; |
1619 | } | 1686 | } |
1687 | EXPORT_SYMBOL(sock_no_shutdown); | ||
1620 | 1688 | ||
1621 | int sock_no_setsockopt(struct socket *sock, int level, int optname, | 1689 | int sock_no_setsockopt(struct socket *sock, int level, int optname, |
1622 | char __user *optval, int optlen) | 1690 | char __user *optval, int optlen) |
1623 | { | 1691 | { |
1624 | return -EOPNOTSUPP; | 1692 | return -EOPNOTSUPP; |
1625 | } | 1693 | } |
1694 | EXPORT_SYMBOL(sock_no_setsockopt); | ||
1626 | 1695 | ||
1627 | int sock_no_getsockopt(struct socket *sock, int level, int optname, | 1696 | int sock_no_getsockopt(struct socket *sock, int level, int optname, |
1628 | char __user *optval, int __user *optlen) | 1697 | char __user *optval, int __user *optlen) |
1629 | { | 1698 | { |
1630 | return -EOPNOTSUPP; | 1699 | return -EOPNOTSUPP; |
1631 | } | 1700 | } |
1701 | EXPORT_SYMBOL(sock_no_getsockopt); | ||
1632 | 1702 | ||
1633 | int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | 1703 | int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, |
1634 | size_t len) | 1704 | size_t len) |
1635 | { | 1705 | { |
1636 | return -EOPNOTSUPP; | 1706 | return -EOPNOTSUPP; |
1637 | } | 1707 | } |
1708 | EXPORT_SYMBOL(sock_no_sendmsg); | ||
1638 | 1709 | ||
1639 | int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | 1710 | int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, |
1640 | size_t len, int flags) | 1711 | size_t len, int flags) |
1641 | { | 1712 | { |
1642 | return -EOPNOTSUPP; | 1713 | return -EOPNOTSUPP; |
1643 | } | 1714 | } |
1715 | EXPORT_SYMBOL(sock_no_recvmsg); | ||
1644 | 1716 | ||
1645 | int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma) | 1717 | int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma) |
1646 | { | 1718 | { |
1647 | /* Mirror missing mmap method error code */ | 1719 | /* Mirror missing mmap method error code */ |
1648 | return -ENODEV; | 1720 | return -ENODEV; |
1649 | } | 1721 | } |
1722 | EXPORT_SYMBOL(sock_no_mmap); | ||
1650 | 1723 | ||
1651 | ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) | 1724 | ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) |
1652 | { | 1725 | { |
@@ -1660,6 +1733,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz | |||
1660 | kunmap(page); | 1733 | kunmap(page); |
1661 | return res; | 1734 | return res; |
1662 | } | 1735 | } |
1736 | EXPORT_SYMBOL(sock_no_sendpage); | ||
1663 | 1737 | ||
1664 | /* | 1738 | /* |
1665 | * Default Socket Callbacks | 1739 | * Default Socket Callbacks |
@@ -1668,7 +1742,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz | |||
1668 | static void sock_def_wakeup(struct sock *sk) | 1742 | static void sock_def_wakeup(struct sock *sk) |
1669 | { | 1743 | { |
1670 | read_lock(&sk->sk_callback_lock); | 1744 | read_lock(&sk->sk_callback_lock); |
1671 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 1745 | if (sk_has_sleeper(sk)) |
1672 | wake_up_interruptible_all(sk->sk_sleep); | 1746 | wake_up_interruptible_all(sk->sk_sleep); |
1673 | read_unlock(&sk->sk_callback_lock); | 1747 | read_unlock(&sk->sk_callback_lock); |
1674 | } | 1748 | } |
@@ -1676,7 +1750,7 @@ static void sock_def_wakeup(struct sock *sk) | |||
1676 | static void sock_def_error_report(struct sock *sk) | 1750 | static void sock_def_error_report(struct sock *sk) |
1677 | { | 1751 | { |
1678 | read_lock(&sk->sk_callback_lock); | 1752 | read_lock(&sk->sk_callback_lock); |
1679 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 1753 | if (sk_has_sleeper(sk)) |
1680 | wake_up_interruptible_poll(sk->sk_sleep, POLLERR); | 1754 | wake_up_interruptible_poll(sk->sk_sleep, POLLERR); |
1681 | sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); | 1755 | sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); |
1682 | read_unlock(&sk->sk_callback_lock); | 1756 | read_unlock(&sk->sk_callback_lock); |
@@ -1685,7 +1759,7 @@ static void sock_def_error_report(struct sock *sk) | |||
1685 | static void sock_def_readable(struct sock *sk, int len) | 1759 | static void sock_def_readable(struct sock *sk, int len) |
1686 | { | 1760 | { |
1687 | read_lock(&sk->sk_callback_lock); | 1761 | read_lock(&sk->sk_callback_lock); |
1688 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 1762 | if (sk_has_sleeper(sk)) |
1689 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | | 1763 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | |
1690 | POLLRDNORM | POLLRDBAND); | 1764 | POLLRDNORM | POLLRDBAND); |
1691 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | 1765 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); |
@@ -1700,7 +1774,7 @@ static void sock_def_write_space(struct sock *sk) | |||
1700 | * progress. --DaveM | 1774 | * progress. --DaveM |
1701 | */ | 1775 | */ |
1702 | if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) { | 1776 | if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) { |
1703 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 1777 | if (sk_has_sleeper(sk)) |
1704 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT | | 1778 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT | |
1705 | POLLWRNORM | POLLWRBAND); | 1779 | POLLWRNORM | POLLWRBAND); |
1706 | 1780 | ||
@@ -1723,6 +1797,7 @@ void sk_send_sigurg(struct sock *sk) | |||
1723 | if (send_sigurg(&sk->sk_socket->file->f_owner)) | 1797 | if (send_sigurg(&sk->sk_socket->file->f_owner)) |
1724 | sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI); | 1798 | sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI); |
1725 | } | 1799 | } |
1800 | EXPORT_SYMBOL(sk_send_sigurg); | ||
1726 | 1801 | ||
1727 | void sk_reset_timer(struct sock *sk, struct timer_list* timer, | 1802 | void sk_reset_timer(struct sock *sk, struct timer_list* timer, |
1728 | unsigned long expires) | 1803 | unsigned long expires) |
@@ -1730,7 +1805,6 @@ void sk_reset_timer(struct sock *sk, struct timer_list* timer, | |||
1730 | if (!mod_timer(timer, expires)) | 1805 | if (!mod_timer(timer, expires)) |
1731 | sock_hold(sk); | 1806 | sock_hold(sk); |
1732 | } | 1807 | } |
1733 | |||
1734 | EXPORT_SYMBOL(sk_reset_timer); | 1808 | EXPORT_SYMBOL(sk_reset_timer); |
1735 | 1809 | ||
1736 | void sk_stop_timer(struct sock *sk, struct timer_list* timer) | 1810 | void sk_stop_timer(struct sock *sk, struct timer_list* timer) |
@@ -1738,7 +1812,6 @@ void sk_stop_timer(struct sock *sk, struct timer_list* timer) | |||
1738 | if (timer_pending(timer) && del_timer(timer)) | 1812 | if (timer_pending(timer) && del_timer(timer)) |
1739 | __sock_put(sk); | 1813 | __sock_put(sk); |
1740 | } | 1814 | } |
1741 | |||
1742 | EXPORT_SYMBOL(sk_stop_timer); | 1815 | EXPORT_SYMBOL(sk_stop_timer); |
1743 | 1816 | ||
1744 | void sock_init_data(struct socket *sock, struct sock *sk) | 1817 | void sock_init_data(struct socket *sock, struct sock *sk) |
@@ -1794,9 +1867,15 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1794 | 1867 | ||
1795 | sk->sk_stamp = ktime_set(-1L, 0); | 1868 | sk->sk_stamp = ktime_set(-1L, 0); |
1796 | 1869 | ||
1870 | /* | ||
1871 | * Before updating sk_refcnt, we must commit prior changes to memory | ||
1872 | * (Documentation/RCU/rculist_nulls.txt for details) | ||
1873 | */ | ||
1874 | smp_wmb(); | ||
1797 | atomic_set(&sk->sk_refcnt, 1); | 1875 | atomic_set(&sk->sk_refcnt, 1); |
1798 | atomic_set(&sk->sk_drops, 0); | 1876 | atomic_set(&sk->sk_drops, 0); |
1799 | } | 1877 | } |
1878 | EXPORT_SYMBOL(sock_init_data); | ||
1800 | 1879 | ||
1801 | void lock_sock_nested(struct sock *sk, int subclass) | 1880 | void lock_sock_nested(struct sock *sk, int subclass) |
1802 | { | 1881 | { |
@@ -1812,7 +1891,6 @@ void lock_sock_nested(struct sock *sk, int subclass) | |||
1812 | mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); | 1891 | mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); |
1813 | local_bh_enable(); | 1892 | local_bh_enable(); |
1814 | } | 1893 | } |
1815 | |||
1816 | EXPORT_SYMBOL(lock_sock_nested); | 1894 | EXPORT_SYMBOL(lock_sock_nested); |
1817 | 1895 | ||
1818 | void release_sock(struct sock *sk) | 1896 | void release_sock(struct sock *sk) |
@@ -1895,7 +1973,6 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname, | |||
1895 | 1973 | ||
1896 | return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); | 1974 | return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); |
1897 | } | 1975 | } |
1898 | |||
1899 | EXPORT_SYMBOL(sock_common_getsockopt); | 1976 | EXPORT_SYMBOL(sock_common_getsockopt); |
1900 | 1977 | ||
1901 | #ifdef CONFIG_COMPAT | 1978 | #ifdef CONFIG_COMPAT |
@@ -1925,7 +2002,6 @@ int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1925 | msg->msg_namelen = addr_len; | 2002 | msg->msg_namelen = addr_len; |
1926 | return err; | 2003 | return err; |
1927 | } | 2004 | } |
1928 | |||
1929 | EXPORT_SYMBOL(sock_common_recvmsg); | 2005 | EXPORT_SYMBOL(sock_common_recvmsg); |
1930 | 2006 | ||
1931 | /* | 2007 | /* |
@@ -1938,7 +2014,6 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname, | |||
1938 | 2014 | ||
1939 | return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); | 2015 | return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); |
1940 | } | 2016 | } |
1941 | |||
1942 | EXPORT_SYMBOL(sock_common_setsockopt); | 2017 | EXPORT_SYMBOL(sock_common_setsockopt); |
1943 | 2018 | ||
1944 | #ifdef CONFIG_COMPAT | 2019 | #ifdef CONFIG_COMPAT |
@@ -1989,7 +2064,6 @@ void sk_common_release(struct sock *sk) | |||
1989 | sk_refcnt_debug_release(sk); | 2064 | sk_refcnt_debug_release(sk); |
1990 | sock_put(sk); | 2065 | sock_put(sk); |
1991 | } | 2066 | } |
1992 | |||
1993 | EXPORT_SYMBOL(sk_common_release); | 2067 | EXPORT_SYMBOL(sk_common_release); |
1994 | 2068 | ||
1995 | static DEFINE_RWLOCK(proto_list_lock); | 2069 | static DEFINE_RWLOCK(proto_list_lock); |
@@ -2171,7 +2245,6 @@ out_free_sock_slab: | |||
2171 | out: | 2245 | out: |
2172 | return -ENOBUFS; | 2246 | return -ENOBUFS; |
2173 | } | 2247 | } |
2174 | |||
2175 | EXPORT_SYMBOL(proto_register); | 2248 | EXPORT_SYMBOL(proto_register); |
2176 | 2249 | ||
2177 | void proto_unregister(struct proto *prot) | 2250 | void proto_unregister(struct proto *prot) |
@@ -2198,7 +2271,6 @@ void proto_unregister(struct proto *prot) | |||
2198 | prot->twsk_prot->twsk_slab = NULL; | 2271 | prot->twsk_prot->twsk_slab = NULL; |
2199 | } | 2272 | } |
2200 | } | 2273 | } |
2201 | |||
2202 | EXPORT_SYMBOL(proto_unregister); | 2274 | EXPORT_SYMBOL(proto_unregister); |
2203 | 2275 | ||
2204 | #ifdef CONFIG_PROC_FS | 2276 | #ifdef CONFIG_PROC_FS |
@@ -2324,33 +2396,3 @@ static int __init proto_init(void) | |||
2324 | subsys_initcall(proto_init); | 2396 | subsys_initcall(proto_init); |
2325 | 2397 | ||
2326 | #endif /* PROC_FS */ | 2398 | #endif /* PROC_FS */ |
2327 | |||
2328 | EXPORT_SYMBOL(sk_alloc); | ||
2329 | EXPORT_SYMBOL(sk_free); | ||
2330 | EXPORT_SYMBOL(sk_send_sigurg); | ||
2331 | EXPORT_SYMBOL(sock_alloc_send_skb); | ||
2332 | EXPORT_SYMBOL(sock_init_data); | ||
2333 | EXPORT_SYMBOL(sock_kfree_s); | ||
2334 | EXPORT_SYMBOL(sock_kmalloc); | ||
2335 | EXPORT_SYMBOL(sock_no_accept); | ||
2336 | EXPORT_SYMBOL(sock_no_bind); | ||
2337 | EXPORT_SYMBOL(sock_no_connect); | ||
2338 | EXPORT_SYMBOL(sock_no_getname); | ||
2339 | EXPORT_SYMBOL(sock_no_getsockopt); | ||
2340 | EXPORT_SYMBOL(sock_no_ioctl); | ||
2341 | EXPORT_SYMBOL(sock_no_listen); | ||
2342 | EXPORT_SYMBOL(sock_no_mmap); | ||
2343 | EXPORT_SYMBOL(sock_no_poll); | ||
2344 | EXPORT_SYMBOL(sock_no_recvmsg); | ||
2345 | EXPORT_SYMBOL(sock_no_sendmsg); | ||
2346 | EXPORT_SYMBOL(sock_no_sendpage); | ||
2347 | EXPORT_SYMBOL(sock_no_setsockopt); | ||
2348 | EXPORT_SYMBOL(sock_no_shutdown); | ||
2349 | EXPORT_SYMBOL(sock_no_socketpair); | ||
2350 | EXPORT_SYMBOL(sock_rfree); | ||
2351 | EXPORT_SYMBOL(sock_setsockopt); | ||
2352 | EXPORT_SYMBOL(sock_wfree); | ||
2353 | EXPORT_SYMBOL(sock_wmalloc); | ||
2354 | EXPORT_SYMBOL(sock_i_uid); | ||
2355 | EXPORT_SYMBOL(sock_i_ino); | ||
2356 | EXPORT_SYMBOL(sysctl_optmem_max); | ||