aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/sock.c')
-rw-r--r--net/core/sock.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 524712a7b154..7626b6aacd68 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -446,7 +446,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
446 */ 446 */
447 447
448int sock_setsockopt(struct socket *sock, int level, int optname, 448int sock_setsockopt(struct socket *sock, int level, int optname,
449 char __user *optval, int optlen) 449 char __user *optval, unsigned int optlen)
450{ 450{
451 struct sock *sk = sock->sk; 451 struct sock *sk = sock->sk;
452 int val; 452 int val;
@@ -1228,17 +1228,22 @@ void __init sk_init(void)
1228void sock_wfree(struct sk_buff *skb) 1228void sock_wfree(struct sk_buff *skb)
1229{ 1229{
1230 struct sock *sk = skb->sk; 1230 struct sock *sk = skb->sk;
1231 int res; 1231 unsigned int len = skb->truesize;
1232 1232
1233 /* In case it might be waiting for more memory. */ 1233 if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
1234 res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); 1234 /*
1235 if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) 1235 * Keep a reference on sk_wmem_alloc, this will be released
1236 * after sk_write_space() call
1237 */
1238 atomic_sub(len - 1, &sk->sk_wmem_alloc);
1236 sk->sk_write_space(sk); 1239 sk->sk_write_space(sk);
1240 len = 1;
1241 }
1237 /* 1242 /*
1238 * if sk_wmem_alloc reached 0, we are last user and should 1243 * if sk_wmem_alloc reaches 0, we must finish what sk_free()
1239 * free this sock, as sk_free() call could not do it. 1244 * could not do because of in-flight packets
1240 */ 1245 */
1241 if (res == 0) 1246 if (atomic_sub_and_test(len, &sk->sk_wmem_alloc))
1242 __sk_free(sk); 1247 __sk_free(sk);
1243} 1248}
1244EXPORT_SYMBOL(sock_wfree); 1249EXPORT_SYMBOL(sock_wfree);
@@ -1697,7 +1702,7 @@ int sock_no_shutdown(struct socket *sock, int how)
1697EXPORT_SYMBOL(sock_no_shutdown); 1702EXPORT_SYMBOL(sock_no_shutdown);
1698 1703
1699int sock_no_setsockopt(struct socket *sock, int level, int optname, 1704int sock_no_setsockopt(struct socket *sock, int level, int optname,
1700 char __user *optval, int optlen) 1705 char __user *optval, unsigned int optlen)
1701{ 1706{
1702 return -EOPNOTSUPP; 1707 return -EOPNOTSUPP;
1703} 1708}
@@ -2018,7 +2023,7 @@ EXPORT_SYMBOL(sock_common_recvmsg);
2018 * Set socket options on an inet socket. 2023 * Set socket options on an inet socket.
2019 */ 2024 */
2020int sock_common_setsockopt(struct socket *sock, int level, int optname, 2025int sock_common_setsockopt(struct socket *sock, int level, int optname,
2021 char __user *optval, int optlen) 2026 char __user *optval, unsigned int optlen)
2022{ 2027{
2023 struct sock *sk = sock->sk; 2028 struct sock *sk = sock->sk;
2024 2029
@@ -2028,7 +2033,7 @@ EXPORT_SYMBOL(sock_common_setsockopt);
2028 2033
2029#ifdef CONFIG_COMPAT 2034#ifdef CONFIG_COMPAT
2030int compat_sock_common_setsockopt(struct socket *sock, int level, int optname, 2035int compat_sock_common_setsockopt(struct socket *sock, int level, int optname,
2031 char __user *optval, int optlen) 2036 char __user *optval, unsigned int optlen)
2032{ 2037{
2033 struct sock *sk = sock->sk; 2038 struct sock *sk = sock->sk;
2034 2039