Commit d89da5d8 authored by Maksim Krasnyanskiy's avatar Maksim Krasnyanskiy

[Bluetooth] Add required infrastructure for socket module refcounting.

Initialize ->owner fields in Bluetooth protocols and drivers.
parent fd801944
...@@ -535,6 +535,7 @@ int __init hci_uart_init(void) ...@@ -535,6 +535,7 @@ int __init hci_uart_init(void)
hci_uart_ldisc.receive_room= hci_uart_tty_room; hci_uart_ldisc.receive_room= hci_uart_tty_room;
hci_uart_ldisc.receive_buf = hci_uart_tty_receive; hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup; hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
hci_uart_ldisc.owner = THIS_MODULE;
if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
BT_ERR("HCI line discipline registration failed. (%d)", err); BT_ERR("HCI line discipline registration failed. (%d)", err);
......
...@@ -235,4 +235,6 @@ struct l2cap_pinfo { ...@@ -235,4 +235,6 @@ struct l2cap_pinfo {
#define CONF_INPUT_DONE 0x02 #define CONF_INPUT_DONE 0x02
#define CONF_OUTPUT_DONE 0x04 #define CONF_OUTPUT_DONE 0x04
void l2cap_load(void);
#endif /* __L2CAP_H */ #endif /* __L2CAP_H */
...@@ -92,6 +92,8 @@ int bt_sock_unregister(int proto) ...@@ -92,6 +92,8 @@ int bt_sock_unregister(int proto)
static int bt_sock_create(struct socket *sock, int proto) static int bt_sock_create(struct socket *sock, int proto)
{ {
int err = 0;
if (proto >= BT_MAX_PROTO) if (proto >= BT_MAX_PROTO)
return -EINVAL; return -EINVAL;
...@@ -102,11 +104,12 @@ static int bt_sock_create(struct socket *sock, int proto) ...@@ -102,11 +104,12 @@ static int bt_sock_create(struct socket *sock, int proto)
request_module(module_name); request_module(module_name);
} }
#endif #endif
err = -EPROTONOSUPPORT;
if (!bt_proto[proto]) if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
return -ENOENT; err = bt_proto[proto]->create(sock, proto);
module_put(bt_proto[proto]->owner);
return bt_proto[proto]->create(sock, proto); }
return err;
} }
struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio) struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio)
......
...@@ -85,14 +85,17 @@ static struct bnep_session *__bnep_get_session(u8 *dst) ...@@ -85,14 +85,17 @@ static struct bnep_session *__bnep_get_session(u8 *dst)
static void __bnep_link_session(struct bnep_session *s) static void __bnep_link_session(struct bnep_session *s)
{ {
MOD_INC_USE_COUNT; /* It's safe to call __module_get() here because sessions are added
by the socket layer which has to hold the refference to this module.
*/
__module_get(THIS_MODULE);
list_add(&s->list, &bnep_session_list); list_add(&s->list, &bnep_session_list);
} }
static void __bnep_unlink_session(struct bnep_session *s) static void __bnep_unlink_session(struct bnep_session *s)
{ {
list_del(&s->list); list_del(&s->list);
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
} }
static int bnep_send(struct bnep_session *s, void *data, size_t len) static int bnep_send(struct bnep_session *s, void *data, size_t len)
...@@ -679,6 +682,8 @@ static int __init bnep_init_module(void) ...@@ -679,6 +682,8 @@ static int __init bnep_init_module(void)
{ {
char flt[50] = ""; char flt[50] = "";
l2cap_load();
#ifdef CONFIG_BT_BNEP_PROTO_FILTER #ifdef CONFIG_BT_BNEP_PROTO_FILTER
strcat(flt, "protocol "); strcat(flt, "protocol ");
#endif #endif
......
...@@ -67,8 +67,6 @@ static int bnep_sock_release(struct socket *sock) ...@@ -67,8 +67,6 @@ static int bnep_sock_release(struct socket *sock)
sock_orphan(sk); sock_orphan(sk);
sock_put(sk); sock_put(sk);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -179,13 +177,10 @@ static int bnep_sock_create(struct socket *sock, int protocol) ...@@ -179,13 +177,10 @@ static int bnep_sock_create(struct socket *sock, int protocol)
return -ENOMEM; return -ENOMEM;
sock->ops = &bnep_sock_ops; sock->ops = &bnep_sock_ops;
MOD_INC_USE_COUNT;
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
sk->destruct = NULL; sk->destruct = NULL;
sk->protocol = protocol; sk->protocol = protocol;
return 0; return 0;
} }
......
...@@ -145,8 +145,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) ...@@ -145,8 +145,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->chan_list.lock = RW_LOCK_UNLOCKED; conn->chan_list.lock = RW_LOCK_UNLOCKED;
BT_DBG("hcon %p conn %p", hcon, conn); BT_DBG("hcon %p conn %p", hcon, conn);
MOD_INC_USE_COUNT;
return conn; return conn;
} }
...@@ -173,8 +171,6 @@ static int l2cap_conn_del(struct hci_conn *hcon, int err) ...@@ -173,8 +171,6 @@ static int l2cap_conn_del(struct hci_conn *hcon, int err)
hcon->l2cap_data = NULL; hcon->l2cap_data = NULL;
kfree(conn); kfree(conn);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -242,8 +238,6 @@ static void l2cap_sock_destruct(struct sock *sk) ...@@ -242,8 +238,6 @@ static void l2cap_sock_destruct(struct sock *sk)
if (sk->protinfo) if (sk->protinfo)
kfree(sk->protinfo); kfree(sk->protinfo);
MOD_DEC_USE_COUNT;
} }
static void l2cap_sock_cleanup_listen(struct sock *parent) static void l2cap_sock_cleanup_listen(struct sock *parent)
...@@ -356,6 +350,8 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio) ...@@ -356,6 +350,8 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
if (!sk) if (!sk)
return NULL; return NULL;
sk_set_owner(sk, THIS_MODULE);
sk->destruct = l2cap_sock_destruct; sk->destruct = l2cap_sock_destruct;
sk->sndtimeo = L2CAP_CONN_TIMEOUT; sk->sndtimeo = L2CAP_CONN_TIMEOUT;
...@@ -365,8 +361,6 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio) ...@@ -365,8 +361,6 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
l2cap_sock_init_timer(sk); l2cap_sock_init_timer(sk);
bt_sock_link(&l2cap_sk_list, sk); bt_sock_link(&l2cap_sk_list, sk);
MOD_INC_USE_COUNT;
return sk; return sk;
} }
...@@ -2133,7 +2127,6 @@ int __init l2cap_init(void) ...@@ -2133,7 +2127,6 @@ int __init l2cap_init(void)
return err; return err;
} }
l2cap_proc_init(); l2cap_proc_init();
BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP ver %s", VERSION);
...@@ -2154,6 +2147,15 @@ void __exit l2cap_cleanup(void) ...@@ -2154,6 +2147,15 @@ void __exit l2cap_cleanup(void)
BT_ERR("L2CAP protocol unregistration failed"); BT_ERR("L2CAP protocol unregistration failed");
} }
void l2cap_load(void)
{
/* Dummy function to trigger automatic L2CAP module loading by
other modules that use L2CAP sockets but don not use any other
symbols from it. */
return;
}
EXPORT_SYMBOL(l2cap_load);
module_init(l2cap_init); module_init(l2cap_init);
module_exit(l2cap_cleanup); module_exit(l2cap_cleanup);
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h> #include <net/bluetooth/rfcomm.h>
#define VERSION "0.3" #define VERSION "1.0"
#ifndef CONFIG_BT_RFCOMM_DEBUG #ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG #undef BT_DBG
...@@ -481,9 +481,12 @@ struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state) ...@@ -481,9 +481,12 @@ struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
list_add(&s->list, &session_list); list_add(&s->list, &session_list);
/* Do not increment module usage count for listeting sessions. /* Do not increment module usage count for listeting sessions.
* Otherwise we won't be able to unload the module. */ * Otherwise we won't be able to unload the module.
* Non listening session are added either by a socket or a TTYs
* which means that we already hold refcount to this module.
*/
if (state != BT_LISTEN) if (state != BT_LISTEN)
MOD_INC_USE_COUNT; __module_get(THIS_MODULE);
return s; return s;
} }
...@@ -502,7 +505,7 @@ void rfcomm_session_del(struct rfcomm_session *s) ...@@ -502,7 +505,7 @@ void rfcomm_session_del(struct rfcomm_session *s)
kfree(s); kfree(s);
if (state != BT_LISTEN) if (state != BT_LISTEN)
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
} }
struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
...@@ -1868,6 +1871,8 @@ static void __exit rfcomm_proc_cleanup(void) ...@@ -1868,6 +1871,8 @@ static void __exit rfcomm_proc_cleanup(void)
/* ---- Initialization ---- */ /* ---- Initialization ---- */
int __init rfcomm_init(void) int __init rfcomm_init(void)
{ {
l2cap_load();
kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
BT_INFO("RFCOMM ver %s", VERSION); BT_INFO("RFCOMM ver %s", VERSION);
......
...@@ -182,8 +182,6 @@ static void rfcomm_sock_destruct(struct sock *sk) ...@@ -182,8 +182,6 @@ static void rfcomm_sock_destruct(struct sock *sk)
if (sk->protinfo) if (sk->protinfo)
kfree(sk->protinfo); kfree(sk->protinfo);
MOD_DEC_USE_COUNT;
} }
static void rfcomm_sock_cleanup_listen(struct sock *parent) static void rfcomm_sock_cleanup_listen(struct sock *parent)
...@@ -265,6 +263,8 @@ static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio) ...@@ -265,6 +263,8 @@ static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
if (!sk) if (!sk)
return NULL; return NULL;
sk_set_owner(sk, THIS_MODULE);
d = rfcomm_dlc_alloc(prio); d = rfcomm_dlc_alloc(prio);
if (!d) { if (!d) {
sk_free(sk); sk_free(sk);
...@@ -288,8 +288,6 @@ static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio) ...@@ -288,8 +288,6 @@ static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
bt_sock_link(&rfcomm_sk_list, sk); bt_sock_link(&rfcomm_sk_list, sk);
BT_DBG("sk %p", sk); BT_DBG("sk %p", sk);
MOD_INC_USE_COUNT;
return sk; return sk;
} }
......
...@@ -99,7 +99,9 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) ...@@ -99,7 +99,9 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
rfcomm_dlc_put(dlc); rfcomm_dlc_put(dlc);
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT; /* It's safe to call module_put() here because socket still
holds refference to this module. */
module_put(THIS_MODULE);
} }
static inline void rfcomm_dev_hold(struct rfcomm_dev *dev) static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
...@@ -211,8 +213,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) ...@@ -211,8 +213,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
dev->dlc = dlc; dev->dlc = dlc;
rfcomm_dlc_unlock(dlc); rfcomm_dlc_unlock(dlc);
MOD_INC_USE_COUNT; /* It's safe to call __module_get() here because socket already
holds refference to this module. */
__module_get(THIS_MODULE);
out: out:
write_unlock_bh(&rfcomm_dev_lock); write_unlock_bh(&rfcomm_dev_lock);
......
...@@ -145,8 +145,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status) ...@@ -145,8 +145,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
conn->mtu = 60; conn->mtu = 60;
BT_DBG("hcon %p conn %p", hcon, conn); BT_DBG("hcon %p conn %p", hcon, conn);
MOD_INC_USE_COUNT;
return conn; return conn;
} }
...@@ -180,8 +178,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err) ...@@ -180,8 +178,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
hcon->sco_data = NULL; hcon->sco_data = NULL;
kfree(conn); kfree(conn);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -347,8 +343,6 @@ static void sco_sock_destruct(struct sock *sk) ...@@ -347,8 +343,6 @@ static void sco_sock_destruct(struct sock *sk)
if (sk->protinfo) if (sk->protinfo)
kfree(sk->protinfo); kfree(sk->protinfo);
MOD_DEC_USE_COUNT;
} }
static void sco_sock_cleanup_listen(struct sock *parent) static void sco_sock_cleanup_listen(struct sock *parent)
...@@ -434,6 +428,8 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio) ...@@ -434,6 +428,8 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
if (!sk) if (!sk)
return NULL; return NULL;
sk_set_owner(sk, THIS_MODULE);
sk->destruct = sco_sock_destruct; sk->destruct = sco_sock_destruct;
sk->sndtimeo = SCO_CONN_TIMEOUT; sk->sndtimeo = SCO_CONN_TIMEOUT;
sk->state = BT_OPEN; sk->state = BT_OPEN;
...@@ -441,8 +437,6 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio) ...@@ -441,8 +437,6 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
sco_sock_init_timer(sk); sco_sock_init_timer(sk);
bt_sock_link(&sco_sk_list, sk); bt_sock_link(&sco_sk_list, sk);
MOD_INC_USE_COUNT;
return sk; return sk;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment