From cfc7551c0afe5c167eebf68be397c84e1fd3957f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 2 May 2003 20:57:58 -0300 Subject: o net: improve the current module infrastructure As per discussions in netdev we'll probably be moving to a brand new scheme, but this set of changesets have been discussed and are an improvement to the current situation and were already done prior to this thread happening. --- include/linux/net.h | 9 +++------ include/net/sock.h | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/net.h b/include/linux/net.h index 8b012430f49d..04bd681473db 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -89,9 +89,11 @@ struct page; struct kiocb; struct sockaddr; struct msghdr; +struct module; struct proto_ops { int family; + struct module *owner; int (*release) (struct socket *sock); int (*bind) (struct socket *sock, struct sockaddr *umyaddr, @@ -127,8 +129,6 @@ struct proto_ops { int offset, size_t size, int flags); }; -struct module; - struct net_proto_family { int family; int (*create)(struct socket *sock, int protocol); @@ -140,9 +140,6 @@ struct net_proto_family { struct module *owner; }; -extern int net_family_get(int family); -extern void net_family_put(int family); - struct iovec; extern int sock_wake_async(struct socket *sk, int how, int band); @@ -227,7 +224,7 @@ SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_are \ static struct proto_ops name##_ops = { \ .family = fam, \ - \ + .owner = THIS_MODULE, \ .release = __lock_##name##_release, \ .bind = __lock_##name##_bind, \ .connect = __lock_##name##_connect, \ diff --git a/include/net/sock.h b/include/net/sock.h index 4f5b79f30880..53639300bc3c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -43,7 +43,7 @@ #include #include #include - +#include #include #include /* struct sk_buff */ #include @@ -197,6 +197,7 @@ struct sock { void *user_data; /* Callbacks */ + struct module *owner; void (*state_change)(struct sock *sk); void (*data_ready)(struct sock *sk,int bytes); void (*write_space)(struct sock *sk); @@ -270,6 +271,23 @@ struct proto { } stats[NR_CPUS]; }; +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. + */ + if (unlikely(sk->owner != NULL)) + BUG(); + sk->owner = owner; + __module_get(owner); +} + /* Called with local bh disabled */ static __inline__ void sock_prot_inc_use(struct proto *prot) { -- cgit v1.2.3 From d4cf4c22167c272d4588a32add0c0c7a5ab354a7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 2 May 2003 21:01:05 -0300 Subject: o pppoe: use revised net module infrastructure Using sk_set_owner and having THIS_MODULE in the struct proto_ops registered with the core. --- drivers/net/pppoe.c | 13 +++++++++---- drivers/net/pppox.c | 42 ++---------------------------------------- include/linux/if_pppox.h | 5 ----- 3 files changed, 11 insertions(+), 49 deletions(-) (limited to 'include') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index ba2ba6d5e179..9f1feff3538b 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -494,16 +494,21 @@ static int pppoe_create(struct socket *sock) struct sock *sk; struct pppox_opt *po; - sk = pppox_sk_alloc(sock, PX_PROTO_OE, GFP_KERNEL, 1, NULL); + sk = sk_alloc(PF_PPPOX, GFP_KERNEL, 1, NULL); if (!sk) goto out; + sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); sock->state = SS_UNCONNECTED; sock->ops = &pppoe_ops; sk->backlog_rcv = pppoe_rcv_core; sk->state = PPPOX_NONE; sk->type = SOCK_STREAM; + sk->family = PF_PPPOX; + sk->protocol = PX_PROTO_OE; + sk->destruct = pppoe_sk_free; po = pppox_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL); if (!po) @@ -1062,10 +1067,12 @@ static struct file_operations pppoe_seq_fops = { }; #endif /* CONFIG_PROC_FS */ -/* ->release and ->ioctl are set at pppox_create */ +/* ->ioctl are set at pppox_create */ struct proto_ops pppoe_ops = { .family = AF_PPPOX, + .owner = THIS_MODULE, + .release = pppoe_release, .bind = sock_no_bind, .connect = pppoe_connect, .socketpair = sock_no_socketpair, @@ -1084,8 +1091,6 @@ struct proto_ops pppoe_ops = { struct pppox_proto pppoe_proto = { .create = pppoe_create, .ioctl = pppoe_ioctl, - .release = pppoe_release, - .sk_free = pppoe_sk_free, .owner = THIS_MODULE, }; diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index fd1838f36da3..a5633d50c35a 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -64,45 +64,9 @@ void pppox_unbind_sock(struct sock *sk) } } -static int pppox_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - int rc = pppox_protos[sk->protocol]->release(sock); - - module_put(pppox_protos[sk->protocol]->owner); - return rc; -} - -static void pppox_sk_free(struct sock *sk) -{ - pppox_protos[sk->protocol]->sk_free(sk); - module_put(pppox_protos[sk->protocol]->owner); -} - -struct sock *pppox_sk_alloc(struct socket *sock, int protocol, int priority, - int zero_it, kmem_cache_t *slab) -{ - struct sock *sk = NULL; - - if (!try_module_get(pppox_protos[protocol]->owner)) - goto out; - - sk = sk_alloc(PF_PPPOX, priority, zero_it, slab); - if (sk) { - sock_init_data(sock, sk); - sk->family = PF_PPPOX; - sk->protocol = protocol; - sk->destruct = pppox_sk_free; - } else - module_put(pppox_protos[protocol]->owner); -out: - return sk; -} - EXPORT_SYMBOL(register_pppox_proto); EXPORT_SYMBOL(unregister_pppox_proto); EXPORT_SYMBOL(pppox_unbind_sock); -EXPORT_SYMBOL(pppox_sk_alloc); static int pppox_ioctl(struct socket* sock, unsigned int cmd, unsigned long arg) @@ -156,12 +120,10 @@ static int pppox_create(struct socket *sock, int protocol) rc = pppox_protos[protocol]->create(sock); if (!rc) { /* We get to set the ioctl handler. */ - /* And the release handler, for module refcounting */ /* For everything else, pppox is just a shell. */ sock->ops->ioctl = pppox_ioctl; - sock->ops->release = pppox_release; - } else - module_put(pppox_protos[protocol]->owner); + } + module_put(pppox_protos[protocol]->owner); out: return rc; } diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 117357b14483..78ffd78ddb9e 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -140,8 +140,6 @@ struct pppox_proto { int (*create)(struct socket *sock); int (*ioctl)(struct socket *sock, unsigned int cmd, unsigned long arg); - int (*release)(struct socket *sock); - void (*sk_free)(struct sock *sk); struct module *owner; }; @@ -150,9 +148,6 @@ extern void unregister_pppox_proto(int proto_num); extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd, unsigned long arg); -extern struct sock *pppox_sk_alloc(struct socket *sock, int protocol, - int priority, int zero_it, - kmem_cache_t *slab); /* PPPoX socket states */ enum { -- cgit v1.2.3