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)
hci_uart_ldisc.receive_room= hci_uart_tty_room;
hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
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))) {
BT_ERR("HCI line discipline registration failed. (%d)", err);
......
......@@ -235,4 +235,6 @@ struct l2cap_pinfo {
#define CONF_INPUT_DONE 0x02
#define CONF_OUTPUT_DONE 0x04
void l2cap_load(void);
#endif /* __L2CAP_H */
......@@ -92,6 +92,8 @@ int bt_sock_unregister(int proto)
static int bt_sock_create(struct socket *sock, int proto)
{
int err = 0;
if (proto >= BT_MAX_PROTO)
return -EINVAL;
......@@ -102,11 +104,12 @@ static int bt_sock_create(struct socket *sock, int proto)
request_module(module_name);
}
#endif
if (!bt_proto[proto])
return -ENOENT;
return bt_proto[proto]->create(sock, proto);
err = -EPROTONOSUPPORT;
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
err = bt_proto[proto]->create(sock, proto);
module_put(bt_proto[proto]->owner);
}
return err;
}
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)
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);
}
static void __bnep_unlink_session(struct bnep_session *s)
{
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)
......@@ -677,7 +680,9 @@ int bnep_get_conninfo(struct bnep_conninfo *ci)
static int __init bnep_init_module(void)
{
char flt[50] = "";
char flt[50] = "";
l2cap_load();
#ifdef CONFIG_BT_BNEP_PROTO_FILTER
strcat(flt, "protocol ");
......
......@@ -67,8 +67,6 @@ static int bnep_sock_release(struct socket *sock)
sock_orphan(sk);
sock_put(sk);
MOD_DEC_USE_COUNT;
return 0;
}
......@@ -179,13 +177,10 @@ static int bnep_sock_create(struct socket *sock, int protocol)
return -ENOMEM;
sock->ops = &bnep_sock_ops;
MOD_INC_USE_COUNT;
sock->state = SS_UNCONNECTED;
sock->state = SS_UNCONNECTED;
sk->destruct = NULL;
sk->protocol = protocol;
return 0;
}
......
......@@ -145,8 +145,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->chan_list.lock = RW_LOCK_UNLOCKED;
BT_DBG("hcon %p conn %p", hcon, conn);
MOD_INC_USE_COUNT;
return conn;
}
......@@ -173,8 +171,6 @@ static int l2cap_conn_del(struct hci_conn *hcon, int err)
hcon->l2cap_data = NULL;
kfree(conn);
MOD_DEC_USE_COUNT;
return 0;
}
......@@ -242,8 +238,6 @@ static void l2cap_sock_destruct(struct sock *sk)
if (sk->protinfo)
kfree(sk->protinfo);
MOD_DEC_USE_COUNT;
}
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)
if (!sk)
return NULL;
sk_set_owner(sk, THIS_MODULE);
sk->destruct = l2cap_sock_destruct;
sk->sndtimeo = L2CAP_CONN_TIMEOUT;
......@@ -365,8 +361,6 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
l2cap_sock_init_timer(sk);
bt_sock_link(&l2cap_sk_list, sk);
MOD_INC_USE_COUNT;
return sk;
}
......@@ -2133,7 +2127,6 @@ int __init l2cap_init(void)
return err;
}
l2cap_proc_init();
BT_INFO("L2CAP ver %s", VERSION);
......@@ -2154,6 +2147,15 @@ void __exit l2cap_cleanup(void)
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_exit(l2cap_cleanup);
......
......@@ -52,7 +52,7 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
#define VERSION "0.3"
#define VERSION "1.0"
#ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG
......@@ -481,9 +481,12 @@ struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
list_add(&s->list, &session_list);
/* 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)
MOD_INC_USE_COUNT;
__module_get(THIS_MODULE);
return s;
}
......@@ -502,7 +505,7 @@ void rfcomm_session_del(struct rfcomm_session *s)
kfree(s);
if (state != BT_LISTEN)
MOD_DEC_USE_COUNT;
module_put(THIS_MODULE);
}
struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
......@@ -1868,6 +1871,8 @@ static void __exit rfcomm_proc_cleanup(void)
/* ---- Initialization ---- */
int __init rfcomm_init(void)
{
l2cap_load();
kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
BT_INFO("RFCOMM ver %s", VERSION);
......
......@@ -182,8 +182,6 @@ static void rfcomm_sock_destruct(struct sock *sk)
if (sk->protinfo)
kfree(sk->protinfo);
MOD_DEC_USE_COUNT;
}
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)
if (!sk)
return NULL;
sk_set_owner(sk, THIS_MODULE);
d = rfcomm_dlc_alloc(prio);
if (!d) {
sk_free(sk);
......@@ -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_DBG("sk %p", sk);
MOD_INC_USE_COUNT;
return sk;
}
......
......@@ -99,7 +99,9 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
rfcomm_dlc_put(dlc);
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)
......@@ -211,8 +213,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
dev->dlc = 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:
write_unlock_bh(&rfcomm_dev_lock);
......
......@@ -145,8 +145,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
conn->mtu = 60;
BT_DBG("hcon %p conn %p", hcon, conn);
MOD_INC_USE_COUNT;
return conn;
}
......@@ -180,8 +178,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
hcon->sco_data = NULL;
kfree(conn);
MOD_DEC_USE_COUNT;
return 0;
}
......@@ -347,8 +343,6 @@ static void sco_sock_destruct(struct sock *sk)
if (sk->protinfo)
kfree(sk->protinfo);
MOD_DEC_USE_COUNT;
}
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)
if (!sk)
return NULL;
sk_set_owner(sk, THIS_MODULE);
sk->destruct = sco_sock_destruct;
sk->sndtimeo = SCO_CONN_TIMEOUT;
sk->state = BT_OPEN;
......@@ -441,8 +437,6 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
sco_sock_init_timer(sk);
bt_sock_link(&sco_sk_list, sk);
MOD_INC_USE_COUNT;
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