aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2005-03-31 05:14:28 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2005-03-31 05:14:28 -0800
commit102bbba64bde80e5cf25119096dba81adcf53933 (patch)
tree4448ef9d6123ff85daa03efe26bfc19df6fb092b
parent841d26e7e026eb5197b8073a6bf3f530b9f7603b (diff)
parent15d26df09084ff3a891a696efd0d56b52d852e24 (diff)
downloadhistory-102bbba64bde80e5cf25119096dba81adcf53933.tar.gz
Merge bk://kernel.bkbits.net/acme/net-2.6
into sunset.davemloft.net:/home/davem/src/BK/net-2.6
-rw-r--r--drivers/net/pppoe.c28
-rw-r--r--include/linux/ip.h2
-rw-r--r--include/net/llc_conn.h2
-rw-r--r--include/net/sock.h33
-rw-r--r--net/appletalk/ddp.c19
-rw-r--r--net/atm/common.c32
-rw-r--r--net/ax25/af_ax25.c26
-rw-r--r--net/bluetooth/bnep/sock.c32
-rw-r--r--net/bluetooth/cmtp/sock.c30
-rw-r--r--net/bluetooth/hci_sock.c33
-rw-r--r--net/bluetooth/hidp/sock.c24
-rw-r--r--net/bluetooth/l2cap.c36
-rw-r--r--net/bluetooth/rfcomm/sock.c34
-rw-r--r--net/bluetooth/sco.c42
-rw-r--r--net/core/sock.c219
-rw-r--r--net/decnet/af_decnet.c28
-rw-r--r--net/econet/af_econet.c20
-rw-r--r--net/ipv4/af_inet.c24
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/syncookies.c5
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_minisocks.c6
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv6/af_inet6.c38
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/ipx/af_ipx.c28
-rw-r--r--net/irda/af_irda.c20
-rw-r--r--net/key/af_key.c39
-rw-r--r--net/llc/af_llc.c28
-rw-r--r--net/llc/llc_conn.c8
-rw-r--r--net/netlink/af_netlink.c28
-rw-r--r--net/netrom/af_netrom.c32
-rw-r--r--net/packet/af_packet.c22
-rw-r--r--net/rose/af_rose.c27
-rw-r--r--net/sctp/ipv6.c14
-rw-r--r--net/sctp/protocol.c12
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/unix/af_unix.c34
-rw-r--r--net/wanrouter/af_wanpipe.c25
-rw-r--r--net/x25/af_x25.c20
42 files changed, 725 insertions, 345 deletions
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index d597a051bc7dfc..ce1a9bf7b9a76e 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -480,6 +480,12 @@ static struct packet_type pppoed_ptype = {
.func = pppoe_disc_rcv,
};
+static struct proto pppoe_sk_proto = {
+ .name = "PPPOE",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct pppox_sock),
+};
+
/***********************************************************************
*
* Initialize a new struct sock.
@@ -490,12 +496,12 @@ static int pppoe_create(struct socket *sock)
int error = -ENOMEM;
struct sock *sk;
- sk = sk_alloc(PF_PPPOX, GFP_KERNEL, sizeof(struct pppox_sock), NULL);
+ sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
if (!sk)
goto out;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
+
sock->state = SS_UNCONNECTED;
sock->ops = &pppoe_ops;
@@ -1103,22 +1109,29 @@ static struct pppox_proto pppoe_proto = {
static int __init pppoe_init(void)
{
- int err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
+ int err = proto_register(&pppoe_sk_proto, 0);
if (err)
goto out;
+ err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
+ if (err)
+ goto out_unregister_pppoe_proto;
+
err = pppoe_proc_init();
- if (err) {
- unregister_pppox_proto(PX_PROTO_OE);
- goto out;
- }
+ if (err)
+ goto out_unregister_pppox_proto;
dev_add_pack(&pppoes_ptype);
dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier);
out:
return err;
+out_unregister_pppox_proto:
+ unregister_pppox_proto(PX_PROTO_OE);
+out_unregister_pppoe_proto:
+ proto_unregister(&pppoe_sk_proto);
+ goto out;
}
static void __exit pppoe_exit(void)
@@ -1128,6 +1141,7 @@ static void __exit pppoe_exit(void)
dev_remove_pack(&pppoed_ptype);
unregister_netdevice_notifier(&pppoe_notifier);
remove_proc_entry("pppoe", proc_net);
+ proto_unregister(&pppoe_sk_proto);
}
module_init(pppoe_init);
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 53a5afeb4e79cd..8438c68591f99c 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -164,7 +164,7 @@ static inline void __inet_sk_copy_descendant(struct sock *sk_to,
const int ancestor_size)
{
memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
- sk_from->sk_prot->slab_obj_size - ancestor_size);
+ sk_from->sk_prot->obj_size - ancestor_size);
}
#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
static inline void inet_sk_copy_descendant(struct sock *sk_to,
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
index 179e98e2aac864..8ad3bc2c23d78d 100644
--- a/include/net/llc_conn.h
+++ b/include/net/llc_conn.h
@@ -92,7 +92,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
return skb->cb[sizeof(skb->cb) - 1];
}
-extern struct sock *llc_sk_alloc(int family, int priority);
+extern struct sock *llc_sk_alloc(int family, int priority, struct proto *prot);
extern void llc_sk_free(struct sock *sk);
extern void llc_sk_reset(struct sock *sk);
diff --git a/include/net/sock.h b/include/net/sock.h
index fb789af4ab0887..be81cabd0da3f8 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -154,12 +154,10 @@ struct sock_common {
* @sk_sndtimeo - %SO_SNDTIMEO setting
* @sk_filter - socket filtering instructions
* @sk_protinfo - private area, net family specific, when not using slab
- * @sk_slab - the slabcache this instance was allocated from
* @sk_timer - sock cleanup timer
* @sk_stamp - time stamp of last packet received
* @sk_socket - Identd and reporting IO signals
* @sk_user_data - RPC layer private data
- * @sk_owner - module that owns this socket
* @sk_sndmsg_page - cached page for sendmsg
* @sk_sndmsg_off - cached offset for sendmsg
* @sk_send_head - front of stuff to transmit
@@ -231,12 +229,10 @@ struct sock {
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
- kmem_cache_t *sk_slab;
struct timer_list sk_timer;
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
- struct module *sk_owner;
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
@@ -546,37 +542,22 @@ struct proto {
int max_header;
kmem_cache_t *slab;
- int slab_obj_size;
+ unsigned int obj_size;
struct module *owner;
char name[32];
+ struct list_head node;
+
struct {
int inuse;
u8 __pad[SMP_CACHE_BYTES - sizeof(int)];
} stats[NR_CPUS];
};
-extern int sk_alloc_slab(struct proto *prot, char *name);
-extern void sk_free_slab(struct proto *prot);
-
-static __inline__ void sk_set_owner(struct sock *sk, struct module *owner)
-{
- /*
- * One should use sk_set_owner just once, after struct sock creation,
- * be it shortly after sk_alloc or after a function that returns a new
- * struct sock (and that down the call chain called sk_alloc), e.g. the
- * IPv4 and IPv6 modules share tcp_create_openreq_child, so if
- * tcp_create_openreq_child called sk_set_owner IPv6 would have to
- * change the ownership of this struct sock, with one not needed
- * transient sk_set_owner call.
- */
- BUG_ON(sk->sk_owner != NULL);
-
- sk->sk_owner = owner;
- __module_get(owner);
-}
+extern int proto_register(struct proto *prot, int alloc_slab);
+extern void proto_unregister(struct proto *prot);
/* Called with local bh disabled */
static __inline__ void sock_prot_inc_use(struct proto *prot)
@@ -696,8 +677,8 @@ extern void FASTCALL(release_sock(struct sock *sk));
#define bh_lock_sock(__sk) spin_lock(&((__sk)->sk_lock.slock))
#define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock))
-extern struct sock * sk_alloc(int family, int priority, int zero_it,
- kmem_cache_t *slab);
+extern struct sock *sk_alloc(int family, int priority,
+ struct proto *prot, int zero_it);
extern void sk_free(struct sock *sk);
extern struct sk_buff *sock_wmalloc(struct sock *sk,
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 8c55dbce87582c..d1fea5c3dda1b0 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1015,6 +1015,12 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len)
return sum ? htons((unsigned short)sum) : 0xFFFF;
}
+static struct proto ddp_proto = {
+ .name = "DDP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct atalk_sock),
+};
+
/*
* Create a socket. Initialise the socket, blank the addresses
* set the state.
@@ -1031,14 +1037,12 @@ static int atalk_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
goto out;
rc = -ENOMEM;
- sk = sk_alloc(PF_APPLETALK, GFP_KERNEL,
- sizeof(struct atalk_sock), NULL);
+ sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
if (!sk)
goto out;
rc = 0;
sock->ops = &atalk_dgram_ops;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
/* Checksums on by default */
sock_set_flag(sk, SOCK_ZAPPED);
@@ -1874,6 +1878,11 @@ static char atalk_err_snap[] __initdata =
/* Called by proto.c on kernel start up */
static int __init atalk_init(void)
{
+ int rc = proto_register(&ddp_proto, 0);
+
+ if (rc != 0)
+ goto out;
+
(void)sock_register(&atalk_family_ops);
ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv);
if (!ddp_dl)
@@ -1886,7 +1895,8 @@ static int __init atalk_init(void)
aarp_proto_init();
atalk_proc_init();
atalk_register_sysctl();
- return 0;
+out:
+ return rc;
}
module_init(atalk_init);
@@ -1911,6 +1921,7 @@ static void __exit atalk_exit(void)
dev_remove_pack(&ppptalk_packet_type);
unregister_snap_client(ddp_dl);
sock_unregister(PF_APPLETALK);
+ proto_unregister(&ddp_proto);
}
module_exit(atalk_exit);
diff --git a/net/atm/common.c b/net/atm/common.c
index 30a6a753256055..6d16be334ea0a3 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -127,6 +127,11 @@ static void vcc_write_space(struct sock *sk)
read_unlock(&sk->sk_callback_lock);
}
+static struct proto vcc_proto = {
+ .name = "VCC",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct atm_vcc),
+};
int vcc_create(struct socket *sock, int protocol, int family)
{
@@ -136,11 +141,10 @@ int vcc_create(struct socket *sock, int protocol, int family)
sock->sk = NULL;
if (sock->type == SOCK_STREAM)
return -EINVAL;
- sk = sk_alloc(family, GFP_KERNEL, sizeof(struct atm_vcc), NULL);
+ sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1);
if (!sk)
return -ENOMEM;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_state_change = vcc_def_wakeup;
sk->sk_write_space = vcc_write_space;
@@ -157,7 +161,6 @@ int vcc_create(struct socket *sock, int protocol, int family)
vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
vcc->atm_options = vcc->aal_options = 0;
sk->sk_destruct = vcc_sock_destruct;
- sock->sk = sk;
return 0;
}
@@ -759,24 +762,30 @@ static int __init atm_init(void)
{
int error;
+ if ((error = proto_register(&vcc_proto, 0)) < 0)
+ goto out;
+
if ((error = atmpvc_init()) < 0) {
printk(KERN_ERR "atmpvc_init() failed with %d\n", error);
- goto failure;
+ goto out_unregister_vcc_proto;
}
if ((error = atmsvc_init()) < 0) {
printk(KERN_ERR "atmsvc_init() failed with %d\n", error);
- goto failure;
+ goto out_atmpvc_exit;
}
if ((error = atm_proc_init()) < 0) {
printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
- goto failure;
+ goto out_atmsvc_exit;
}
- return 0;
-
-failure:
- atmsvc_exit();
- atmpvc_exit();
+out:
return error;
+out_atmsvc_exit:
+ atmsvc_exit();
+out_atmpvc_exit:
+ atmsvc_exit();
+out_unregister_vcc_proto:
+ proto_unregister(&vcc_proto);
+ goto out;
}
static void __exit atm_exit(void)
@@ -784,6 +793,7 @@ static void __exit atm_exit(void)
atm_proc_exit();
atmsvc_exit();
atmpvc_exit();
+ proto_unregister(&vcc_proto);
}
module_init(atm_init);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index fbef221c2f6577..33b1a376302702 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -760,6 +760,16 @@ out:
return res;
}
+/*
+ * XXX: when creating ax25_sock we should update the .obj_size setting
+ * below.
+ */
+static struct proto ax25_proto = {
+ .name = "AX25",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct sock),
+};
+
static int ax25_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -810,7 +820,7 @@ static int ax25_create(struct socket *sock, int protocol)
return -ESOCKTNOSUPPORT;
}
- if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, 1, NULL)) == NULL)
+ if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
return -ENOMEM;
ax25 = sk->sk_protinfo = ax25_create_cb();
@@ -820,7 +830,6 @@ static int ax25_create(struct socket *sock, int protocol)
}
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_destruct = ax25_free_sock;
sock->ops = &ax25_proto_ops;
@@ -836,7 +845,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
struct sock *sk;
ax25_cb *ax25, *oax25;
- if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, 1, NULL)) == NULL)
+ if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
return NULL;
if ((ax25 = ax25_create_cb()) == NULL) {
@@ -856,7 +865,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
}
sock_init_data(NULL, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_destruct = ax25_free_sock;
sk->sk_type = osk->sk_type;
@@ -1998,6 +2006,11 @@ EXPORT_SYMBOL(ax25_display_timer);
static int __init ax25_init(void)
{
+ int rc = proto_register(&ax25_proto, 0);
+
+ if (rc != 0)
+ goto out;
+
sock_register(&ax25_family_ops);
dev_add_pack(&ax25_packet_type);
register_netdevice_notifier(&ax25_dev_notifier);
@@ -2006,8 +2019,8 @@ static int __init ax25_init(void)
proc_net_fops_create("ax25_route", S_IRUGO, &ax25_route_fops);
proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops);
proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops);
-
- return 0;
+out:
+ return rc;
}
module_init(ax25_init);
@@ -2032,5 +2045,6 @@ static void __exit ax25_exit(void)
dev_remove_pack(&ax25_packet_type);
sock_unregister(PF_AX25);
+ proto_unregister(&ax25_proto);
}
module_exit(ax25_exit);
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index b17a39ee8161f9..9a8d99a39b6dbc 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -167,6 +167,12 @@ static struct proto_ops bnep_sock_ops = {
.mmap = sock_no_mmap
};
+static struct proto bnep_proto = {
+ .name = "BNEP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct bt_sock)
+};
+
static int bnep_sock_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -176,13 +182,12 @@ static int bnep_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
- if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, sizeof(struct bt_sock), NULL)))
+ sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1);
+ if (!sk)
return -ENOMEM;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
-
sock->ops = &bnep_sock_ops;
sock->state = SS_UNCONNECTED;
@@ -203,13 +208,30 @@ static struct net_proto_family bnep_sock_family_ops = {
int __init bnep_sock_init(void)
{
- bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
+ int err;
+
+ err = proto_register(&bnep_proto, 0);
+ if (err < 0)
+ return err;
+
+ err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
+ if (err < 0)
+ goto error;
+
return 0;
+
+error:
+ BT_ERR("Can't register BNEP socket");
+ proto_unregister(&bnep_proto);
+ return err;
}
int __exit bnep_sock_cleanup(void)
{
- if (bt_sock_unregister(BTPROTO_BNEP))
+ if (bt_sock_unregister(BTPROTO_BNEP) < 0)
BT_ERR("Can't unregister BNEP socket");
+
+ proto_unregister(&bnep_proto);
+
return 0;
}
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index e4beaad22adf65..4c7f9e20dade01 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -158,6 +158,12 @@ static struct proto_ops cmtp_sock_ops = {
.mmap = sock_no_mmap
};
+static struct proto cmtp_proto = {
+ .name = "CMTP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct bt_sock)
+};
+
static int cmtp_sock_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -167,13 +173,12 @@ static int cmtp_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
- if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, sizeof(struct bt_sock), NULL)))
+ sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1);
+ if (!sk)
return -ENOMEM;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
-
sock->ops = &cmtp_sock_ops;
sock->state = SS_UNCONNECTED;
@@ -194,13 +199,28 @@ static struct net_proto_family cmtp_sock_family_ops = {
int cmtp_init_sockets(void)
{
- bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
+ int err;
+
+ err = proto_register(&cmtp_proto, 0);
+ if (err < 0)
+ return err;
+
+ err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
+ if (err < 0)
+ goto error;
return 0;
+
+error:
+ BT_ERR("Can't register CMTP socket");
+ proto_unregister(&cmtp_proto);
+ return err;
}
void cmtp_cleanup_sockets(void)
{
- if (bt_sock_unregister(BTPROTO_CMTP))
+ if (bt_sock_unregister(BTPROTO_CMTP) < 0)
BT_ERR("Can't unregister CMTP socket");
+
+ proto_unregister(&cmtp_proto);
}
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 841bdba0b877a0..c9792ba751221e 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -590,6 +590,12 @@ static struct proto_ops hci_sock_ops = {
.mmap = sock_no_mmap
};
+static struct proto hci_sk_proto = {
+ .name = "HCI",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct hci_pinfo)
+};
+
static int hci_sock_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -601,7 +607,7 @@ static int hci_sock_create(struct socket *sock, int protocol)
sock->ops = &hci_sock_ops;
- sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, sizeof(struct hci_pinfo), NULL);
+ sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1);
if (!sk)
return -ENOMEM;
@@ -611,8 +617,6 @@ static int hci_sock_create(struct socket *sock, int protocol)
sk->sk_protocol = protocol;
- sk_set_owner(sk, THIS_MODULE);
-
sock->state = SS_UNCONNECTED;
sk->sk_state = BT_OPEN;
@@ -668,23 +672,36 @@ static struct notifier_block hci_sock_nblock = {
int __init hci_sock_init(void)
{
- if (bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
- BT_ERR("HCI socket registration failed");
- return -EPROTO;
- }
+ int err;
+
+ err = proto_register(&hci_sk_proto, 0);
+ if (err < 0)
+ return err;
+
+ err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
+ if (err < 0)
+ goto error;
hci_register_notifier(&hci_sock_nblock);
BT_INFO("HCI socket layer initialized");
return 0;
+
+error:
+ BT_ERR("HCI socket registration failed");
+ proto_unregister(&hci_sk_proto);
+ return err;
}
int __exit hci_sock_cleanup(void)
{
- if (bt_sock_unregister(BTPROTO_HCI))
+ if (bt_sock_unregister(BTPROTO_HCI) < 0)
BT_ERR("HCI socket unregistration failed");
hci_unregister_notifier(&hci_sock_nblock);
+
+ proto_unregister(&hci_sk_proto);
+
return 0;
}
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index dc642f667eea59..fabb36d4666b4b 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -164,6 +164,12 @@ static struct proto_ops hidp_sock_ops = {
.mmap = sock_no_mmap
};
+static struct proto hidp_proto = {
+ .name = "HIDP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct bt_sock)
+};
+
static int hidp_sock_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -173,13 +179,12 @@ static int hidp_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
- if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, sizeof(struct bt_sock), NULL)))
+ sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1);
+ if (!sk)
return -ENOMEM;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
-
sock->ops = &hidp_sock_ops;
sock->state = SS_UNCONNECTED;
@@ -202,10 +207,19 @@ int __init hidp_init_sockets(void)
{
int err;
+ err = proto_register(&hidp_proto, 0);
+ if (err < 0)
+ return err;
+
err = bt_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops);
if (err < 0)
- BT_ERR("Can't register HIDP socket");
+ goto error;
+ return 0;
+
+error:
+ BT_ERR("Can't register HIDP socket");
+ proto_unregister(&hidp_proto);
return err;
}
@@ -213,4 +227,6 @@ void __exit hidp_cleanup_sockets(void)
{
if (bt_sock_unregister(BTPROTO_HIDP) < 0)
BT_ERR("Can't unregister HIDP socket");
+
+ proto_unregister(&hidp_proto);
}
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 59b58661c1a829..c12babcf0b3ccb 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -367,19 +367,23 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
}
+static struct proto l2cap_proto = {
+ .name = "L2CAP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct l2cap_pinfo)
+};
+
static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
{
struct sock *sk;
- sk = sk_alloc(PF_BLUETOOTH, prio, sizeof(struct l2cap_pinfo), NULL);
+ sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1);
if (!sk)
return NULL;
sock_init_data(sock, sk);
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
- sk_set_owner(sk, THIS_MODULE);
-
sk->sk_destruct = l2cap_sock_destruct;
sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
@@ -2263,15 +2267,22 @@ static struct hci_proto l2cap_hci_proto = {
static int __init l2cap_init(void)
{
int err;
+
+ err = proto_register(&l2cap_proto, 0);
+ if (err < 0)
+ return err;
- if ((err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
+ err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
+ if (err < 0) {
BT_ERR("L2CAP socket registration failed");
- return err;
+ goto error;
}
- if ((err = hci_register_proto(&l2cap_hci_proto))) {
+ err = hci_register_proto(&l2cap_hci_proto);
+ if (err < 0) {
BT_ERR("L2CAP protocol registration failed");
- return err;
+ bt_sock_unregister(BTPROTO_L2CAP);
+ goto error;
}
l2cap_proc_init();
@@ -2280,18 +2291,23 @@ static int __init l2cap_init(void)
BT_INFO("L2CAP socket layer initialized");
return 0;
+
+error:
+ proto_unregister(&l2cap_proto);
+ return err;
}
static void __exit l2cap_exit(void)
{
l2cap_proc_cleanup();
- /* Unregister socket and protocol */
- if (bt_sock_unregister(BTPROTO_L2CAP))
+ if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
BT_ERR("L2CAP socket unregistration failed");
- if (hci_unregister_proto(&l2cap_hci_proto))
+ if (hci_unregister_proto(&l2cap_hci_proto) < 0)
BT_ERR("L2CAP protocol unregistration failed");
+
+ proto_unregister(&l2cap_proto);
}
void l2cap_load(void)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 097e007cd9b0dc..640028a2183cd9 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -279,20 +279,24 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
pi->dlc->link_mode = pi->link_mode;
}
+static struct proto rfcomm_proto = {
+ .name = "RFCOMM",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct rfcomm_pinfo)
+};
+
static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
{
struct rfcomm_dlc *d;
struct sock *sk;
- sk = sk_alloc(PF_BLUETOOTH, prio, sizeof(struct rfcomm_pinfo), NULL);
+ sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1);
if (!sk)
return NULL;
sock_init_data(sock, sk);
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
- sk_set_owner(sk, THIS_MODULE);
-
d = rfcomm_dlc_alloc(prio);
if (!d) {
sk_free(sk);
@@ -975,24 +979,32 @@ int __init rfcomm_init_sockets(void)
{
int err;
- if ((err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
- BT_ERR("RFCOMM socket layer registration failed. %d", err);
+ err = proto_register(&rfcomm_proto, 0);
+ if (err < 0)
return err;
- }
+
+ err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops);
+ if (err < 0)
+ goto error;
rfcomm_sock_proc_init();
BT_INFO("RFCOMM socket layer initialized");
+
return 0;
+
+error:
+ BT_ERR("RFCOMM socket layer registration failed");
+ proto_unregister(&rfcomm_proto);
+ return err;
}
void __exit rfcomm_cleanup_sockets(void)
{
- int err;
-
rfcomm_sock_proc_cleanup();
- /* Unregister socket, protocol and notifier */
- if ((err = bt_sock_unregister(BTPROTO_RFCOMM)))
- BT_ERR("RFCOMM socket layer unregistration failed. %d", err);
+ if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
+ BT_ERR("RFCOMM socket layer unregistration failed");
+
+ proto_unregister(&rfcomm_proto);
}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index d1361367d74955..9d59df1fe545be 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -413,19 +413,23 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
sk->sk_type = parent->sk_type;
}
+static struct proto sco_proto = {
+ .name = "SCO",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct sco_pinfo)
+};
+
static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
{
struct sock *sk;
- sk = sk_alloc(PF_BLUETOOTH, prio, sizeof(struct sco_pinfo), NULL);
+ sk = sk_alloc(PF_BLUETOOTH, prio, &sco_proto, 1);
if (!sk)
return NULL;
sock_init_data(sock, sk);
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
- sk_set_owner(sk, THIS_MODULE);
-
sk->sk_destruct = sco_sock_destruct;
sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
@@ -1015,14 +1019,21 @@ static int __init sco_init(void)
{
int err;
- if ((err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
- BT_ERR("SCO socket registration failed");
+ err = proto_register(&sco_proto, 0);
+ if (err < 0)
return err;
+
+ err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
+ if (err < 0) {
+ BT_ERR("SCO socket registration failed");
+ goto error;
}
- if ((err = hci_register_proto(&sco_hci_proto))) {
+ err = hci_register_proto(&sco_hci_proto);
+ if (err < 0) {
BT_ERR("SCO protocol registration failed");
- return err;
+ bt_sock_unregister(BTPROTO_SCO);
+ goto error;
}
sco_proc_init();
@@ -1031,20 +1042,23 @@ static int __init sco_init(void)
BT_INFO("SCO socket layer initialized");
return 0;
+
+error:
+ proto_unregister(&sco_proto);
+ return err;
}
static void __exit sco_exit(void)
{
- int err;
-
sco_proc_cleanup();
- /* Unregister socket, protocol and notifier */
- if ((err = bt_sock_unregister(BTPROTO_SCO)))
- BT_ERR("SCO socket unregistration failed. %d", err);
+ if (bt_sock_unregister(BTPROTO_SCO) < 0)
+ BT_ERR("SCO socket unregistration failed");
+
+ if (hci_unregister_proto(&sco_hci_proto) < 0)
+ BT_ERR("SCO protocol unregistration failed");
- if ((err = hci_unregister_proto(&sco_hci_proto)))
- BT_ERR("SCO protocol unregistration failed. %d", err);
+ proto_unregister(&sco_proto);
}
module_init(sco_init);
diff --git a/net/core/sock.c b/net/core/sock.c
index 18365fb8853f98..29e8a34d83edb4 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -99,6 +99,8 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
@@ -613,48 +615,36 @@ lenout:
return 0;
}
-static kmem_cache_t *sk_cachep;
-
/**
* sk_alloc - All socket objects are allocated here
* @family - protocol family
* @priority - for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
- * @zero_it - zeroes the allocated sock
- * @slab - alternate slab
- *
- * All socket objects are allocated here. If @zero_it is non-zero
- * it should have the size of the are to be zeroed, because the
- * private slabcaches have different sizes of the generic struct sock.
- * 1 has been kept as a way to say sizeof(struct sock).
+ * @prot - struct proto associated with this new sock instance
+ * @zero_it - if we should zero the newly allocated sock
*/
-struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab)
+struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
{
struct sock *sk = NULL;
-
- /*
- * Transitional, this test will be removed when sk_cachep is killed
- */
- if (slab == NULL && zero_it == 1)
- slab = sk_cachep;
+ kmem_cache_t *slab = prot->slab;
if (slab != NULL)
sk = kmem_cache_alloc(slab, priority);
else
- sk = kmalloc(zero_it, priority);
+ sk = kmalloc(prot->obj_size, priority);
if (sk) {
if (zero_it) {
- memset(sk, 0,
- zero_it == 1 ? sizeof(struct sock) : zero_it);
+ memset(sk, 0, prot->obj_size);
sk->sk_family = family;
+ sk->sk_prot = prot;
sock_lock_init(sk);
}
- sk->sk_slab = slab;
if (security_sk_alloc(sk, family, priority)) {
kmem_cache_free(slab, sk);
sk = NULL;
- }
+ } else
+ __module_get(prot->owner);
}
return sk;
}
@@ -662,7 +652,7 @@ struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab)
void sk_free(struct sock *sk)
{
struct sk_filter *filter;
- struct module *owner = sk->sk_owner;
+ struct module *owner = sk->sk_prot->owner;
if (sk->sk_destruct)
sk->sk_destruct(sk);
@@ -680,8 +670,8 @@ void sk_free(struct sock *sk)
__FUNCTION__, atomic_read(&sk->sk_omem_alloc));
security_sk_free(sk);
- if (sk->sk_slab != NULL)
- kmem_cache_free(sk->sk_slab, sk);
+ if (sk->sk_prot->slab != NULL)
+ kmem_cache_free(sk->sk_prot->slab, sk);
else
kfree(sk);
module_put(owner);
@@ -689,11 +679,6 @@ void sk_free(struct sock *sk)
void __init sk_init(void)
{
- sk_cachep = kmem_cache_create("sock", sizeof(struct sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if (!sk_cachep)
- printk(KERN_CRIT "sk_init: Cannot create sock SLAB cache!");
-
if (num_physpages <= 4096) {
sysctl_wmem_max = 32767;
sysctl_rmem_max = 32767;
@@ -1227,7 +1212,6 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_rcvlowat = 1;
sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
- sk->sk_owner = NULL;
sk->sk_stamp.tv_sec = -1L;
sk->sk_stamp.tv_usec = -1L;
@@ -1368,32 +1352,183 @@ void sk_common_release(struct sock *sk)
EXPORT_SYMBOL(sk_common_release);
-int sk_alloc_slab(struct proto *prot, char *name)
+static rwlock_t proto_list_lock;
+static LIST_HEAD(proto_list);
+
+int proto_register(struct proto *prot, int alloc_slab)
{
- prot->slab = kmem_cache_create(name,
- prot->slab_obj_size, 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
+ int rc = -ENOBUFS;
- if (prot->slab == NULL) {
- printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
- prot->name);
- return -ENOBUFS;
+ write_lock(&proto_list_lock);
+
+ if (alloc_slab) {
+ prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+ if (prot->slab == NULL) {
+ printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
+ prot->name);
+ goto out_unlock;
+ }
}
- return 0;
+ list_add(&prot->node, &proto_list);
+ rc = 0;
+out_unlock:
+ write_unlock(&proto_list_lock);
+ return rc;
}
-EXPORT_SYMBOL(sk_alloc_slab);
+EXPORT_SYMBOL(proto_register);
-void sk_free_slab(struct proto *prot)
+void proto_unregister(struct proto *prot)
{
+ write_lock(&proto_list_lock);
+
if (prot->slab != NULL) {
kmem_cache_destroy(prot->slab);
prot->slab = NULL;
}
+
+ list_del(&prot->node);
+ write_unlock(&proto_list_lock);
+}
+
+EXPORT_SYMBOL(proto_unregister);
+
+#ifdef CONFIG_PROC_FS
+static inline struct proto *__proto_head(void)
+{
+ return list_entry(proto_list.next, struct proto, node);
+}
+
+static inline struct proto *proto_head(void)
+{
+ return list_empty(&proto_list) ? NULL : __proto_head();
+}
+
+static inline struct proto *proto_next(struct proto *proto)
+{
+ return proto->node.next == &proto_list ? NULL :
+ list_entry(proto->node.next, struct proto, node);
+}
+
+static inline struct proto *proto_get_idx(loff_t pos)
+{
+ struct proto *proto;
+ loff_t i = 0;
+
+ list_for_each_entry(proto, &proto_list, node)
+ if (i++ == pos)
+ goto out;
+
+ proto = NULL;
+out:
+ return proto;
}
-EXPORT_SYMBOL(sk_free_slab);
+static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ read_lock(&proto_list_lock);
+ return *pos ? proto_get_idx(*pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ return v == SEQ_START_TOKEN ? proto_head() : proto_next(v);
+}
+
+static void proto_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock(&proto_list_lock);
+}
+
+static char proto_method_implemented(const void *method)
+{
+ return method == NULL ? 'n' : 'y';
+}
+
+static void proto_seq_printf(struct seq_file *seq, struct proto *proto)
+{
+ seq_printf(seq, "%-9s %4u %6d %6d %-3s %6u %-3s %-10s "
+ "%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n",
+ proto->name,
+ proto->obj_size,
+ proto->sockets_allocated != NULL ? atomic_read(proto->sockets_allocated) : -1,
+ proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1,
+ proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI",
+ proto->max_header,
+ proto->slab == NULL ? "no" : "yes",
+ module_name(proto->owner),
+ proto_method_implemented(proto->close),
+ proto_method_implemented(proto->connect),
+ proto_method_implemented(proto->disconnect),
+ proto_method_implemented(proto->accept),
+ proto_method_implemented(proto->ioctl),
+ proto_method_implemented(proto->init),
+ proto_method_implemented(proto->destroy),
+ proto_method_implemented(proto->shutdown),
+ proto_method_implemented(proto->setsockopt),
+ proto_method_implemented(proto->getsockopt),
+ proto_method_implemented(proto->sendmsg),
+ proto_method_implemented(proto->recvmsg),
+ proto_method_implemented(proto->sendpage),
+ proto_method_implemented(proto->bind),
+ proto_method_implemented(proto->backlog_rcv),
+ proto_method_implemented(proto->hash),
+ proto_method_implemented(proto->unhash),
+ proto_method_implemented(proto->get_port),
+ proto_method_implemented(proto->enter_memory_pressure));
+}
+
+static int proto_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-9s %-4s %-8s %-6s %-5s %-7s %-4s %-10s %s",
+ "protocol",
+ "size",
+ "sockets",
+ "memory",
+ "press",
+ "maxhdr",
+ "slab",
+ "module",
+ "cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n");
+ else
+ proto_seq_printf(seq, v);
+ return 0;
+}
+
+static struct seq_operations proto_seq_ops = {
+ .start = proto_seq_start,
+ .next = proto_seq_next,
+ .stop = proto_seq_stop,
+ .show = proto_seq_show,
+};
+
+static int proto_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &proto_seq_ops);
+}
+
+static struct file_operations proto_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = proto_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int __init proto_init(void)
+{
+ /* register /proc/net/protocols */
+ return proc_net_fops_create("protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
+}
+
+subsys_initcall(proto_init);
+
+#endif /* PROC_FS */
EXPORT_SYMBOL(sk_alloc);
EXPORT_SYMBOL(sk_free);
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 442075a7eaec01..29bb3cd219655b 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -149,7 +149,6 @@ static void dn_keepalive(struct sock *sk);
#define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
-static kmem_cache_t *dn_sk_cachep;
static struct proto_ops dn_proto_ops;
static DEFINE_RWLOCK(dn_hash_lock);
static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
@@ -447,11 +446,16 @@ static void dn_destruct(struct sock *sk)
dst_release(xchg(&sk->sk_dst_cache, NULL));
}
+static struct proto dn_proto = {
+ .name = "DECNET",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct dn_sock),
+};
+
static struct sock *dn_alloc_sock(struct socket *sock, int gfp)
{
struct dn_scp *scp;
- struct sock *sk = sk_alloc(PF_DECnet, gfp, sizeof(struct dn_sock),
- dn_sk_cachep);
+ struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1);
if (!sk)
goto out;
@@ -459,7 +463,6 @@ static struct sock *dn_alloc_sock(struct socket *sock, int gfp)
if (sock)
sock->ops = &dn_proto_ops;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_backlog_rcv = dn_nsp_backlog_rcv;
sk->sk_destruct = dn_destruct;
@@ -2349,14 +2352,13 @@ static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (
static int __init decnet_init(void)
{
+ int rc;
+
printk(banner);
- dn_sk_cachep = kmem_cache_create("decnet_socket_cache",
- sizeof(struct dn_sock),
- 0, SLAB_HWCACHE_ALIGN,
- NULL, NULL);
- if (!dn_sk_cachep)
- return -ENOMEM;
+ rc = proto_register(&dn_proto, 1);
+ if (rc != 0)
+ goto out;
dn_neigh_init();
dn_dev_init();
@@ -2369,8 +2371,8 @@ static int __init decnet_init(void)
proc_net_fops_create("decnet", S_IRUGO, &dn_socket_seq_fops);
dn_register_sysctl();
-
- return 0;
+out:
+ return rc;
}
module_init(decnet_init);
@@ -2397,7 +2399,7 @@ static void __exit decnet_exit(void)
proc_net_remove("decnet");
- kmem_cache_destroy(dn_sk_cachep);
+ proto_unregister(&dn_proto);
}
module_exit(decnet_exit);
#endif
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 70f01713d89b08..de691e119e173f 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -555,6 +555,12 @@ static int econet_release(struct socket *sock)
return 0;
}
+static struct proto econet_proto = {
+ .name = "ECONET",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct econet_sock),
+};
+
/*
* Create an Econet socket
*/
@@ -572,15 +578,13 @@ static int econet_create(struct socket *sock, int protocol)
sock->state = SS_UNCONNECTED;
err = -ENOBUFS;
- sk = sk_alloc(PF_ECONET, GFP_KERNEL,
- sizeof(struct econet_sock), NULL);
+ sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
if (sk == NULL)
goto out;
sk->sk_reuse = 1;
sock->ops = &econet_ops;
- sock_init_data(sock,sk);
- sk_set_owner(sk, THIS_MODULE);
+ sock_init_data(sock, sk);
eo = ec_sk(sk);
sock_reset_flag(sk, SOCK_ZAPPED);
@@ -1096,10 +1100,15 @@ static void __exit econet_proto_exit(void)
#endif
unregister_netdevice_notifier(&econet_netdev_notifier);
sock_unregister(econet_family_ops.family);
+ proto_unregister(&econet_proto);
}
static int __init econet_proto_init(void)
{
+ int err = proto_register(&econet_proto, 0);
+
+ if (err != 0)
+ goto out;
sock_register(&econet_family_ops);
#ifdef CONFIG_ECONET_AUNUDP
spin_lock_init(&aun_queue_lock);
@@ -1109,7 +1118,8 @@ static int __init econet_proto_init(void)
econet_hw_initialise();
#endif
register_netdevice_notifier(&econet_netdev_notifier);
- return 0;
+out:
+ return err;
}
module_init(econet_proto_init);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index aa4fb251c54c7c..c34dab67e4612a 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -281,14 +281,11 @@ static int inet_create(struct socket *sock, int protocol)
BUG_TRAP(answer_prot->slab != NULL);
err = -ENOBUFS;
- sk = sk_alloc(PF_INET, GFP_KERNEL,
- answer_prot->slab_obj_size,
- answer_prot->slab);
+ sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
if (sk == NULL)
goto out;
err = 0;
- sk->sk_prot = answer_prot;
sk->sk_no_check = answer_no_check;
if (INET_PROTOSW_REUSE & answer_flags)
sk->sk_reuse = 1;
@@ -309,7 +306,6 @@ static int inet_create(struct socket *sock, int protocol)
inet->id = 0;
sock_init_data(sock, sk);
- sk_set_owner(sk, sk->sk_prot->owner);
sk->sk_destruct = inet_sock_destruct;
sk->sk_family = PF_INET;
@@ -1026,17 +1022,17 @@ static int __init inet_init(void)
goto out;
}
- rc = sk_alloc_slab(&tcp_prot, "tcp_sock");
+ rc = proto_register(&tcp_prot, 1);
if (rc)
goto out;
- rc = sk_alloc_slab(&udp_prot, "udp_sock");
+ rc = proto_register(&udp_prot, 1);
if (rc)
- goto out_tcp_free_slab;
+ goto out_unregister_tcp_proto;
- rc = sk_alloc_slab(&raw_prot, "raw_sock");
+ rc = proto_register(&raw_prot, 1);
if (rc)
- goto out_udp_free_slab;
+ goto out_unregister_udp_proto;
/*
* Tell SOCKET that we are alive...
@@ -1110,10 +1106,10 @@ static int __init inet_init(void)
rc = 0;
out:
return rc;
-out_tcp_free_slab:
- sk_free_slab(&tcp_prot);
-out_udp_free_slab:
- sk_free_slab(&udp_prot);
+out_unregister_tcp_proto:
+ proto_unregister(&tcp_prot);
+out_unregister_udp_proto:
+ proto_unregister(&udp_prot);
goto out;
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 1e71ed6507fd48..93624a32eb9ae3 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -724,7 +724,7 @@ struct proto raw_prot = {
.backlog_rcv = raw_rcv_skb,
.hash = raw_v4_hash,
.unhash = raw_v4_unhash,
- .slab_obj_size = sizeof(struct raw_sock),
+ .obj_size = sizeof(struct raw_sock),
};
#ifdef CONFIG_PROC_FS
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 4b87a4f11f4656..e923d2f021aa8b 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -179,10 +179,9 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
struct sock *child;
child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
- if (child) {
- sk_set_owner(child, sk->sk_owner);
+ if (child)
tcp_acceptq_queue(sk, req, child);
- } else
+ else
tcp_openreq_free(req);
return child;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fa30d1d83d0377..3ac6659869c41e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2614,7 +2614,7 @@ struct proto tcp_prot = {
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
- .slab_obj_size = sizeof(struct tcp_sock),
+ .obj_size = sizeof(struct tcp_sock),
};
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 2faf1a9c3eba26..fd70509f0d53df 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -688,8 +688,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
{
/* allocate the newsk from the same slab of the master sock,
* if not, at sk_free time we'll try to free it from the wrong
- * slabcache (i.e. is it TCPv4 or v6?) -acme */
- struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, 0, sk->sk_prot->slab);
+ * slabcache (i.e. is it TCPv4 or v6?), this is handled thru sk->sk_prot -acme */
+ struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, sk->sk_prot, 0);
if(newsk != NULL) {
struct tcp_sock *newtp;
@@ -807,7 +807,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
keepalive_time_when(newtp));
newsk->sk_socket = NULL;
newsk->sk_sleep = NULL;
- newsk->sk_owner = NULL;
newtp->rx_opt.tstamp_ok = req->tstamp_ok;
if((newtp->rx_opt.sack_ok = req->sack_ok) != 0) {
@@ -1019,7 +1018,6 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
if (child == NULL)
goto listen_overflow;
- sk_set_owner(child, sk->sk_owner);
tcp_synq_unlink(tp, req, prev);
tcp_synq_removed(sk, req);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index eac0bd84d7a674..6baddfbedca3f9 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1371,7 +1371,7 @@ struct proto udp_prot = {
.hash = udp_v4_hash,
.unhash = udp_v4_unhash,
.get_port = udp_v4_get_port,
- .slab_obj_size = sizeof(struct udp_sock),
+ .obj_size = sizeof(struct udp_sock),
};
/* ------------------------------------------------------------------------ */
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2f1e7b439e2f4c..768b11703daf7f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -107,7 +107,7 @@ static void inet6_sock_destruct(struct sock *sk)
static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
{
- const int offset = sk->sk_prot->slab_obj_size - sizeof(struct ipv6_pinfo);
+ const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo);
return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
}
@@ -166,15 +166,11 @@ static int inet6_create(struct socket *sock, int protocol)
BUG_TRAP(answer_prot->slab != NULL);
rc = -ENOBUFS;
- sk = sk_alloc(PF_INET6, GFP_KERNEL,
- answer_prot->slab_obj_size,
- answer_prot->slab);
+ sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
if (sk == NULL)
goto out;
sock_init_data(sock, sk);
- sk->sk_prot = answer_prot;
- sk_set_owner(sk, sk->sk_prot->owner);
rc = 0;
sk->sk_no_check = answer_no_check;
@@ -710,17 +706,17 @@ static int __init inet6_init(void)
return -EINVAL;
}
- err = sk_alloc_slab(&tcpv6_prot, "tcpv6_sock");
+ err = proto_register(&tcpv6_prot, 1);
if (err)
goto out;
- err = sk_alloc_slab(&udpv6_prot, "udpv6_sock");
+ err = proto_register(&udpv6_prot, 1);
if (err)
- goto out_tcp_free_slab;
+ goto out_unregister_tcp_proto;
- err = sk_alloc_slab(&rawv6_prot, "rawv6_sock");
+ err = proto_register(&rawv6_prot, 1);
if (err)
- goto out_udp_free_slab;
+ goto out_unregister_udp_proto;
/* Register the socket-side information for inet6_create. */
@@ -740,7 +736,7 @@ static int __init inet6_init(void)
/* Initialise ipv6 mibs */
err = init_ipv6_mibs();
if (err)
- goto out_raw_free_slab;
+ goto out_unregister_raw_proto;
/*
* ipngwg API draft makes clear that the correct semantics
@@ -827,12 +823,12 @@ icmp_fail:
ipv6_sysctl_unregister();
#endif
cleanup_ipv6_mibs();
-out_raw_free_slab:
- sk_free_slab(&rawv6_prot);
-out_udp_free_slab:
- sk_free_slab(&udpv6_prot);
-out_tcp_free_slab:
- sk_free_slab(&tcpv6_prot);
+out_unregister_raw_proto:
+ proto_unregister(&rawv6_prot);
+out_unregister_udp_proto:
+ proto_unregister(&udpv6_prot);
+out_unregister_tcp_proto:
+ proto_unregister(&tcpv6_prot);
goto out;
}
module_init(inet6_init);
@@ -862,9 +858,9 @@ static void __exit inet6_exit(void)
ipv6_sysctl_unregister();
#endif
cleanup_ipv6_mibs();
- sk_free_slab(&rawv6_prot);
- sk_free_slab(&udpv6_prot);
- sk_free_slab(&tcpv6_prot);
+ proto_unregister(&rawv6_prot);
+ proto_unregister(&udpv6_prot);
+ proto_unregister(&tcpv6_prot);
}
module_exit(inet6_exit);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a8b4acfab951b5..5488ad0de4f6bd 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -977,7 +977,7 @@ static int rawv6_init_sk(struct sock *sk)
}
struct proto rawv6_prot = {
- .name = "RAW",
+ .name = "RAWv6",
.owner = THIS_MODULE,
.close = rawv6_close,
.connect = ip6_datagram_connect,
@@ -993,7 +993,7 @@ struct proto rawv6_prot = {
.backlog_rcv = rawv6_rcv_skb,
.hash = raw_v6_hash,
.unhash = raw_v6_unhash,
- .slab_obj_size = sizeof(struct raw6_sock),
+ .obj_size = sizeof(struct raw6_sock),
};
#ifdef CONFIG_PROC_FS
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 40a50e82ed55aa..4760c85e19db83 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2235,7 +2235,7 @@ struct proto tcpv6_prot = {
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
- .slab_obj_size = sizeof(struct tcp6_sock),
+ .obj_size = sizeof(struct tcp6_sock),
};
static struct inet6_protocol tcpv6_protocol = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index badbcc26c338ae..e251d0ba4f3936 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1036,7 +1036,7 @@ void udp6_proc_exit(void) {
/* ------------------------------------------------------------------------ */
struct proto udpv6_prot = {
- .name = "UDP",
+ .name = "UDPv6",
.owner = THIS_MODULE,
.close = udpv6_close,
.connect = ip6_datagram_connect,
@@ -1051,7 +1051,7 @@ struct proto udpv6_prot = {
.hash = udp_v6_hash,
.unhash = udp_v6_unhash,
.get_port = udp_v6_get_port,
- .slab_obj_size = sizeof(struct udp6_sock),
+ .obj_size = sizeof(struct udp6_sock),
};
extern struct proto_ops inet6_dgram_ops;
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 65309f9d9e532d..5a27e5df5886e9 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -80,8 +80,6 @@ static struct proto_ops ipx_dgram_ops;
LIST_HEAD(ipx_interfaces);
DEFINE_SPINLOCK(ipx_interfaces_lock);
-static kmem_cache_t *ipx_sk_slab;
-
struct ipx_interface *ipx_primary_net;
struct ipx_interface *ipx_internal_net;
@@ -1347,6 +1345,12 @@ out:
return rc;
}
+static struct proto ipx_proto = {
+ .name = "IPX",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct ipx_sock),
+};
+
static int ipx_create(struct socket *sock, int protocol)
{
int rc = -ESOCKTNOSUPPORT;
@@ -1361,8 +1365,8 @@ static int ipx_create(struct socket *sock, int protocol)
if (sock->type != SOCK_DGRAM)
goto out;
- sk = sk_alloc(PF_IPX, GFP_KERNEL, sizeof(struct ipx_sock), ipx_sk_slab);
rc = -ENOMEM;
+ sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1);
if (!sk)
goto out;
#ifdef IPX_REFCNT_DEBUG
@@ -1371,7 +1375,6 @@ static int ipx_create(struct socket *sock, int protocol)
atomic_read(&ipx_sock_nr));
#endif
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_no_check = 1; /* Checksum off by default */
sock->ops = &ipx_dgram_ops;
rc = 0;
@@ -1954,12 +1957,10 @@ static char ipx_snap_err_msg[] __initdata =
static int __init ipx_init(void)
{
- ipx_sk_slab = kmem_cache_create("ipx_sock",
- sizeof(struct ipx_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
+ int rc = proto_register(&ipx_proto, 1);
- if (ipx_sk_slab == NULL)
- return -ENOMEM;
+ if (rc != 0)
+ goto out;
sock_register(&ipx_family_ops);
@@ -1986,7 +1987,8 @@ static int __init ipx_init(void)
register_netdevice_notifier(&ipx_dev_notifier);
ipx_register_sysctl();
ipx_proc_init();
- return 0;
+out:
+ return rc;
}
static void __exit ipx_proto_finito(void)
@@ -2012,11 +2014,7 @@ static void __exit ipx_proto_finito(void)
destroy_EII_client(pEII_datalink);
pEII_datalink = NULL;
- if (ipx_sk_slab != NULL) {
- kmem_cache_destroy(ipx_sk_slab);
- ipx_sk_slab = NULL;
- }
-
+ proto_unregister(&ipx_proto);
sock_unregister(ipx_family_ops.family);
}
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index a6f32b96d3b56c..92c6e8d4e731b1 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1071,6 +1071,12 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
return 0;
}
+static struct proto irda_proto = {
+ .name = "IRDA",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct irda_sock),
+};
+
/*
* Function irda_create (sock, protocol)
*
@@ -1095,8 +1101,7 @@ static int irda_create(struct socket *sock, int protocol)
}
/* Allocate networking socket */
- sk = sk_alloc(PF_IRDA, GFP_ATOMIC,
- sizeof(struct irda_sock), NULL);
+ sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
if (sk == NULL)
return -ENOMEM;
@@ -1107,7 +1112,6 @@ static int irda_create(struct socket *sock, int protocol)
/* Initialise networking socket struct */
sock_init_data(sock, sk); /* Note : set sk->sk_refcnt to 1 */
- sk_set_owner(sk, THIS_MODULE);
sk->sk_family = PF_IRDA;
sk->sk_protocol = protocol;
@@ -2561,9 +2565,12 @@ SOCKOPS_WRAP(irda_ultra, PF_IRDA);
*/
int __init irsock_init(void)
{
- sock_register(&irda_family_ops);
+ int rc = proto_register(&irda_proto, 0);
- return 0;
+ if (rc == 0)
+ rc = sock_register(&irda_family_ops);
+
+ return rc;
}
/*
@@ -2575,6 +2582,5 @@ int __init irsock_init(void)
void __exit irsock_cleanup(void)
{
sock_unregister(PF_IRDA);
-
- return;
+ proto_unregister(&irda_proto);
}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 6682c7e261acb1..ce980aa94ed8e4 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -129,6 +129,12 @@ static void pfkey_remove(struct sock *sk)
pfkey_table_ungrab();
}
+static struct proto key_proto = {
+ .name = "KEY",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct pfkey_sock),
+};
+
static int pfkey_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -142,13 +148,12 @@ static int pfkey_create(struct socket *sock, int protocol)
return -EPROTONOSUPPORT;
err = -ENOMEM;
- sk = sk_alloc(PF_KEY, GFP_KERNEL, sizeof(struct pfkey_sock), NULL);
+ sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
if (sk == NULL)
goto out;
sock->ops = &pfkey_ops;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_family = PF_KEY;
sk->sk_destruct = pfkey_sock_destruct;
@@ -2858,16 +2863,38 @@ static void __exit ipsec_pfkey_exit(void)
xfrm_unregister_km(&pfkeyv2_mgr);
remove_proc_entry("net/pfkey", NULL);
sock_unregister(PF_KEY);
+ proto_unregister(&key_proto);
}
static int __init ipsec_pfkey_init(void)
{
- sock_register(&pfkey_family_ops);
+ int err = proto_register(&key_proto, 0);
+
+ if (err != 0)
+ goto out;
+
+ err = sock_register(&pfkey_family_ops);
+ if (err != 0)
+ goto out_unregister_key_proto;
#ifdef CONFIG_PROC_FS
- create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL);
+ err = -ENOMEM;
+ if (create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL) == NULL)
+ goto out_sock_unregister;
#endif
- xfrm_register_km(&pfkeyv2_mgr);
- return 0;
+ err = xfrm_register_km(&pfkeyv2_mgr);
+ if (err != 0)
+ goto out_remove_proc_entry;
+out:
+ return err;
+out_remove_proc_entry:
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry("net/pfkey", NULL);
+out_sock_unregister:
+#endif
+ sock_unregister(PF_KEY);
+out_unregister_key_proto:
+ proto_unregister(&key_proto);
+ goto out;
}
module_init(ipsec_pfkey_init);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 2e11283e5062e1..20b4cfebd74ca5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -135,6 +135,12 @@ static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
sock->ops = &llc_ui_ops;
}
+static struct proto llc_proto = {
+ .name = "DDP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct llc_sock),
+};
+
/**
* llc_ui_create - alloc and init a new llc_ui socket
* @sock: Socket to initialize and attach allocated sk to.
@@ -151,7 +157,7 @@ static int llc_ui_create(struct socket *sock, int protocol)
if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) {
rc = -ENOMEM;
- sk = llc_sk_alloc(PF_LLC, GFP_KERNEL);
+ sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
if (sk) {
rc = 0;
llc_ui_sk_init(sock, sk);
@@ -1033,18 +1039,25 @@ extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
static int __init llc2_init(void)
{
- int rc;
+ int rc = proto_register(&llc_proto, 0);
+
+ if (rc != 0)
+ goto out;
llc_build_offset_table();
llc_station_init();
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
rc = llc_proc_init();
- if (!rc) {
- sock_register(&llc_ui_family_ops);
- llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
- llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
- }
+ if (rc != 0)
+ goto out_unregister_llc_proto;
+ sock_register(&llc_ui_family_ops);
+ llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
+ llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
+out:
return rc;
+out_unregister_llc_proto:
+ proto_unregister(&llc_proto);
+ goto out;
}
static void __exit llc2_exit(void)
@@ -1054,6 +1067,7 @@ static void __exit llc2_exit(void)
llc_remove_pack(LLC_DEST_CONN);
sock_unregister(PF_LLC);
llc_proc_exit();
+ proto_unregister(&llc_proto);
}
module_init(llc2_init);
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index cc587ebf42c15a..eba812a9c69c6e 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -683,7 +683,7 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
goto drop;
}
- sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC);
+ sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC, parent->sk_prot);
if (!sk) {
sock_put(parent);
goto drop;
@@ -830,16 +830,14 @@ static void llc_sk_init(struct sock* sk)
* Allocates a LLC sock and initializes it. Returns the new LLC sock
* or %NULL if there's no memory available for one
*/
-struct sock *llc_sk_alloc(int family, int priority)
+struct sock *llc_sk_alloc(int family, int priority, struct proto *prot)
{
- struct sock *sk = sk_alloc(family, priority,
- sizeof(struct llc_sock), NULL);
+ struct sock *sk = sk_alloc(family, priority, prot, 1);
if (!sk)
goto out;
llc_sk_init(sk);
sock_init_data(NULL, sk);
- sk_set_owner(sk, THIS_MODULE);
#ifdef LLC_REFCNT_DEBUG
atomic_inc(&llc_sock_nr);
printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 81f3a4c9c43e4b..1d5089f92a5121 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -321,6 +321,12 @@ static void netlink_remove(struct sock *sk)
netlink_table_ungrab();
}
+static struct proto netlink_proto = {
+ .name = "NETLINK",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct netlink_sock),
+};
+
static int netlink_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -336,13 +342,11 @@ static int netlink_create(struct socket *sock, int protocol)
sock->ops = &netlink_ops;
- sk = sk_alloc(PF_NETLINK, GFP_KERNEL,
- sizeof(struct netlink_sock), NULL);
+ sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
if (!sk)
return -ENOMEM;
- sock_init_data(sock,sk);
- sk_set_owner(sk, THIS_MODULE);
+ sock_init_data(sock, sk);
nlk = nlk_sk(sk);
@@ -1369,6 +1373,10 @@ static int __init netlink_proto_init(void)
int i;
unsigned long max;
unsigned int order;
+ int err = proto_register(&netlink_proto, 0);
+
+ if (err != 0)
+ goto out;
if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb))
netlink_skb_parms_too_large();
@@ -1415,15 +1423,17 @@ enomem:
#endif
/* The netlink device handler may be needed early. */
rtnetlink_init();
- return 0;
+out:
+ return err;
}
static void __exit netlink_proto_exit(void)
{
- sock_unregister(PF_NETLINK);
- proc_net_remove("netlink");
- kfree(nl_table);
- nl_table = NULL;
+ sock_unregister(PF_NETLINK);
+ proc_net_remove("netlink");
+ kfree(nl_table);
+ nl_table = NULL;
+ proto_unregister(&netlink_proto);
}
core_initcall(netlink_proto_init);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 024217b2f9e583..31ed4a9a1d066c 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -64,11 +64,6 @@ static DEFINE_SPINLOCK(nr_list_lock);
static struct proto_ops nr_proto_ops;
-static struct sock *nr_alloc_sock(void)
-{
- return sk_alloc(PF_NETROM, GFP_ATOMIC, sizeof(struct nr_sock), NULL);
-}
-
/*
* Socket removal during an interrupt is now safe.
*/
@@ -398,6 +393,12 @@ static int nr_listen(struct socket *sock, int backlog)
return -EOPNOTSUPP;
}
+static struct proto nr_proto = {
+ .name = "NETROM",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct nr_sock),
+};
+
static int nr_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -406,13 +407,12 @@ static int nr_create(struct socket *sock, int protocol)
if (sock->type != SOCK_SEQPACKET || protocol != 0)
return -ESOCKTNOSUPPORT;
- if ((sk = nr_alloc_sock()) == NULL)
+ if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
return -ENOMEM;
nr = nr_sk(sk);
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
sock->ops = &nr_proto_ops;
sk->sk_protocol = protocol;
@@ -444,13 +444,12 @@ static struct sock *nr_make_new(struct sock *osk)
if (osk->sk_type != SOCK_SEQPACKET)
return NULL;
- if ((sk = nr_alloc_sock()) == NULL)
+ if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
return NULL;
nr = nr_sk(sk);
sock_init_data(NULL, sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_type = osk->sk_type;
sk->sk_socket = osk->sk_socket;
@@ -1368,6 +1367,10 @@ static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.
static int __init nr_proto_init(void)
{
int i;
+ int rc = proto_register(&nr_proto, 0);
+
+ if (rc != 0)
+ goto out;
if (nr_ndevs > 0x7fffffff/sizeof(struct net_device *)) {
printk(KERN_ERR "NET/ROM: nr_proto_init - nr_ndevs parameter to large\n");
@@ -1423,15 +1426,17 @@ static int __init nr_proto_init(void)
proc_net_fops_create("nr", S_IRUGO, &nr_info_fops);
proc_net_fops_create("nr_neigh", S_IRUGO, &nr_neigh_fops);
proc_net_fops_create("nr_nodes", S_IRUGO, &nr_nodes_fops);
- return 0;
-
- fail:
+out:
+ return rc;
+fail:
while (--i >= 0) {
unregister_netdev(dev_nr[i]);
free_netdev(dev_nr[i]);
}
kfree(dev_nr);
- return -1;
+ proto_unregister(&nr_proto);
+ rc = -1;
+ goto out;
}
module_init(nr_proto_init);
@@ -1475,5 +1480,6 @@ static void __exit nr_exit(void)
}
kfree(dev_nr);
+ proto_unregister(&nr_proto);
}
module_exit(nr_exit);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 1c994ed5cf3561..64acea0adaaea6 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -955,6 +955,11 @@ out:
return err;
}
+static struct proto packet_proto = {
+ .name = "PACKET",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct packet_sock),
+};
/*
* Create a packet of type SOCK_PACKET.
@@ -978,8 +983,7 @@ static int packet_create(struct socket *sock, int protocol)
sock->state = SS_UNCONNECTED;
err = -ENOBUFS;
- sk = sk_alloc(PF_PACKET, GFP_KERNEL,
- sizeof(struct packet_sock), NULL);
+ sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
if (sk == NULL)
goto out;
@@ -988,8 +992,7 @@ static int packet_create(struct socket *sock, int protocol)
if (sock->type == SOCK_PACKET)
sock->ops = &packet_ops_spkt;
#endif
- sock_init_data(sock,sk);
- sk_set_owner(sk, THIS_MODULE);
+ sock_init_data(sock, sk);
po = pkt_sk(sk);
sk->sk_family = PF_PACKET;
@@ -1881,16 +1884,21 @@ static void __exit packet_exit(void)
proc_net_remove("packet");
unregister_netdevice_notifier(&packet_netdev_notifier);
sock_unregister(PF_PACKET);
- return;
+ proto_unregister(&packet_proto);
}
static int __init packet_init(void)
{
+ int rc = proto_register(&packet_proto, 0);
+
+ if (rc != 0)
+ goto out;
+
sock_register(&packet_family_ops);
register_netdevice_notifier(&packet_netdev_notifier);
proc_net_fops_create("packet", 0, &packet_seq_fops);
-
- return 0;
+out:
+ return rc;
}
module_init(packet_init);
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 68da687c9142ad..7eb6a5bf93ea19 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -126,11 +126,6 @@ int rosecmpm(rose_address *addr1, rose_address *addr2, unsigned short mask)
return 0;
}
-static struct sock *rose_alloc_sock(void)
-{
- return sk_alloc(PF_ROSE, GFP_ATOMIC, sizeof(struct rose_sock), NULL);
-}
-
/*
* Socket removal during an interrupt is now safe.
*/
@@ -488,6 +483,12 @@ static int rose_listen(struct socket *sock, int backlog)
return -EOPNOTSUPP;
}
+static struct proto rose_proto = {
+ .name = "ROSE",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct rose_sock),
+};
+
static int rose_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -496,13 +497,12 @@ static int rose_create(struct socket *sock, int protocol)
if (sock->type != SOCK_SEQPACKET || protocol != 0)
return -ESOCKTNOSUPPORT;
- if ((sk = rose_alloc_sock()) == NULL)
+ if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
return -ENOMEM;
rose = rose_sk(sk);
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
skb_queue_head_init(&rose->ack_queue);
#ifdef M_BIT
@@ -535,13 +535,12 @@ static struct sock *rose_make_new(struct sock *osk)
if (osk->sk_type != SOCK_SEQPACKET)
return NULL;
- if ((sk = rose_alloc_sock()) == NULL)
+ if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
return NULL;
rose = rose_sk(sk);
sock_init_data(NULL, sk);
- sk_set_owner(sk, THIS_MODULE);
skb_queue_head_init(&rose->ack_queue);
#ifdef M_BIT
@@ -1472,6 +1471,10 @@ static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62
static int __init rose_proto_init(void)
{
int i;
+ int rc = proto_register(&rose_proto, 0);
+
+ if (rc != 0)
+ goto out;
rose_callsign = null_ax25_address;
@@ -1524,14 +1527,15 @@ static int __init rose_proto_init(void)
proc_net_fops_create("rose_neigh", S_IRUGO, &rose_neigh_fops);
proc_net_fops_create("rose_nodes", S_IRUGO, &rose_nodes_fops);
proc_net_fops_create("rose_routes", S_IRUGO, &rose_routes_fops);
-
- return 0;
+out:
+ return rc;
fail:
while (--i >= 0) {
unregister_netdev(dev_rose[i]);
free_netdev(dev_rose[i]);
}
kfree(dev_rose);
+ proto_unregister(&rose_proto);
return -ENOMEM;
}
module_init(rose_proto_init);
@@ -1579,6 +1583,7 @@ static void __exit rose_exit(void)
}
kfree(dev_rose);
+ proto_unregister(&rose_proto);
}
module_exit(rose_exit);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ee1be46dd57094..e42c74e3ec1e8f 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -594,13 +594,11 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
- newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot->slab_obj_size,
- sk->sk_prot->slab);
+ newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
if (!newsk)
goto out;
sock_init_data(NULL, newsk);
- sk_set_owner(newsk, THIS_MODULE);
newsk->sk_type = SOCK_STREAM;
@@ -974,14 +972,14 @@ static struct sctp_pf sctp_pf_inet6_specific = {
/* Initialize IPv6 support and register with inet6 stack. */
int sctp_v6_init(void)
{
- int rc = sk_alloc_slab(&sctpv6_prot, "sctpv6_sock");
+ int rc = proto_register(&sctpv6_prot, 1);
if (rc)
goto out;
/* Register inet6 protocol. */
rc = -EAGAIN;
if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0)
- goto out_sctp_free_slab;
+ goto out_unregister_sctp_proto;
/* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */
inet6_register_protosw(&sctpv6_seqpacket_protosw);
@@ -998,8 +996,8 @@ int sctp_v6_init(void)
rc = 0;
out:
return rc;
-out_sctp_free_slab:
- sk_free_slab(&sctpv6_prot);
+out_unregister_sctp_proto:
+ proto_unregister(&sctpv6_prot);
goto out;
}
@@ -1011,5 +1009,5 @@ void sctp_v6_exit(void)
inet6_unregister_protosw(&sctpv6_seqpacket_protosw);
inet6_unregister_protosw(&sctpv6_stream_protosw);
unregister_inet6addr_notifier(&sctp_inet6addr_notifier);
- sk_free_slab(&sctpv6_prot);
+ proto_unregister(&sctpv6_prot);
}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 49214c3b45f43b..b9813cf3d91c6e 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -550,21 +550,17 @@ static int sctp_v4_is_ce(const struct sk_buff *skb)
static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
struct sctp_association *asoc)
{
- struct sock *newsk;
struct inet_sock *inet = inet_sk(sk);
struct inet_sock *newinet;
+ struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1);
- newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot->slab_obj_size,
- sk->sk_prot->slab);
if (!newsk)
goto out;
sock_init_data(NULL, newsk);
- sk_set_owner(newsk, THIS_MODULE);
newsk->sk_type = SOCK_STREAM;
- newsk->sk_prot = sk->sk_prot;
newsk->sk_no_check = sk->sk_no_check;
newsk->sk_reuse = sk->sk_reuse;
newsk->sk_shutdown = sk->sk_shutdown;
@@ -970,7 +966,7 @@ SCTP_STATIC __init int sctp_init(void)
if (!sctp_sanity_check())
goto out;
- status = sk_alloc_slab(&sctp_prot, "sctp_sock");
+ status = proto_register(&sctp_prot, 1);
if (status)
goto out;
@@ -1164,7 +1160,7 @@ SCTP_STATIC __init int sctp_init(void)
out:
return status;
err_add_protocol:
- sk_free_slab(&sctp_prot);
+ proto_unregister(&sctp_prot);
err_ctl_sock_init:
sctp_v6_exit();
err_v6_init:
@@ -1233,7 +1229,7 @@ SCTP_STATIC __exit void sctp_exit(void)
inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
inet_unregister_protosw(&sctp_seqpacket_protosw);
inet_unregister_protosw(&sctp_stream_protosw);
- sk_free_slab(&sctp_prot);
+ proto_unregister(&sctp_prot);
}
module_init(sctp_init);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6f66ee49078460..e8c21018257105 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4768,7 +4768,7 @@ struct proto sctp_prot = {
.hash = sctp_hash,
.unhash = sctp_unhash,
.get_port = sctp_get_port,
- .slab_obj_size = sizeof(struct sctp_sock),
+ .obj_size = sizeof(struct sctp_sock),
};
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -4792,6 +4792,6 @@ struct proto sctpv6_prot = {
.hash = sctp_hash,
.unhash = sctp_unhash,
.get_port = sctp_get_port,
- .slab_obj_size = sizeof(struct sctp6_sock),
+ .obj_size = sizeof(struct sctp6_sock),
};
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 20165335e27b88..acc73fe686983d 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -121,8 +121,6 @@
int sysctl_unix_max_dgram_qlen = 10;
-static kmem_cache_t *unix_sk_cachep;
-
struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
DEFINE_RWLOCK(unix_table_lock);
static atomic_t unix_nr_socks = ATOMIC_INIT(0);
@@ -539,6 +537,12 @@ static struct proto_ops unix_seqpacket_ops = {
.sendpage = sock_no_sendpage,
};
+static struct proto unix_proto = {
+ .name = "UNIX",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct unix_sock),
+};
+
static struct sock * unix_create1(struct socket *sock)
{
struct sock *sk = NULL;
@@ -547,15 +551,13 @@ static struct sock * unix_create1(struct socket *sock)
if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files)
goto out;
- sk = sk_alloc(PF_UNIX, GFP_KERNEL, sizeof(struct unix_sock),
- unix_sk_cachep);
+ sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
if (!sk)
goto out;
atomic_inc(&unix_nr_socks);
sock_init_data(sock,sk);
- sk_set_owner(sk, THIS_MODULE);
sk->sk_write_space = unix_write_space;
sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen;
@@ -2057,26 +2059,28 @@ static inline void unix_sysctl_unregister(void) {}
static int __init af_unix_init(void)
{
+ int rc = -1;
struct sk_buff *dummy_skb;
if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
- return -1;
+ goto out;
+ }
+
+ rc = proto_register(&unix_proto, 1);
+ if (rc != 0) {
+ printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
+ __FUNCTION__);
+ goto out;
}
- /* allocate our sock slab cache */
- unix_sk_cachep = kmem_cache_create("unix_sock",
- sizeof(struct unix_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if (!unix_sk_cachep)
- printk(KERN_CRIT
- "af_unix_init: Cannot create unix_sock SLAB cache!\n");
sock_register(&unix_family_ops);
#ifdef CONFIG_PROC_FS
proc_net_fops_create("unix", 0, &unix_seq_fops);
#endif
unix_sysctl_register();
- return 0;
+out:
+ return rc;
}
static void __exit af_unix_exit(void)
@@ -2084,7 +2088,7 @@ static void __exit af_unix_exit(void)
sock_unregister(PF_UNIX);
unix_sysctl_unregister();
proc_net_remove("unix");
- kmem_cache_destroy(unix_sk_cachep);
+ proto_unregister(&unix_proto);
}
module_init(af_unix_init);
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 6698c872c96b9e..d93b19faaab7f9 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -477,6 +477,17 @@ static struct sock *wanpipe_make_new(struct sock *osk)
return sk;
}
+/*
+ * FIXME: wanpipe_opt has to include a sock in its definition and stop using
+ * sk_protinfo, but this code is not even compilable now, so lets leave it for
+ * later.
+ */
+static struct proto wanpipe_proto = {
+ .name = "WANPIPE",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct sock),
+};
+
/*============================================================
* wanpipe_make_new
*
@@ -495,7 +506,7 @@ static struct sock *wanpipe_alloc_socket(void)
struct sock *sk;
struct wanpipe_opt *wan_opt;
- if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, 1, NULL)) == NULL)
+ if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL)
return NULL;
if ((wan_opt = kmalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) {
@@ -2577,17 +2588,23 @@ void cleanup_module(void)
printk(KERN_INFO "wansock: Cleaning up \n");
unregister_netdevice_notifier(&wanpipe_netdev_notifier);
sock_unregister(PF_WANPIPE);
- return;
+ proto_unregister(&wanpipe_proto);
}
-
int init_module(void)
{
+ int rc;
printk(KERN_INFO "wansock: Registering Socket \n");
+
+ rc = proto_register(&wanpipe_proto, 0);
+ if (rc != 0)
+ goto out;
+
sock_register(&wanpipe_family_ops);
register_netdevice_notifier(&wanpipe_netdev_notifier);
- return 0;
+out:
+ return rc;
}
#endif
MODULE_LICENSE("GPL");
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index e05189a7f85fda..2a24b243b841aa 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -442,17 +442,21 @@ static int x25_listen(struct socket *sock, int backlog)
return rc;
}
+static struct proto x25_proto = {
+ .name = "X25",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct x25_sock),
+};
+
static struct sock *x25_alloc_socket(void)
{
struct x25_sock *x25;
- struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC,
- sizeof(struct x25_sock), NULL);
+ struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1);
if (!sk)
goto out;
sock_init_data(NULL, sk);
- sk_set_owner(sk, THIS_MODULE);
x25 = x25_sk(sk);
skb_queue_head_init(&x25->ack_queue);
@@ -481,7 +485,6 @@ static int x25_create(struct socket *sock, int protocol)
x25 = x25_sk(sk);
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
x25_init_timers(sk);
@@ -1385,6 +1388,11 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
static int __init x25_init(void)
{
+ int rc = proto_register(&x25_proto, 0);
+
+ if (rc != 0)
+ goto out;
+
sock_register(&x25_family_ops);
dev_add_pack(&x25_packet_type);
@@ -1397,7 +1405,8 @@ static int __init x25_init(void)
x25_register_sysctl();
#endif
x25_proc_init();
- return 0;
+out:
+ return rc;
}
module_init(x25_init);
@@ -1416,6 +1425,7 @@ static void __exit x25_exit(void)
dev_remove_pack(&x25_packet_type);
sock_unregister(AF_X25);
+ proto_unregister(&x25_proto);
}
module_exit(x25_exit);