diff options
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 1220d8a41eb5..d366423c8392 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -53,6 +53,30 @@ | |||
53 | /* Bluetooth sockets */ | 53 | /* Bluetooth sockets */ |
54 | #define BT_MAX_PROTO 8 | 54 | #define BT_MAX_PROTO 8 |
55 | static struct net_proto_family *bt_proto[BT_MAX_PROTO]; | 55 | static struct net_proto_family *bt_proto[BT_MAX_PROTO]; |
56 | |||
57 | static struct lock_class_key bt_slock_key[BT_MAX_PROTO]; | ||
58 | static struct lock_class_key bt_lock_key[BT_MAX_PROTO]; | ||
59 | static const char *bt_key_strings[BT_MAX_PROTO] = { | ||
60 | "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP", | ||
61 | "sk_lock-AF_BLUETOOTH-BTPROTO_HCI", | ||
62 | "sk_lock-AF_BLUETOOTH-BTPROTO_SCO", | ||
63 | "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM", | ||
64 | "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP", | ||
65 | "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP", | ||
66 | "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP", | ||
67 | "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP", | ||
68 | }; | ||
69 | |||
70 | static const char *bt_slock_key_strings[BT_MAX_PROTO] = { | ||
71 | "slock-AF_BLUETOOTH-BTPROTO_L2CAP", | ||
72 | "slock-AF_BLUETOOTH-BTPROTO_HCI", | ||
73 | "slock-AF_BLUETOOTH-BTPROTO_SCO", | ||
74 | "slock-AF_BLUETOOTH-BTPROTO_RFCOMM", | ||
75 | "slock-AF_BLUETOOTH-BTPROTO_BNEP", | ||
76 | "slock-AF_BLUETOOTH-BTPROTO_CMTP", | ||
77 | "slock-AF_BLUETOOTH-BTPROTO_HIDP", | ||
78 | "slock-AF_BLUETOOTH-BTPROTO_AVDTP", | ||
79 | }; | ||
56 | static DEFINE_RWLOCK(bt_proto_lock); | 80 | static DEFINE_RWLOCK(bt_proto_lock); |
57 | 81 | ||
58 | int bt_sock_register(int proto, struct net_proto_family *ops) | 82 | int bt_sock_register(int proto, struct net_proto_family *ops) |
@@ -95,6 +119,21 @@ int bt_sock_unregister(int proto) | |||
95 | } | 119 | } |
96 | EXPORT_SYMBOL(bt_sock_unregister); | 120 | EXPORT_SYMBOL(bt_sock_unregister); |
97 | 121 | ||
122 | static void bt_reclassify_sock_lock(struct socket *sock, int proto) | ||
123 | { | ||
124 | struct sock *sk = sock->sk; | ||
125 | |||
126 | if (!sk) | ||
127 | return; | ||
128 | BUG_ON(sock_owned_by_user(sk)); | ||
129 | |||
130 | sock_lock_init_class_and_name(sk, | ||
131 | bt_slock_key_strings[proto], | ||
132 | &bt_slock_key[proto], | ||
133 | bt_key_strings[proto], | ||
134 | &bt_lock_key[proto]); | ||
135 | } | ||
136 | |||
98 | static int bt_sock_create(struct net *net, struct socket *sock, int proto) | 137 | static int bt_sock_create(struct net *net, struct socket *sock, int proto) |
99 | { | 138 | { |
100 | int err; | 139 | int err; |
@@ -117,6 +156,7 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto) | |||
117 | 156 | ||
118 | if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { | 157 | if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { |
119 | err = bt_proto[proto]->create(net, sock, proto); | 158 | err = bt_proto[proto]->create(net, sock, proto); |
159 | bt_reclassify_sock_lock(sock, proto); | ||
120 | module_put(bt_proto[proto]->owner); | 160 | module_put(bt_proto[proto]->owner); |
121 | } | 161 | } |
122 | 162 | ||