瀏覽代碼

Merge branch 'kernel_socket_netns'

Eric W. Biederman says:

====================
Cleanup the kernel sockets.

Right now the situtation for allocating kernel sockets is a mess.
- sock_create_kern does not take a namespace parameter.
- kernel sockets must not reference count a network namespace and keep
  it alive or else we will have a reference counting loop.
- The way we avoid the reference counting loop with sk_change_net
  and sk_release_kernel are major hacks.

This patchset addresses this mess by fixing sock_create_kern to do
everything necessary to create a kernel socket.  None of the current
users of kernel sockets need the network namespace reference counted.
Either kernel sockets are network namespace aware (and using the current
hacks) or kernel sockets are limited to the initial network namespace
in which case it does not matter.

This patchset starts by addressing tun which should be using normal
userspace sockets like macvtap.

Then sock_create_kern is fixed to take a network namespace.
Then the in kernel status of sockets are passed through to sk_alloc.
Then sk_alloc is fixed to not reference count the network namespace
     of kernel sockets.
Then the callers of sock_create_kern are fixed up to stop using hacks.
Then netlink which uses it's own flavor of sock_create_kern is fixed.

Finally the hacks that are sk_change_net and sk_release_kernel are removed.

When it is all done the code is easier to follow, easier to use, easier
to maintain and shorter by about 70 lines.
====================

Reported-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 10 年之前
父節點
當前提交
0198e09c4b
共有 72 個文件被更改,包括 166 次插入238 次删除
  1. 2 2
      crypto/af_alg.c
  2. 2 2
      drivers/block/drbd/drbd_receiver.c
  3. 6 6
      drivers/isdn/mISDN/socket.c
  4. 1 1
      drivers/net/macvtap.c
  5. 2 2
      drivers/net/ppp/pppoe.c
  6. 1 1
      drivers/net/ppp/pppox.c
  7. 2 2
      drivers/net/ppp/pptp.c
  8. 5 21
      drivers/net/tun.c
  9. 1 1
      fs/afs/rxrpc.c
  10. 8 8
      fs/dlm/lowcomms.c
  11. 1 1
      include/linux/if_pppox.h
  12. 1 2
      include/linux/net.h
  13. 1 1
      include/net/af_vsock.h
  14. 1 1
      include/net/inet_common.h
  15. 1 1
      include/net/llc_conn.h
  16. 3 18
      include/net/sock.h
  17. 1 1
      net/appletalk/ddp.c
  18. 2 2
      net/atm/common.c
  19. 1 1
      net/atm/common.h
  20. 1 1
      net/atm/pvc.c
  21. 1 1
      net/atm/svc.c
  22. 2 2
      net/ax25/af_ax25.c
  23. 1 1
      net/bluetooth/bnep/sock.c
  24. 1 1
      net/bluetooth/cmtp/sock.c
  25. 1 1
      net/bluetooth/hci_sock.c
  26. 1 1
      net/bluetooth/hidp/sock.c
  27. 5 5
      net/bluetooth/l2cap_sock.c
  28. 1 1
      net/bluetooth/rfcomm/core.c
  29. 4 4
      net/bluetooth/rfcomm/sock.c
  30. 4 4
      net/bluetooth/sco.c
  31. 1 1
      net/caif/caif_socket.c
  32. 1 1
      net/can/af_can.c
  33. 2 2
      net/ceph/messenger.c
  34. 8 22
      net/core/sock.c
  35. 4 4
      net/decnet/af_decnet.c
  36. 1 1
      net/ieee802154/socket.c
  37. 2 4
      net/ipv4/af_inet.c
  38. 3 5
      net/ipv4/udp_tunnel.c
  39. 1 1
      net/ipv6/af_inet6.c
  40. 2 4
      net/ipv6/ip6_udp_tunnel.c
  41. 1 1
      net/ipx/af_ipx.c
  42. 1 1
      net/irda/af_irda.c
  43. 5 5
      net/iucv/af_iucv.c
  44. 1 1
      net/key/af_key.c
  45. 6 9
      net/l2tp/l2tp_core.c
  46. 2 2
      net/l2tp/l2tp_ppp.c
  47. 1 1
      net/llc/af_llc.c
  48. 3 3
      net/llc/llc_conn.c
  49. 9 21
      net/netfilter/ipvs/ip_vs_sync.c
  50. 9 12
      net/netlink/af_netlink.c
  51. 2 2
      net/netrom/af_netrom.c
  52. 1 1
      net/nfc/af_nfc.c
  53. 1 1
      net/nfc/llcp.h
  54. 1 1
      net/nfc/llcp_core.c
  55. 4 4
      net/nfc/llcp_sock.c
  56. 1 1
      net/nfc/nfc.h
  57. 2 2
      net/nfc/rawsock.c
  58. 1 1
      net/packet/af_packet.c
  59. 1 1
      net/phonet/af_phonet.c
  60. 1 1
      net/phonet/pep.c
  61. 1 1
      net/rds/af_rds.c
  62. 2 2
      net/rose/af_rose.c
  63. 1 1
      net/rxrpc/af_rxrpc.c
  64. 2 2
      net/rxrpc/ar-local.c
  65. 1 1
      net/sctp/ipv6.c
  66. 1 1
      net/sctp/protocol.c
  67. 2 5
      net/socket.c
  68. 1 1
      net/tipc/socket.c
  69. 4 4
      net/unix/af_unix.c
  70. 4 3
      net/vmw_vsock/af_vsock.c
  71. 1 1
      net/vmw_vsock/vmci_transport.c
  72. 4 4
      net/x25/af_x25.c

+ 2 - 2
crypto/af_alg.c

@@ -244,7 +244,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
 	if (!type)
 	if (!type)
 		goto unlock;
 		goto unlock;
 
 
-	sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto);
+	sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto, 0);
 	err = -ENOMEM;
 	err = -ENOMEM;
 	if (!sk2)
 	if (!sk2)
 		goto unlock;
 		goto unlock;
@@ -324,7 +324,7 @@ static int alg_create(struct net *net, struct socket *sock, int protocol,
 		return -EPROTONOSUPPORT;
 		return -EPROTONOSUPPORT;
 
 
 	err = -ENOMEM;
 	err = -ENOMEM;
-	sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto);
+	sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 

+ 2 - 2
drivers/block/drbd/drbd_receiver.c

@@ -598,7 +598,7 @@ static struct socket *drbd_try_connect(struct drbd_connection *connection)
 	memcpy(&peer_in6, &connection->peer_addr, peer_addr_len);
 	memcpy(&peer_in6, &connection->peer_addr, peer_addr_len);
 
 
 	what = "sock_create_kern";
 	what = "sock_create_kern";
-	err = sock_create_kern(((struct sockaddr *)&src_in6)->sa_family,
+	err = sock_create_kern(&init_net, ((struct sockaddr *)&src_in6)->sa_family,
 			       SOCK_STREAM, IPPROTO_TCP, &sock);
 			       SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (err < 0) {
 	if (err < 0) {
 		sock = NULL;
 		sock = NULL;
@@ -693,7 +693,7 @@ static int prepare_listen_socket(struct drbd_connection *connection, struct acce
 	memcpy(&my_addr, &connection->my_addr, my_addr_len);
 	memcpy(&my_addr, &connection->my_addr, my_addr_len);
 
 
 	what = "sock_create_kern";
 	what = "sock_create_kern";
-	err = sock_create_kern(((struct sockaddr *)&my_addr)->sa_family,
+	err = sock_create_kern(&init_net, ((struct sockaddr *)&my_addr)->sa_family,
 			       SOCK_STREAM, IPPROTO_TCP, &s_listen);
 			       SOCK_STREAM, IPPROTO_TCP, &s_listen);
 	if (err) {
 	if (err) {
 		s_listen = NULL;
 		s_listen = NULL;

+ 6 - 6
drivers/isdn/mISDN/socket.c

@@ -601,14 +601,14 @@ static const struct proto_ops data_sock_ops = {
 };
 };
 
 
 static int
 static int
-data_sock_create(struct net *net, struct socket *sock, int protocol)
+data_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
 	if (sock->type != SOCK_DGRAM)
 	if (sock->type != SOCK_DGRAM)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto);
+	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -756,14 +756,14 @@ static const struct proto_ops base_sock_ops = {
 
 
 
 
 static int
 static int
-base_sock_create(struct net *net, struct socket *sock, int protocol)
+base_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
 	if (sock->type != SOCK_RAW)
 	if (sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto);
+	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -785,7 +785,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
 
 
 	switch (proto) {
 	switch (proto) {
 	case ISDN_P_BASE:
 	case ISDN_P_BASE:
-		err = base_sock_create(net, sock, proto);
+		err = base_sock_create(net, sock, proto, kern);
 		break;
 		break;
 	case ISDN_P_TE_S0:
 	case ISDN_P_TE_S0:
 	case ISDN_P_NT_S0:
 	case ISDN_P_NT_S0:
@@ -799,7 +799,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
 	case ISDN_P_B_L2DTMF:
 	case ISDN_P_B_L2DTMF:
 	case ISDN_P_B_L2DSP:
 	case ISDN_P_B_L2DSP:
 	case ISDN_P_B_L2DSPHDLC:
 	case ISDN_P_B_L2DSPHDLC:
-		err = data_sock_create(net, sock, proto);
+		err = data_sock_create(net, sock, proto, kern);
 		break;
 		break;
 	default:
 	default:
 		return err;
 		return err;

+ 1 - 1
drivers/net/macvtap.c

@@ -476,7 +476,7 @@ static int macvtap_open(struct inode *inode, struct file *file)
 
 
 	err = -ENOMEM;
 	err = -ENOMEM;
 	q = (struct macvtap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
 	q = (struct macvtap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
-					     &macvtap_proto);
+					     &macvtap_proto, 0);
 	if (!q)
 	if (!q)
 		goto out;
 		goto out;
 
 

+ 2 - 2
drivers/net/ppp/pppoe.c

@@ -546,11 +546,11 @@ static struct proto pppoe_sk_proto __read_mostly = {
  * Initialize a new struct sock.
  * Initialize a new struct sock.
  *
  *
  **********************************************************************/
  **********************************************************************/
-static int pppoe_create(struct net *net, struct socket *sock)
+static int pppoe_create(struct net *net, struct socket *sock, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
-	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto);
+	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
drivers/net/ppp/pppox.c

@@ -118,7 +118,7 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol,
 	    !try_module_get(pppox_protos[protocol]->owner))
 	    !try_module_get(pppox_protos[protocol]->owner))
 		goto out;
 		goto out;
 
 
-	rc = pppox_protos[protocol]->create(net, sock);
+	rc = pppox_protos[protocol]->create(net, sock, kern);
 
 
 	module_put(pppox_protos[protocol]->owner);
 	module_put(pppox_protos[protocol]->owner);
 out:
 out:

+ 2 - 2
drivers/net/ppp/pptp.c

@@ -561,14 +561,14 @@ static void pptp_sock_destruct(struct sock *sk)
 	skb_queue_purge(&sk->sk_receive_queue);
 	skb_queue_purge(&sk->sk_receive_queue);
 }
 }
 
 
-static int pptp_create(struct net *net, struct socket *sock)
+static int pptp_create(struct net *net, struct socket *sock, int kern)
 {
 {
 	int error = -ENOMEM;
 	int error = -ENOMEM;
 	struct sock *sk;
 	struct sock *sk;
 	struct pppox_sock *po;
 	struct pppox_sock *po;
 	struct pptp_opt *opt;
 	struct pptp_opt *opt;
 
 
-	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto);
+	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 

+ 5 - 21
drivers/net/tun.c

@@ -146,7 +146,6 @@ struct tun_file {
 	struct socket socket;
 	struct socket socket;
 	struct socket_wq wq;
 	struct socket_wq wq;
 	struct tun_struct __rcu *tun;
 	struct tun_struct __rcu *tun;
-	struct net *net;
 	struct fasync_struct *fasync;
 	struct fasync_struct *fasync;
 	/* only used for fasnyc */
 	/* only used for fasnyc */
 	unsigned int flags;
 	unsigned int flags;
@@ -493,10 +492,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
 			    tun->dev->reg_state == NETREG_REGISTERED)
 			    tun->dev->reg_state == NETREG_REGISTERED)
 				unregister_netdevice(tun->dev);
 				unregister_netdevice(tun->dev);
 		}
 		}
-
-		BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED,
-				 &tfile->socket.flags));
-		sk_release_kernel(&tfile->sk);
+		sock_put(&tfile->sk);
 	}
 	}
 }
 }
 
 
@@ -1492,18 +1488,10 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
-static int tun_release(struct socket *sock)
-{
-	if (sock->sk)
-		sock_put(sock->sk);
-	return 0;
-}
-
 /* Ops structure to mimic raw sockets with tun */
 /* Ops structure to mimic raw sockets with tun */
 static const struct proto_ops tun_socket_ops = {
 static const struct proto_ops tun_socket_ops = {
 	.sendmsg = tun_sendmsg,
 	.sendmsg = tun_sendmsg,
 	.recvmsg = tun_recvmsg,
 	.recvmsg = tun_recvmsg,
-	.release = tun_release,
 };
 };
 
 
 static struct proto tun_proto = {
 static struct proto tun_proto = {
@@ -1865,7 +1853,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 	if (cmd == TUNSETIFF && !tun) {
 	if (cmd == TUNSETIFF && !tun) {
 		ifr.ifr_name[IFNAMSIZ-1] = '\0';
 		ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
 
-		ret = tun_set_iff(tfile->net, file, &ifr);
+		ret = tun_set_iff(sock_net(&tfile->sk), file, &ifr);
 
 
 		if (ret)
 		if (ret)
 			goto unlock;
 			goto unlock;
@@ -2154,16 +2142,16 @@ out:
 
 
 static int tun_chr_open(struct inode *inode, struct file * file)
 static int tun_chr_open(struct inode *inode, struct file * file)
 {
 {
+	struct net *net = current->nsproxy->net_ns;
 	struct tun_file *tfile;
 	struct tun_file *tfile;
 
 
 	DBG1(KERN_INFO, "tunX: tun_chr_open\n");
 	DBG1(KERN_INFO, "tunX: tun_chr_open\n");
 
 
-	tfile = (struct tun_file *)sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL,
-					    &tun_proto);
+	tfile = (struct tun_file *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
+					    &tun_proto, 0);
 	if (!tfile)
 	if (!tfile)
 		return -ENOMEM;
 		return -ENOMEM;
 	RCU_INIT_POINTER(tfile->tun, NULL);
 	RCU_INIT_POINTER(tfile->tun, NULL);
-	tfile->net = get_net(current->nsproxy->net_ns);
 	tfile->flags = 0;
 	tfile->flags = 0;
 	tfile->ifindex = 0;
 	tfile->ifindex = 0;
 
 
@@ -2174,13 +2162,11 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 	tfile->socket.ops = &tun_socket_ops;
 	tfile->socket.ops = &tun_socket_ops;
 
 
 	sock_init_data(&tfile->socket, &tfile->sk);
 	sock_init_data(&tfile->socket, &tfile->sk);
-	sk_change_net(&tfile->sk, tfile->net);
 
 
 	tfile->sk.sk_write_space = tun_sock_write_space;
 	tfile->sk.sk_write_space = tun_sock_write_space;
 	tfile->sk.sk_sndbuf = INT_MAX;
 	tfile->sk.sk_sndbuf = INT_MAX;
 
 
 	file->private_data = tfile;
 	file->private_data = tfile;
-	set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags);
 	INIT_LIST_HEAD(&tfile->next);
 	INIT_LIST_HEAD(&tfile->next);
 
 
 	sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
 	sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
@@ -2191,10 +2177,8 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 static int tun_chr_close(struct inode *inode, struct file *file)
 static int tun_chr_close(struct inode *inode, struct file *file)
 {
 {
 	struct tun_file *tfile = file->private_data;
 	struct tun_file *tfile = file->private_data;
-	struct net *net = tfile->net;
 
 
 	tun_detach(tfile, true);
 	tun_detach(tfile, true);
-	put_net(net);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 1
fs/afs/rxrpc.c

@@ -85,7 +85,7 @@ int afs_open_socket(void)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	ret = sock_create_kern(AF_RXRPC, SOCK_DGRAM, PF_INET, &socket);
+	ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET, &socket);
 	if (ret < 0) {
 	if (ret < 0) {
 		destroy_workqueue(afs_async_calls);
 		destroy_workqueue(afs_async_calls);
 		_leave(" = %d [socket]", ret);
 		_leave(" = %d [socket]", ret);

+ 8 - 8
fs/dlm/lowcomms.c

@@ -921,8 +921,8 @@ static int tcp_accept_from_sock(struct connection *con)
 	mutex_unlock(&connections_lock);
 	mutex_unlock(&connections_lock);
 
 
 	memset(&peeraddr, 0, sizeof(peeraddr));
 	memset(&peeraddr, 0, sizeof(peeraddr));
-	result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
-				  IPPROTO_TCP, &newsock);
+	result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
+				  SOCK_STREAM, IPPROTO_TCP, &newsock);
 	if (result < 0)
 	if (result < 0)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1173,8 +1173,8 @@ static void tcp_connect_to_sock(struct connection *con)
 		goto out;
 		goto out;
 
 
 	/* Create a socket to communicate with */
 	/* Create a socket to communicate with */
-	result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
-				  IPPROTO_TCP, &sock);
+	result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
+				  SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (result < 0)
 	if (result < 0)
 		goto out_err;
 		goto out_err;
 
 
@@ -1258,8 +1258,8 @@ static struct socket *tcp_create_listen_sock(struct connection *con,
 		addr_len = sizeof(struct sockaddr_in6);
 		addr_len = sizeof(struct sockaddr_in6);
 
 
 	/* Create a socket to communicate with */
 	/* Create a socket to communicate with */
-	result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
-				  IPPROTO_TCP, &sock);
+	result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
+				  SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (result < 0) {
 	if (result < 0) {
 		log_print("Can't create listening comms socket");
 		log_print("Can't create listening comms socket");
 		goto create_out;
 		goto create_out;
@@ -1365,8 +1365,8 @@ static int sctp_listen_for_all(void)
 
 
 	log_print("Using SCTP for communications");
 	log_print("Using SCTP for communications");
 
 
-	result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_SEQPACKET,
-				  IPPROTO_SCTP, &sock);
+	result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
+				  SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
 	if (result < 0) {
 	if (result < 0) {
 		log_print("Can't create comms socket, check SCTP is loaded");
 		log_print("Can't create comms socket, check SCTP is loaded");
 		goto out;
 		goto out;

+ 1 - 1
include/linux/if_pppox.h

@@ -74,7 +74,7 @@ static inline struct sock *sk_pppox(struct pppox_sock *po)
 struct module;
 struct module;
 
 
 struct pppox_proto {
 struct pppox_proto {
-	int		(*create)(struct net *net, struct socket *sock);
+	int		(*create)(struct net *net, struct socket *sock, int kern);
 	int		(*ioctl)(struct socket *sock, unsigned int cmd,
 	int		(*ioctl)(struct socket *sock, unsigned int cmd,
 				 unsigned long arg);
 				 unsigned long arg);
 	struct module	*owner;
 	struct module	*owner;

+ 1 - 2
include/linux/net.h

@@ -38,7 +38,6 @@ struct net;
 #define SOCK_NOSPACE		2
 #define SOCK_NOSPACE		2
 #define SOCK_PASSCRED		3
 #define SOCK_PASSCRED		3
 #define SOCK_PASSSEC		4
 #define SOCK_PASSSEC		4
-#define SOCK_EXTERNALLY_ALLOCATED 5
 
 
 #ifndef ARCH_HAS_SOCKET_TYPES
 #ifndef ARCH_HAS_SOCKET_TYPES
 /**
 /**
@@ -208,7 +207,7 @@ void sock_unregister(int family);
 int __sock_create(struct net *net, int family, int type, int proto,
 int __sock_create(struct net *net, int family, int type, int proto,
 		  struct socket **res, int kern);
 		  struct socket **res, int kern);
 int sock_create(int family, int type, int proto, struct socket **res);
 int sock_create(int family, int type, int proto, struct socket **res);
-int sock_create_kern(int family, int type, int proto, struct socket **res);
+int sock_create_kern(struct net *net, int family, int type, int proto, struct socket **res);
 int sock_create_lite(int family, int type, int proto, struct socket **res);
 int sock_create_lite(int family, int type, int proto, struct socket **res);
 void sock_release(struct socket *sock);
 void sock_release(struct socket *sock);
 int sock_sendmsg(struct socket *sock, struct msghdr *msg);
 int sock_sendmsg(struct socket *sock, struct msghdr *msg);

+ 1 - 1
include/net/af_vsock.h

@@ -74,7 +74,7 @@ void vsock_pending_work(struct work_struct *work);
 struct sock *__vsock_create(struct net *net,
 struct sock *__vsock_create(struct net *net,
 			    struct socket *sock,
 			    struct socket *sock,
 			    struct sock *parent,
 			    struct sock *parent,
-			    gfp_t priority, unsigned short type);
+			    gfp_t priority, unsigned short type, int kern);
 
 
 /**** TRANSPORT ****/
 /**** TRANSPORT ****/
 
 

+ 1 - 1
include/net/inet_common.h

@@ -41,7 +41,7 @@ int inet_recv_error(struct sock *sk, struct msghdr *msg, int len,
 
 
 static inline void inet_ctl_sock_destroy(struct sock *sk)
 static inline void inet_ctl_sock_destroy(struct sock *sk)
 {
 {
-	sk_release_kernel(sk);
+	sock_release(sk->sk_socket);
 }
 }
 
 
 #endif
 #endif

+ 1 - 1
include/net/llc_conn.h

@@ -96,7 +96,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
 }
 }
 
 
 struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
 struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
-			  struct proto *prot);
+			  struct proto *prot, int kern);
 void llc_sk_free(struct sock *sk);
 void llc_sk_free(struct sock *sk);
 
 
 void llc_sk_reset(struct sock *sk);
 void llc_sk_reset(struct sock *sk);

+ 3 - 18
include/net/sock.h

@@ -184,6 +184,7 @@ struct sock_common {
 	unsigned char		skc_reuse:4;
 	unsigned char		skc_reuse:4;
 	unsigned char		skc_reuseport:1;
 	unsigned char		skc_reuseport:1;
 	unsigned char		skc_ipv6only:1;
 	unsigned char		skc_ipv6only:1;
+	unsigned char		skc_net_refcnt:1;
 	int			skc_bound_dev_if;
 	int			skc_bound_dev_if;
 	union {
 	union {
 		struct hlist_node	skc_bind_node;
 		struct hlist_node	skc_bind_node;
@@ -323,6 +324,7 @@ struct sock {
 #define sk_reuse		__sk_common.skc_reuse
 #define sk_reuse		__sk_common.skc_reuse
 #define sk_reuseport		__sk_common.skc_reuseport
 #define sk_reuseport		__sk_common.skc_reuseport
 #define sk_ipv6only		__sk_common.skc_ipv6only
 #define sk_ipv6only		__sk_common.skc_ipv6only
+#define sk_net_refcnt		__sk_common.skc_net_refcnt
 #define sk_bound_dev_if		__sk_common.skc_bound_dev_if
 #define sk_bound_dev_if		__sk_common.skc_bound_dev_if
 #define sk_bind_node		__sk_common.skc_bind_node
 #define sk_bind_node		__sk_common.skc_bind_node
 #define sk_prot			__sk_common.skc_prot
 #define sk_prot			__sk_common.skc_prot
@@ -1514,9 +1516,8 @@ static inline void unlock_sock_fast(struct sock *sk, bool slow)
 
 
 
 
 struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
 struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
-		      struct proto *prot);
+		      struct proto *prot, int kern);
 void sk_free(struct sock *sk);
 void sk_free(struct sock *sk);
-void sk_release_kernel(struct sock *sk);
 struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
 struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
 
 
 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
@@ -2192,22 +2193,6 @@ void sock_net_set(struct sock *sk, struct net *net)
 	write_pnet(&sk->sk_net, net);
 	write_pnet(&sk->sk_net, net);
 }
 }
 
 
-/*
- * Kernel sockets, f.e. rtnl or icmp_socket, are a part of a namespace.
- * They should not hold a reference to a namespace in order to allow
- * to stop it.
- * Sockets after sk_change_net should be released using sk_release_kernel
- */
-static inline void sk_change_net(struct sock *sk, struct net *net)
-{
-	struct net *current_net = sock_net(sk);
-
-	if (!net_eq(current_net, net)) {
-		put_net(current_net);
-		sock_net_set(sk, net);
-	}
-}
-
 static inline struct sock *skb_steal_sock(struct sk_buff *skb)
 static inline struct sock *skb_steal_sock(struct sk_buff *skb)
 {
 {
 	if (skb->sk) {
 	if (skb->sk) {

+ 1 - 1
net/appletalk/ddp.c

@@ -1030,7 +1030,7 @@ static int atalk_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
 	if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
 		goto out;
 		goto out;
 	rc = -ENOMEM;
 	rc = -ENOMEM;
-	sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto);
+	sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 	rc = 0;
 	rc = 0;

+ 2 - 2
net/atm/common.c

@@ -141,7 +141,7 @@ static struct proto vcc_proto = {
 	.release_cb = vcc_release_cb,
 	.release_cb = vcc_release_cb,
 };
 };
 
 
-int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
+int vcc_create(struct net *net, struct socket *sock, int protocol, int family, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct atm_vcc *vcc;
 	struct atm_vcc *vcc;
@@ -149,7 +149,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
 	sock->sk = NULL;
 	sock->sk = NULL;
 	if (sock->type == SOCK_STREAM)
 	if (sock->type == SOCK_STREAM)
 		return -EINVAL;
 		return -EINVAL;
-	sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto);
+	sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 	sock_init_data(sock, sk);
 	sock_init_data(sock, sk);

+ 1 - 1
net/atm/common.h

@@ -10,7 +10,7 @@
 #include <linux/poll.h> /* for poll_table */
 #include <linux/poll.h> /* for poll_table */
 
 
 
 
-int vcc_create(struct net *net, struct socket *sock, int protocol, int family);
+int vcc_create(struct net *net, struct socket *sock, int protocol, int family, int kern);
 int vcc_release(struct socket *sock);
 int vcc_release(struct socket *sock);
 int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
 int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
 int vcc_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 int vcc_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,

+ 1 - 1
net/atm/pvc.c

@@ -136,7 +136,7 @@ static int pvc_create(struct net *net, struct socket *sock, int protocol,
 		return -EAFNOSUPPORT;
 		return -EAFNOSUPPORT;
 
 
 	sock->ops = &pvc_proto_ops;
 	sock->ops = &pvc_proto_ops;
-	return vcc_create(net, sock, protocol, PF_ATMPVC);
+	return vcc_create(net, sock, protocol, PF_ATMPVC, kern);
 }
 }
 
 
 static const struct net_proto_family pvc_family_ops = {
 static const struct net_proto_family pvc_family_ops = {

+ 1 - 1
net/atm/svc.c

@@ -660,7 +660,7 @@ static int svc_create(struct net *net, struct socket *sock, int protocol,
 		return -EAFNOSUPPORT;
 		return -EAFNOSUPPORT;
 
 
 	sock->ops = &svc_proto_ops;
 	sock->ops = &svc_proto_ops;
-	error = vcc_create(net, sock, protocol, AF_ATMSVC);
+	error = vcc_create(net, sock, protocol, AF_ATMSVC, kern);
 	if (error)
 	if (error)
 		return error;
 		return error;
 	ATM_SD(sock)->local.sas_family = AF_ATMSVC;
 	ATM_SD(sock)->local.sas_family = AF_ATMSVC;

+ 2 - 2
net/ax25/af_ax25.c

@@ -855,7 +855,7 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol,
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 	}
 	}
 
 
-	sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto);
+	sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -881,7 +881,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
 	struct sock *sk;
 	struct sock *sk;
 	ax25_cb *ax25, *oax25;
 	ax25_cb *ax25, *oax25;
 
 
-	sk = sk_alloc(sock_net(osk), PF_AX25, GFP_ATOMIC,	osk->sk_prot);
+	sk = sk_alloc(sock_net(osk), PF_AX25, GFP_ATOMIC, osk->sk_prot, 0);
 	if (sk == NULL)
 	if (sk == NULL)
 		return NULL;
 		return NULL;
 
 

+ 1 - 1
net/bluetooth/bnep/sock.c

@@ -202,7 +202,7 @@ static int bnep_sock_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_RAW)
 	if (sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/bluetooth/cmtp/sock.c

@@ -205,7 +205,7 @@ static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_RAW)
 	if (sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/bluetooth/hci_sock.c

@@ -1377,7 +1377,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
 
 
 	sock->ops = &hci_sock_ops;
 	sock->ops = &hci_sock_ops;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/bluetooth/hidp/sock.c

@@ -235,7 +235,7 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_RAW)
 	if (sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 5 - 5
net/bluetooth/l2cap_sock.c

@@ -43,7 +43,7 @@ static struct bt_sock_list l2cap_sk_list = {
 static const struct proto_ops l2cap_sock_ops;
 static const struct proto_ops l2cap_sock_ops;
 static void l2cap_sock_init(struct sock *sk, struct sock *parent);
 static void l2cap_sock_init(struct sock *sk, struct sock *parent);
 static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
 static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
-				     int proto, gfp_t prio);
+				     int proto, gfp_t prio, int kern);
 
 
 bool l2cap_is_socket(struct socket *sock)
 bool l2cap_is_socket(struct socket *sock)
 {
 {
@@ -1193,7 +1193,7 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
 	}
 	}
 
 
 	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
 	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
-			      GFP_ATOMIC);
+			      GFP_ATOMIC, 0);
 	if (!sk) {
 	if (!sk) {
 		release_sock(parent);
 		release_sock(parent);
 		return NULL;
 		return NULL;
@@ -1523,12 +1523,12 @@ static struct proto l2cap_proto = {
 };
 };
 
 
 static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
 static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
-				     int proto, gfp_t prio)
+				     int proto, gfp_t prio, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct l2cap_chan *chan;
 	struct l2cap_chan *chan;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, kern);
 	if (!sk)
 	if (!sk)
 		return NULL;
 		return NULL;
 
 
@@ -1574,7 +1574,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
 
 
 	sock->ops = &l2cap_sock_ops;
 	sock->ops = &l2cap_sock_ops;
 
 
-	sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+	sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/bluetooth/rfcomm/core.c

@@ -200,7 +200,7 @@ static int rfcomm_l2sock_create(struct socket **sock)
 
 
 	BT_DBG("");
 	BT_DBG("");
 
 
-	err = sock_create_kern(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
+	err = sock_create_kern(&init_net, PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
 	if (!err) {
 	if (!err) {
 		struct sock *sk = (*sock)->sk;
 		struct sock *sk = (*sock)->sk;
 		sk->sk_data_ready   = rfcomm_l2data_ready;
 		sk->sk_data_ready   = rfcomm_l2data_ready;

+ 4 - 4
net/bluetooth/rfcomm/sock.c

@@ -269,12 +269,12 @@ static struct proto rfcomm_proto = {
 	.obj_size	= sizeof(struct rfcomm_pinfo)
 	.obj_size	= sizeof(struct rfcomm_pinfo)
 };
 };
 
 
-static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
+static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio, int kern)
 {
 {
 	struct rfcomm_dlc *d;
 	struct rfcomm_dlc *d;
 	struct sock *sk;
 	struct sock *sk;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, kern);
 	if (!sk)
 	if (!sk)
 		return NULL;
 		return NULL;
 
 
@@ -324,7 +324,7 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock,
 
 
 	sock->ops = &rfcomm_sock_ops;
 	sock->ops = &rfcomm_sock_ops;
 
 
-	sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+	sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -969,7 +969,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
 		goto done;
 		goto done;
 	}
 	}
 
 
-	sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
+	sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC, 0);
 	if (!sk)
 	if (!sk)
 		goto done;
 		goto done;
 
 

+ 4 - 4
net/bluetooth/sco.c

@@ -460,11 +460,11 @@ static struct proto sco_proto = {
 	.obj_size	= sizeof(struct sco_pinfo)
 	.obj_size	= sizeof(struct sco_pinfo)
 };
 };
 
 
-static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
+static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
-	sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto);
+	sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, kern);
 	if (!sk)
 	if (!sk)
 		return NULL;
 		return NULL;
 
 
@@ -501,7 +501,7 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
 
 
 	sock->ops = &sco_sock_ops;
 	sock->ops = &sco_sock_ops;
 
 
-	sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+	sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1026,7 +1026,7 @@ static void sco_conn_ready(struct sco_conn *conn)
 		bh_lock_sock(parent);
 		bh_lock_sock(parent);
 
 
 		sk = sco_sock_alloc(sock_net(parent), NULL,
 		sk = sco_sock_alloc(sock_net(parent), NULL,
-				    BTPROTO_SCO, GFP_ATOMIC);
+				    BTPROTO_SCO, GFP_ATOMIC, 0);
 		if (!sk) {
 		if (!sk) {
 			bh_unlock_sock(parent);
 			bh_unlock_sock(parent);
 			sco_conn_unlock(conn);
 			sco_conn_unlock(conn);

+ 1 - 1
net/caif/caif_socket.c

@@ -1047,7 +1047,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
 	 * is really not used at all in the net/core or socket.c but the
 	 * is really not used at all in the net/core or socket.c but the
 	 * initialization makes sure that sock->state is not uninitialized.
 	 * initialization makes sure that sock->state is not uninitialized.
 	 */
 	 */
-	sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot);
+	sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/can/af_can.c

@@ -179,7 +179,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
 
 
 	sock->ops = cp->ops;
 	sock->ops = cp->ops;
 
 
-	sk = sk_alloc(net, PF_CAN, GFP_KERNEL, cp->prot);
+	sk = sk_alloc(net, PF_CAN, GFP_KERNEL, cp->prot, kern);
 	if (!sk) {
 	if (!sk) {
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto errout;
 		goto errout;

+ 2 - 2
net/ceph/messenger.c

@@ -480,8 +480,8 @@ static int ceph_tcp_connect(struct ceph_connection *con)
 	int ret;
 	int ret;
 
 
 	BUG_ON(con->sock);
 	BUG_ON(con->sock);
-	ret = sock_create_kern(con->peer_addr.in_addr.ss_family, SOCK_STREAM,
-			       IPPROTO_TCP, &sock);
+	ret = sock_create_kern(&init_net, con->peer_addr.in_addr.ss_family,
+			       SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 	sock->sk->sk_allocation = GFP_NOFS;
 	sock->sk->sk_allocation = GFP_NOFS;

+ 8 - 22
net/core/sock.c

@@ -1396,9 +1396,10 @@ EXPORT_SYMBOL_GPL(sock_update_netprioidx);
  *	@family: protocol family
  *	@family: protocol family
  *	@priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
  *	@priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
  *	@prot: struct proto associated with this new sock instance
  *	@prot: struct proto associated with this new sock instance
+ *	@kern: is this to be a kernel socket?
  */
  */
 struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
 struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
-		      struct proto *prot)
+		      struct proto *prot, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
@@ -1411,7 +1412,10 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
 		 */
 		 */
 		sk->sk_prot = sk->sk_prot_creator = prot;
 		sk->sk_prot = sk->sk_prot_creator = prot;
 		sock_lock_init(sk);
 		sock_lock_init(sk);
-		sock_net_set(sk, get_net(net));
+		sk->sk_net_refcnt = kern ? 0 : 1;
+		if (likely(sk->sk_net_refcnt))
+			get_net(net);
+		sock_net_set(sk, net);
 		atomic_set(&sk->sk_wmem_alloc, 1);
 		atomic_set(&sk->sk_wmem_alloc, 1);
 
 
 		sock_update_classid(sk);
 		sock_update_classid(sk);
@@ -1445,7 +1449,8 @@ static void __sk_free(struct sock *sk)
 	if (sk->sk_peer_cred)
 	if (sk->sk_peer_cred)
 		put_cred(sk->sk_peer_cred);
 		put_cred(sk->sk_peer_cred);
 	put_pid(sk->sk_peer_pid);
 	put_pid(sk->sk_peer_pid);
-	put_net(sock_net(sk));
+	if (likely(sk->sk_net_refcnt))
+		put_net(sock_net(sk));
 	sk_prot_free(sk->sk_prot_creator, sk);
 	sk_prot_free(sk->sk_prot_creator, sk);
 }
 }
 
 
@@ -1461,25 +1466,6 @@ void sk_free(struct sock *sk)
 }
 }
 EXPORT_SYMBOL(sk_free);
 EXPORT_SYMBOL(sk_free);
 
 
-/*
- * Last sock_put should drop reference to sk->sk_net. It has already
- * been dropped in sk_change_net. Taking reference to stopping namespace
- * is not an option.
- * Take reference to a socket to remove it from hash _alive_ and after that
- * destroy it in the context of init_net.
- */
-void sk_release_kernel(struct sock *sk)
-{
-	if (sk == NULL || sk->sk_socket == NULL)
-		return;
-
-	sock_hold(sk);
-	sock_net_set(sk, get_net(&init_net));
-	sock_release(sk->sk_socket);
-	sock_put(sk);
-}
-EXPORT_SYMBOL(sk_release_kernel);
-
 static void sk_update_clone(const struct sock *sk, struct sock *newsk)
 static void sk_update_clone(const struct sock *sk, struct sock *newsk)
 {
 {
 	if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
 	if (mem_cgroup_sockets_enabled && sk->sk_cgrp)

+ 4 - 4
net/decnet/af_decnet.c

@@ -468,10 +468,10 @@ static struct proto dn_proto = {
 	.obj_size		= sizeof(struct dn_sock),
 	.obj_size		= sizeof(struct dn_sock),
 };
 };
 
 
-static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp)
+static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp, int kern)
 {
 {
 	struct dn_scp *scp;
 	struct dn_scp *scp;
-	struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto);
+	struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, kern);
 
 
 	if  (!sk)
 	if  (!sk)
 		goto out;
 		goto out;
@@ -693,7 +693,7 @@ static int dn_create(struct net *net, struct socket *sock, int protocol,
 	}
 	}
 
 
 
 
-	if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL)) == NULL)
+	if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL, kern)) == NULL)
 		return -ENOBUFS;
 		return -ENOBUFS;
 
 
 	sk->sk_protocol = protocol;
 	sk->sk_protocol = protocol;
@@ -1096,7 +1096,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
 
 
 	cb = DN_SKB_CB(skb);
 	cb = DN_SKB_CB(skb);
 	sk->sk_ack_backlog--;
 	sk->sk_ack_backlog--;
-	newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation);
+	newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation, 0);
 	if (newsk == NULL) {
 	if (newsk == NULL) {
 		release_sock(sk);
 		release_sock(sk);
 		kfree_skb(skb);
 		kfree_skb(skb);

+ 1 - 1
net/ieee802154/socket.c

@@ -1014,7 +1014,7 @@ static int ieee802154_create(struct net *net, struct socket *sock,
 	}
 	}
 
 
 	rc = -ENOMEM;
 	rc = -ENOMEM;
-	sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto);
+	sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 	rc = 0;
 	rc = 0;

+ 2 - 4
net/ipv4/af_inet.c

@@ -317,7 +317,7 @@ lookup_protocol:
 	WARN_ON(!answer_prot->slab);
 	WARN_ON(!answer_prot->slab);
 
 
 	err = -ENOBUFS;
 	err = -ENOBUFS;
-	sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
+	sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 
@@ -1430,7 +1430,7 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family,
 			 struct net *net)
 			 struct net *net)
 {
 {
 	struct socket *sock;
 	struct socket *sock;
-	int rc = sock_create_kern(family, type, protocol, &sock);
+	int rc = sock_create_kern(net, family, type, protocol, &sock);
 
 
 	if (rc == 0) {
 	if (rc == 0) {
 		*sk = sock->sk;
 		*sk = sock->sk;
@@ -1440,8 +1440,6 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family,
 		 * we do not wish this socket to see incoming packets.
 		 * we do not wish this socket to see incoming packets.
 		 */
 		 */
 		(*sk)->sk_prot->unhash(*sk);
 		(*sk)->sk_prot->unhash(*sk);
-
-		sk_change_net(*sk, net);
 	}
 	}
 	return rc;
 	return rc;
 }
 }

+ 3 - 5
net/ipv4/udp_tunnel.c

@@ -15,12 +15,10 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
 	struct socket *sock = NULL;
 	struct socket *sock = NULL;
 	struct sockaddr_in udp_addr;
 	struct sockaddr_in udp_addr;
 
 
-	err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
+	err = sock_create_kern(net, AF_INET, SOCK_DGRAM, 0, &sock);
 	if (err < 0)
 	if (err < 0)
 		goto error;
 		goto error;
 
 
-	sk_change_net(sock->sk, net);
-
 	udp_addr.sin_family = AF_INET;
 	udp_addr.sin_family = AF_INET;
 	udp_addr.sin_addr = cfg->local_ip;
 	udp_addr.sin_addr = cfg->local_ip;
 	udp_addr.sin_port = cfg->local_udp_port;
 	udp_addr.sin_port = cfg->local_udp_port;
@@ -47,7 +45,7 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
 error:
 error:
 	if (sock) {
 	if (sock) {
 		kernel_sock_shutdown(sock, SHUT_RDWR);
 		kernel_sock_shutdown(sock, SHUT_RDWR);
-		sk_release_kernel(sock->sk);
+		sock_release(sock);
 	}
 	}
 	*sockp = NULL;
 	*sockp = NULL;
 	return err;
 	return err;
@@ -101,7 +99,7 @@ void udp_tunnel_sock_release(struct socket *sock)
 {
 {
 	rcu_assign_sk_user_data(sock->sk, NULL);
 	rcu_assign_sk_user_data(sock->sk, NULL);
 	kernel_sock_shutdown(sock, SHUT_RDWR);
 	kernel_sock_shutdown(sock, SHUT_RDWR);
-	sk_release_kernel(sock->sk);
+	sock_release(sock);
 }
 }
 EXPORT_SYMBOL_GPL(udp_tunnel_sock_release);
 EXPORT_SYMBOL_GPL(udp_tunnel_sock_release);
 
 

+ 1 - 1
net/ipv6/af_inet6.c

@@ -167,7 +167,7 @@ lookup_protocol:
 	WARN_ON(!answer_prot->slab);
 	WARN_ON(!answer_prot->slab);
 
 
 	err = -ENOBUFS;
 	err = -ENOBUFS;
-	sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot);
+	sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 

+ 2 - 4
net/ipv6/ip6_udp_tunnel.c

@@ -19,12 +19,10 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
 	int err;
 	int err;
 	struct socket *sock = NULL;
 	struct socket *sock = NULL;
 
 
-	err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
+	err = sock_create_kern(net, AF_INET6, SOCK_DGRAM, 0, &sock);
 	if (err < 0)
 	if (err < 0)
 		goto error;
 		goto error;
 
 
-	sk_change_net(sock->sk, net);
-
 	udp6_addr.sin6_family = AF_INET6;
 	udp6_addr.sin6_family = AF_INET6;
 	memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
 	memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
 	       sizeof(udp6_addr.sin6_addr));
 	       sizeof(udp6_addr.sin6_addr));
@@ -55,7 +53,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
 error:
 error:
 	if (sock) {
 	if (sock) {
 		kernel_sock_shutdown(sock, SHUT_RDWR);
 		kernel_sock_shutdown(sock, SHUT_RDWR);
-		sk_release_kernel(sock->sk);
+		sock_release(sock);
 	}
 	}
 	*sockp = NULL;
 	*sockp = NULL;
 	return err;
 	return err;

+ 1 - 1
net/ipx/af_ipx.c

@@ -1347,7 +1347,7 @@ static int ipx_create(struct net *net, struct socket *sock, int protocol,
 		goto out;
 		goto out;
 
 
 	rc = -ENOMEM;
 	rc = -ENOMEM;
-	sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto);
+	sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 

+ 1 - 1
net/irda/af_irda.c

@@ -1100,7 +1100,7 @@ static int irda_create(struct net *net, struct socket *sock, int protocol,
 	}
 	}
 
 
 	/* Allocate networking socket */
 	/* Allocate networking socket */
-	sk = sk_alloc(net, PF_IRDA, GFP_KERNEL, &irda_proto);
+	sk = sk_alloc(net, PF_IRDA, GFP_KERNEL, &irda_proto, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 5 - 5
net/iucv/af_iucv.c

@@ -535,12 +535,12 @@ static void iucv_sock_init(struct sock *sk, struct sock *parent)
 		sk->sk_type = parent->sk_type;
 		sk->sk_type = parent->sk_type;
 }
 }
 
 
-static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct iucv_sock *iucv;
 	struct iucv_sock *iucv;
 
 
-	sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto);
+	sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto, kern);
 	if (!sk)
 	if (!sk)
 		return NULL;
 		return NULL;
 	iucv = iucv_sk(sk);
 	iucv = iucv_sk(sk);
@@ -602,7 +602,7 @@ static int iucv_sock_create(struct net *net, struct socket *sock, int protocol,
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 	}
 	}
 
 
-	sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL);
+	sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1723,7 +1723,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
 	}
 	}
 
 
 	/* Create the new socket */
 	/* Create the new socket */
-	nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
+	nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0);
 	if (!nsk) {
 	if (!nsk) {
 		err = pr_iucv->path_sever(path, user_data);
 		err = pr_iucv->path_sever(path, user_data);
 		iucv_path_free(path);
 		iucv_path_free(path);
@@ -1933,7 +1933,7 @@ static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
+	nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0);
 	bh_lock_sock(sk);
 	bh_lock_sock(sk);
 	if ((sk->sk_state != IUCV_LISTEN) ||
 	if ((sk->sk_state != IUCV_LISTEN) ||
 	    sk_acceptq_is_full(sk) ||
 	    sk_acceptq_is_full(sk) ||

+ 1 - 1
net/key/af_key.c

@@ -149,7 +149,7 @@ static int pfkey_create(struct net *net, struct socket *sock, int protocol,
 		return -EPROTONOSUPPORT;
 		return -EPROTONOSUPPORT;
 
 
 	err = -ENOMEM;
 	err = -ENOMEM;
-	sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto);
+	sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		goto out;
 		goto out;
 
 

+ 6 - 9
net/l2tp/l2tp_core.c

@@ -1334,9 +1334,10 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
 		if (sock)
 		if (sock)
 			inet_shutdown(sock, 2);
 			inet_shutdown(sock, 2);
 	} else {
 	} else {
-		if (sock)
+		if (sock) {
 			kernel_sock_shutdown(sock, SHUT_RDWR);
 			kernel_sock_shutdown(sock, SHUT_RDWR);
-		sk_release_kernel(sk);
+			sock_release(sock);
+		}
 	}
 	}
 
 
 	l2tp_tunnel_sock_put(sk);
 	l2tp_tunnel_sock_put(sk);
@@ -1399,13 +1400,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
 		if (cfg->local_ip6 && cfg->peer_ip6) {
 		if (cfg->local_ip6 && cfg->peer_ip6) {
 			struct sockaddr_l2tpip6 ip6_addr = {0};
 			struct sockaddr_l2tpip6 ip6_addr = {0};
 
 
-			err = sock_create_kern(AF_INET6, SOCK_DGRAM,
+			err = sock_create_kern(net, AF_INET6, SOCK_DGRAM,
 					  IPPROTO_L2TP, &sock);
 					  IPPROTO_L2TP, &sock);
 			if (err < 0)
 			if (err < 0)
 				goto out;
 				goto out;
 
 
-			sk_change_net(sock->sk, net);
-
 			ip6_addr.l2tp_family = AF_INET6;
 			ip6_addr.l2tp_family = AF_INET6;
 			memcpy(&ip6_addr.l2tp_addr, cfg->local_ip6,
 			memcpy(&ip6_addr.l2tp_addr, cfg->local_ip6,
 			       sizeof(ip6_addr.l2tp_addr));
 			       sizeof(ip6_addr.l2tp_addr));
@@ -1429,13 +1428,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
 		{
 		{
 			struct sockaddr_l2tpip ip_addr = {0};
 			struct sockaddr_l2tpip ip_addr = {0};
 
 
-			err = sock_create_kern(AF_INET, SOCK_DGRAM,
+			err = sock_create_kern(net, AF_INET, SOCK_DGRAM,
 					  IPPROTO_L2TP, &sock);
 					  IPPROTO_L2TP, &sock);
 			if (err < 0)
 			if (err < 0)
 				goto out;
 				goto out;
 
 
-			sk_change_net(sock->sk, net);
-
 			ip_addr.l2tp_family = AF_INET;
 			ip_addr.l2tp_family = AF_INET;
 			ip_addr.l2tp_addr = cfg->local_ip;
 			ip_addr.l2tp_addr = cfg->local_ip;
 			ip_addr.l2tp_conn_id = tunnel_id;
 			ip_addr.l2tp_conn_id = tunnel_id;
@@ -1462,7 +1459,7 @@ out:
 	*sockp = sock;
 	*sockp = sock;
 	if ((err < 0) && sock) {
 	if ((err < 0) && sock) {
 		kernel_sock_shutdown(sock, SHUT_RDWR);
 		kernel_sock_shutdown(sock, SHUT_RDWR);
-		sk_release_kernel(sock->sk);
+		sock_release(sock);
 		*sockp = NULL;
 		*sockp = NULL;
 	}
 	}
 
 

+ 2 - 2
net/l2tp/l2tp_ppp.c

@@ -542,12 +542,12 @@ static int pppol2tp_backlog_recv(struct sock *sk, struct sk_buff *skb)
 
 
 /* socket() handler. Initialize a new struct sock.
 /* socket() handler. Initialize a new struct sock.
  */
  */
-static int pppol2tp_create(struct net *net, struct socket *sock)
+static int pppol2tp_create(struct net *net, struct socket *sock, int kern)
 {
 {
 	int error = -ENOMEM;
 	int error = -ENOMEM;
 	struct sock *sk;
 	struct sock *sk;
 
 
-	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto);
+	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 

+ 1 - 1
net/llc/af_llc.c

@@ -168,7 +168,7 @@ static int llc_ui_create(struct net *net, struct socket *sock, int protocol,
 
 
 	if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
 	if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
 		rc = -ENOMEM;
 		rc = -ENOMEM;
-		sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto);
+		sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto, kern);
 		if (sk) {
 		if (sk) {
 			rc = 0;
 			rc = 0;
 			llc_ui_sk_init(sock, sk);
 			llc_ui_sk_init(sock, sk);

+ 3 - 3
net/llc/llc_conn.c

@@ -768,7 +768,7 @@ static struct sock *llc_create_incoming_sock(struct sock *sk,
 					     struct llc_addr *daddr)
 					     struct llc_addr *daddr)
 {
 {
 	struct sock *newsk = llc_sk_alloc(sock_net(sk), sk->sk_family, GFP_ATOMIC,
 	struct sock *newsk = llc_sk_alloc(sock_net(sk), sk->sk_family, GFP_ATOMIC,
-					  sk->sk_prot);
+					  sk->sk_prot, 0);
 	struct llc_sock *newllc, *llc = llc_sk(sk);
 	struct llc_sock *newllc, *llc = llc_sk(sk);
 
 
 	if (!newsk)
 	if (!newsk)
@@ -931,9 +931,9 @@ static void llc_sk_init(struct sock *sk)
  *	Allocates a LLC sock and initializes it. Returns the new LLC sock
  *	Allocates a LLC sock and initializes it. Returns the new LLC sock
  *	or %NULL if there's no memory available for one
  *	or %NULL if there's no memory available for one
  */
  */
-struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot)
+struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot, int kern)
 {
 {
-	struct sock *sk = sk_alloc(net, family, priority, prot);
+	struct sock *sk = sk_alloc(net, family, priority, prot, kern);
 
 
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;

+ 9 - 21
net/netfilter/ipvs/ip_vs_sync.c

@@ -1457,18 +1457,12 @@ static struct socket *make_send_sock(struct net *net, int id)
 	struct socket *sock;
 	struct socket *sock;
 	int result;
 	int result;
 
 
-	/* First create a socket move it to right name space later */
-	result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
+	/* First create a socket */
+	result = sock_create_kern(net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
 	if (result < 0) {
 	if (result < 0) {
 		pr_err("Error during creation of socket; terminating\n");
 		pr_err("Error during creation of socket; terminating\n");
 		return ERR_PTR(result);
 		return ERR_PTR(result);
 	}
 	}
-	/*
-	 * Kernel sockets that are a part of a namespace, should not
-	 * hold a reference to a namespace in order to allow to stop it.
-	 * After sk_change_net should be released using sk_release_kernel.
-	 */
-	sk_change_net(sock->sk, net);
 	result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn);
 	result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn);
 	if (result < 0) {
 	if (result < 0) {
 		pr_err("Error setting outbound mcast interface\n");
 		pr_err("Error setting outbound mcast interface\n");
@@ -1497,7 +1491,7 @@ static struct socket *make_send_sock(struct net *net, int id)
 	return sock;
 	return sock;
 
 
 error:
 error:
-	sk_release_kernel(sock->sk);
+	sock_release(sock);
 	return ERR_PTR(result);
 	return ERR_PTR(result);
 }
 }
 
 
@@ -1518,17 +1512,11 @@ static struct socket *make_receive_sock(struct net *net, int id)
 	int result;
 	int result;
 
 
 	/* First create a socket */
 	/* First create a socket */
-	result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
+	result = sock_create_kern(net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
 	if (result < 0) {
 	if (result < 0) {
 		pr_err("Error during creation of socket; terminating\n");
 		pr_err("Error during creation of socket; terminating\n");
 		return ERR_PTR(result);
 		return ERR_PTR(result);
 	}
 	}
-	/*
-	 * Kernel sockets that are a part of a namespace, should not
-	 * hold a reference to a namespace in order to allow to stop it.
-	 * After sk_change_net should be released using sk_release_kernel.
-	 */
-	sk_change_net(sock->sk, net);
 	/* it is equivalent to the REUSEADDR option in user-space */
 	/* it is equivalent to the REUSEADDR option in user-space */
 	sock->sk->sk_reuse = SK_CAN_REUSE;
 	sock->sk->sk_reuse = SK_CAN_REUSE;
 	result = sysctl_sync_sock_size(ipvs);
 	result = sysctl_sync_sock_size(ipvs);
@@ -1554,7 +1542,7 @@ static struct socket *make_receive_sock(struct net *net, int id)
 	return sock;
 	return sock;
 
 
 error:
 error:
-	sk_release_kernel(sock->sk);
+	sock_release(sock);
 	return ERR_PTR(result);
 	return ERR_PTR(result);
 }
 }
 
 
@@ -1692,7 +1680,7 @@ done:
 		ip_vs_sync_buff_release(sb);
 		ip_vs_sync_buff_release(sb);
 
 
 	/* release the sending multicast socket */
 	/* release the sending multicast socket */
-	sk_release_kernel(tinfo->sock->sk);
+	sock_release(tinfo->sock);
 	kfree(tinfo);
 	kfree(tinfo);
 
 
 	return 0;
 	return 0;
@@ -1729,7 +1717,7 @@ static int sync_thread_backup(void *data)
 	}
 	}
 
 
 	/* release the sending multicast socket */
 	/* release the sending multicast socket */
-	sk_release_kernel(tinfo->sock->sk);
+	sock_release(tinfo->sock);
 	kfree(tinfo->buf);
 	kfree(tinfo->buf);
 	kfree(tinfo);
 	kfree(tinfo);
 
 
@@ -1854,11 +1842,11 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid)
 	return 0;
 	return 0;
 
 
 outsocket:
 outsocket:
-	sk_release_kernel(sock->sk);
+	sock_release(sock);
 
 
 outtinfo:
 outtinfo:
 	if (tinfo) {
 	if (tinfo) {
-		sk_release_kernel(tinfo->sock->sk);
+		sock_release(tinfo->sock);
 		kfree(tinfo->buf);
 		kfree(tinfo->buf);
 		kfree(tinfo);
 		kfree(tinfo);
 	}
 	}

+ 9 - 12
net/netlink/af_netlink.c

@@ -1119,14 +1119,15 @@ static struct proto netlink_proto = {
 };
 };
 
 
 static int __netlink_create(struct net *net, struct socket *sock,
 static int __netlink_create(struct net *net, struct socket *sock,
-			    struct mutex *cb_mutex, int protocol)
+			    struct mutex *cb_mutex, int protocol,
+			    int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct netlink_sock *nlk;
 	struct netlink_sock *nlk;
 
 
 	sock->ops = &netlink_ops;
 	sock->ops = &netlink_ops;
 
 
-	sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto);
+	sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1188,7 +1189,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
 	if (err < 0)
 	if (err < 0)
 		goto out;
 		goto out;
 
 
-	err = __netlink_create(net, sock, cb_mutex, protocol);
+	err = __netlink_create(net, sock, cb_mutex, protocol, kern);
 	if (err < 0)
 	if (err < 0)
 		goto out_module;
 		goto out_module;
 
 
@@ -2516,17 +2517,10 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
 	if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
 	if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
 		return NULL;
 		return NULL;
 
 
-	/*
-	 * We have to just have a reference on the net from sk, but don't
-	 * get_net it. Besides, we cannot get and then put the net here.
-	 * So we create one inside init_net and the move it to net.
-	 */
-
-	if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0)
+	if (__netlink_create(net, sock, cb_mutex, unit, 1) < 0)
 		goto out_sock_release_nosk;
 		goto out_sock_release_nosk;
 
 
 	sk = sock->sk;
 	sk = sock->sk;
-	sk_change_net(sk, net);
 
 
 	if (!cfg || cfg->groups < 32)
 	if (!cfg || cfg->groups < 32)
 		groups = 32;
 		groups = 32;
@@ -2582,7 +2576,10 @@ EXPORT_SYMBOL(__netlink_kernel_create);
 void
 void
 netlink_kernel_release(struct sock *sk)
 netlink_kernel_release(struct sock *sk)
 {
 {
-	sk_release_kernel(sk);
+	if (sk == NULL || sk->sk_socket == NULL)
+		return;
+
+	sock_release(sk->sk_socket);
 }
 }
 EXPORT_SYMBOL(netlink_kernel_release);
 EXPORT_SYMBOL(netlink_kernel_release);
 
 

+ 2 - 2
net/netrom/af_netrom.c

@@ -433,7 +433,7 @@ static int nr_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_SEQPACKET || protocol != 0)
 	if (sock->type != SOCK_SEQPACKET || protocol != 0)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto);
+	sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, kern);
 	if (sk  == NULL)
 	if (sk  == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -476,7 +476,7 @@ static struct sock *nr_make_new(struct sock *osk)
 	if (osk->sk_type != SOCK_SEQPACKET)
 	if (osk->sk_type != SOCK_SEQPACKET)
 		return NULL;
 		return NULL;
 
 
-	sk = sk_alloc(sock_net(osk), PF_NETROM, GFP_ATOMIC, osk->sk_prot);
+	sk = sk_alloc(sock_net(osk), PF_NETROM, GFP_ATOMIC, osk->sk_prot, 0);
 	if (sk == NULL)
 	if (sk == NULL)
 		return NULL;
 		return NULL;
 
 

+ 1 - 1
net/nfc/af_nfc.c

@@ -40,7 +40,7 @@ static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
 
 
 	read_lock(&proto_tab_lock);
 	read_lock(&proto_tab_lock);
 	if (proto_tab[proto] &&	try_module_get(proto_tab[proto]->owner)) {
 	if (proto_tab[proto] &&	try_module_get(proto_tab[proto]->owner)) {
-		rc = proto_tab[proto]->create(net, sock, proto_tab[proto]);
+		rc = proto_tab[proto]->create(net, sock, proto_tab[proto], kern);
 		module_put(proto_tab[proto]->owner);
 		module_put(proto_tab[proto]->owner);
 	}
 	}
 	read_unlock(&proto_tab_lock);
 	read_unlock(&proto_tab_lock);

+ 1 - 1
net/nfc/llcp.h

@@ -225,7 +225,7 @@ void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
 			       struct sk_buff *skb, u8 direction);
 			       struct sk_buff *skb, u8 direction);
 
 
 /* Sock API */
 /* Sock API */
-struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
+struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp, int kern);
 void nfc_llcp_sock_free(struct nfc_llcp_sock *sock);
 void nfc_llcp_sock_free(struct nfc_llcp_sock *sock);
 void nfc_llcp_accept_unlink(struct sock *sk);
 void nfc_llcp_accept_unlink(struct sock *sk);
 void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk);
 void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk);

+ 1 - 1
net/nfc/llcp_core.c

@@ -934,7 +934,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
 		sock->ssap = ssap;
 		sock->ssap = ssap;
 	}
 	}
 
 
-	new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, GFP_ATOMIC);
+	new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, GFP_ATOMIC, 0);
 	if (new_sk == NULL) {
 	if (new_sk == NULL) {
 		reason = LLCP_DM_REJ;
 		reason = LLCP_DM_REJ;
 		release_sock(&sock->sk);
 		release_sock(&sock->sk);

+ 4 - 4
net/nfc/llcp_sock.c

@@ -942,12 +942,12 @@ static void llcp_sock_destruct(struct sock *sk)
 	}
 	}
 }
 }
 
 
-struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
+struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct nfc_llcp_sock *llcp_sock;
 	struct nfc_llcp_sock *llcp_sock;
 
 
-	sk = sk_alloc(&init_net, PF_NFC, gfp, &llcp_sock_proto);
+	sk = sk_alloc(&init_net, PF_NFC, gfp, &llcp_sock_proto, kern);
 	if (!sk)
 	if (!sk)
 		return NULL;
 		return NULL;
 
 
@@ -993,7 +993,7 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
 }
 }
 
 
 static int llcp_sock_create(struct net *net, struct socket *sock,
 static int llcp_sock_create(struct net *net, struct socket *sock,
-			    const struct nfc_protocol *nfc_proto)
+			    const struct nfc_protocol *nfc_proto, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
@@ -1009,7 +1009,7 @@ static int llcp_sock_create(struct net *net, struct socket *sock,
 	else
 	else
 		sock->ops = &llcp_sock_ops;
 		sock->ops = &llcp_sock_ops;
 
 
-	sk = nfc_llcp_sock_alloc(sock, sock->type, GFP_ATOMIC);
+	sk = nfc_llcp_sock_alloc(sock, sock->type, GFP_ATOMIC, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/nfc/nfc.h

@@ -30,7 +30,7 @@ struct nfc_protocol {
 	struct proto *proto;
 	struct proto *proto;
 	struct module *owner;
 	struct module *owner;
 	int (*create)(struct net *net, struct socket *sock,
 	int (*create)(struct net *net, struct socket *sock,
-		      const struct nfc_protocol *nfc_proto);
+		      const struct nfc_protocol *nfc_proto, int kern);
 };
 };
 
 
 struct nfc_rawsock {
 struct nfc_rawsock {

+ 2 - 2
net/nfc/rawsock.c

@@ -334,7 +334,7 @@ static void rawsock_destruct(struct sock *sk)
 }
 }
 
 
 static int rawsock_create(struct net *net, struct socket *sock,
 static int rawsock_create(struct net *net, struct socket *sock,
-			  const struct nfc_protocol *nfc_proto)
+			  const struct nfc_protocol *nfc_proto, int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 
 
@@ -348,7 +348,7 @@ static int rawsock_create(struct net *net, struct socket *sock,
 	else
 	else
 		sock->ops = &rawsock_ops;
 		sock->ops = &rawsock_ops;
 
 
-	sk = sk_alloc(net, PF_NFC, GFP_ATOMIC, nfc_proto->proto);
+	sk = sk_alloc(net, PF_NFC, GFP_ATOMIC, nfc_proto->proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 1 - 1
net/packet/af_packet.c

@@ -2832,7 +2832,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
 	sock->state = SS_UNCONNECTED;
 	sock->state = SS_UNCONNECTED;
 
 
 	err = -ENOBUFS;
 	err = -ENOBUFS;
-	sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto);
+	sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		goto out;
 		goto out;
 
 

+ 1 - 1
net/phonet/af_phonet.c

@@ -97,7 +97,7 @@ static int pn_socket_create(struct net *net, struct socket *sock, int protocol,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot);
+	sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot, kern);
 	if (sk == NULL) {
 	if (sk == NULL) {
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto out;
 		goto out;

+ 1 - 1
net/phonet/pep.c

@@ -845,7 +845,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)
 	}
 	}
 
 
 	/* Create a new to-be-accepted sock */
 	/* Create a new to-be-accepted sock */
-	newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_KERNEL, sk->sk_prot);
+	newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_KERNEL, sk->sk_prot, 0);
 	if (!newsk) {
 	if (!newsk) {
 		pep_reject_conn(sk, skb, PN_PIPE_ERR_OVERLOAD, GFP_KERNEL);
 		pep_reject_conn(sk, skb, PN_PIPE_ERR_OVERLOAD, GFP_KERNEL);
 		err = -ENOBUFS;
 		err = -ENOBUFS;

+ 1 - 1
net/rds/af_rds.c

@@ -440,7 +440,7 @@ static int rds_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_SEQPACKET || protocol)
 	if (sock->type != SOCK_SEQPACKET || protocol)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, AF_RDS, GFP_ATOMIC, &rds_proto);
+	sk = sk_alloc(net, AF_RDS, GFP_ATOMIC, &rds_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 2 - 2
net/rose/af_rose.c

@@ -520,7 +520,7 @@ static int rose_create(struct net *net, struct socket *sock, int protocol,
 	if (sock->type != SOCK_SEQPACKET || protocol != 0)
 	if (sock->type != SOCK_SEQPACKET || protocol != 0)
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 
 
-	sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto);
+	sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -559,7 +559,7 @@ static struct sock *rose_make_new(struct sock *osk)
 	if (osk->sk_type != SOCK_SEQPACKET)
 	if (osk->sk_type != SOCK_SEQPACKET)
 		return NULL;
 		return NULL;
 
 
-	sk = sk_alloc(sock_net(osk), PF_ROSE, GFP_ATOMIC, &rose_proto);
+	sk = sk_alloc(sock_net(osk), PF_ROSE, GFP_ATOMIC, &rose_proto, 0);
 	if (sk == NULL)
 	if (sk == NULL)
 		return NULL;
 		return NULL;
 
 

+ 1 - 1
net/rxrpc/af_rxrpc.c

@@ -632,7 +632,7 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
 	sock->ops = &rxrpc_rpc_ops;
 	sock->ops = &rxrpc_rpc_ops;
 	sock->state = SS_UNCONNECTED;
 	sock->state = SS_UNCONNECTED;
 
 
-	sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto);
+	sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, kern);
 	if (!sk)
 	if (!sk)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 2 - 2
net/rxrpc/ar-local.c

@@ -73,8 +73,8 @@ static int rxrpc_create_local(struct rxrpc_local *local)
 	_enter("%p{%d}", local, local->srx.transport_type);
 	_enter("%p{%d}", local, local->srx.transport_type);
 
 
 	/* create a socket to represent the local endpoint */
 	/* create a socket to represent the local endpoint */
-	ret = sock_create_kern(PF_INET, local->srx.transport_type, IPPROTO_UDP,
-			       &local->socket);
+	ret = sock_create_kern(&init_net, PF_INET, local->srx.transport_type,
+			       IPPROTO_UDP, &local->socket);
 	if (ret < 0) {
 	if (ret < 0) {
 		_leave(" = %d [socket]", ret);
 		_leave(" = %d [socket]", ret);
 		return ret;
 		return ret;

+ 1 - 1
net/sctp/ipv6.c

@@ -635,7 +635,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct sctp6_sock *newsctp6sk;
 	struct sctp6_sock *newsctp6sk;
 
 
-	newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot);
+	newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, 0);
 	if (!newsk)
 	if (!newsk)
 		goto out;
 		goto out;
 
 

+ 1 - 1
net/sctp/protocol.c

@@ -550,7 +550,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
 					     struct sctp_association *asoc)
 					     struct sctp_association *asoc)
 {
 {
 	struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL,
 	struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL,
-			sk->sk_prot);
+			sk->sk_prot, 0);
 	struct inet_sock *newinet;
 	struct inet_sock *newinet;
 
 
 	if (!newsk)
 	if (!newsk)

+ 2 - 5
net/socket.c

@@ -576,9 +576,6 @@ void sock_release(struct socket *sock)
 	if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
 	if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
 		pr_err("%s: fasync list not empty!\n", __func__);
 		pr_err("%s: fasync list not empty!\n", __func__);
 
 
-	if (test_bit(SOCK_EXTERNALLY_ALLOCATED, &sock->flags))
-		return;
-
 	this_cpu_sub(sockets_in_use, 1);
 	this_cpu_sub(sockets_in_use, 1);
 	if (!sock->file) {
 	if (!sock->file) {
 		iput(SOCK_INODE(sock));
 		iput(SOCK_INODE(sock));
@@ -1213,9 +1210,9 @@ int sock_create(int family, int type, int protocol, struct socket **res)
 }
 }
 EXPORT_SYMBOL(sock_create);
 EXPORT_SYMBOL(sock_create);
 
 
-int sock_create_kern(int family, int type, int protocol, struct socket **res)
+int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
 {
 {
-	return __sock_create(&init_net, family, type, protocol, res, 1);
+	return __sock_create(net, family, type, protocol, res, 1);
 }
 }
 EXPORT_SYMBOL(sock_create_kern);
 EXPORT_SYMBOL(sock_create_kern);
 
 

+ 1 - 1
net/tipc/socket.c

@@ -342,7 +342,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	}
 	}
 
 
 	/* Allocate socket's protocol area */
 	/* Allocate socket's protocol area */
-	sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
+	sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto, kern);
 	if (sk == NULL)
 	if (sk == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 4 - 4
net/unix/af_unix.c

@@ -620,7 +620,7 @@ static struct proto unix_proto = {
  */
  */
 static struct lock_class_key af_unix_sk_receive_queue_lock_key;
 static struct lock_class_key af_unix_sk_receive_queue_lock_key;
 
 
-static struct sock *unix_create1(struct net *net, struct socket *sock)
+static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
 {
 {
 	struct sock *sk = NULL;
 	struct sock *sk = NULL;
 	struct unix_sock *u;
 	struct unix_sock *u;
@@ -629,7 +629,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock)
 	if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
 	if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
 		goto out;
 		goto out;
 
 
-	sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
+	sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, kern);
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
 
 
@@ -688,7 +688,7 @@ static int unix_create(struct net *net, struct socket *sock, int protocol,
 		return -ESOCKTNOSUPPORT;
 		return -ESOCKTNOSUPPORT;
 	}
 	}
 
 
-	return unix_create1(net, sock) ? 0 : -ENOMEM;
+	return unix_create1(net, sock, kern) ? 0 : -ENOMEM;
 }
 }
 
 
 static int unix_release(struct socket *sock)
 static int unix_release(struct socket *sock)
@@ -1088,7 +1088,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 	err = -ENOMEM;
 	err = -ENOMEM;
 
 
 	/* create new sock for complete connection */
 	/* create new sock for complete connection */
-	newsk = unix_create1(sock_net(sk), NULL);
+	newsk = unix_create1(sock_net(sk), NULL, 0);
 	if (newsk == NULL)
 	if (newsk == NULL)
 		goto out;
 		goto out;
 
 

+ 4 - 3
net/vmw_vsock/af_vsock.c

@@ -581,13 +581,14 @@ struct sock *__vsock_create(struct net *net,
 			    struct socket *sock,
 			    struct socket *sock,
 			    struct sock *parent,
 			    struct sock *parent,
 			    gfp_t priority,
 			    gfp_t priority,
-			    unsigned short type)
+			    unsigned short type,
+			    int kern)
 {
 {
 	struct sock *sk;
 	struct sock *sk;
 	struct vsock_sock *psk;
 	struct vsock_sock *psk;
 	struct vsock_sock *vsk;
 	struct vsock_sock *vsk;
 
 
-	sk = sk_alloc(net, AF_VSOCK, priority, &vsock_proto);
+	sk = sk_alloc(net, AF_VSOCK, priority, &vsock_proto, kern);
 	if (!sk)
 	if (!sk)
 		return NULL;
 		return NULL;
 
 
@@ -1866,7 +1867,7 @@ static int vsock_create(struct net *net, struct socket *sock,
 
 
 	sock->state = SS_UNCONNECTED;
 	sock->state = SS_UNCONNECTED;
 
 
-	return __vsock_create(net, sock, NULL, GFP_KERNEL, 0) ? 0 : -ENOMEM;
+	return __vsock_create(net, sock, NULL, GFP_KERNEL, 0, kern) ? 0 : -ENOMEM;
 }
 }
 
 
 static const struct net_proto_family vsock_family_ops = {
 static const struct net_proto_family vsock_family_ops = {

+ 1 - 1
net/vmw_vsock/vmci_transport.c

@@ -1022,7 +1022,7 @@ static int vmci_transport_recv_listen(struct sock *sk,
 	}
 	}
 
 
 	pending = __vsock_create(sock_net(sk), NULL, sk, GFP_KERNEL,
 	pending = __vsock_create(sock_net(sk), NULL, sk, GFP_KERNEL,
-				 sk->sk_type);
+				 sk->sk_type, 0);
 	if (!pending) {
 	if (!pending) {
 		vmci_transport_send_reset(sk, pkt);
 		vmci_transport_send_reset(sk, pkt);
 		return -ENOMEM;
 		return -ENOMEM;

+ 4 - 4
net/x25/af_x25.c

@@ -515,10 +515,10 @@ static struct proto x25_proto = {
 	.obj_size = sizeof(struct x25_sock),
 	.obj_size = sizeof(struct x25_sock),
 };
 };
 
 
-static struct sock *x25_alloc_socket(struct net *net)
+static struct sock *x25_alloc_socket(struct net *net, int kern)
 {
 {
 	struct x25_sock *x25;
 	struct x25_sock *x25;
-	struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto);
+	struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, kern);
 
 
 	if (!sk)
 	if (!sk)
 		goto out;
 		goto out;
@@ -553,7 +553,7 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
 		goto out;
 		goto out;
 
 
 	rc = -ENOBUFS;
 	rc = -ENOBUFS;
-	if ((sk = x25_alloc_socket(net)) == NULL)
+	if ((sk = x25_alloc_socket(net, kern)) == NULL)
 		goto out;
 		goto out;
 
 
 	x25 = x25_sk(sk);
 	x25 = x25_sk(sk);
@@ -602,7 +602,7 @@ static struct sock *x25_make_new(struct sock *osk)
 	if (osk->sk_type != SOCK_SEQPACKET)
 	if (osk->sk_type != SOCK_SEQPACKET)
 		goto out;
 		goto out;
 
 
-	if ((sk = x25_alloc_socket(sock_net(osk))) == NULL)
+	if ((sk = x25_alloc_socket(sock_net(osk), 0)) == NULL)
 		goto out;
 		goto out;
 
 
 	x25 = x25_sk(sk);
 	x25 = x25_sk(sk);