diff options
Diffstat (limited to 'net/bluetooth/cmtp/sock.c')
-rw-r--r-- | net/bluetooth/cmtp/sock.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 311668d14571..aacb802d1ee4 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c | |||
@@ -42,6 +42,10 @@ | |||
42 | 42 | ||
43 | #include "cmtp.h" | 43 | #include "cmtp.h" |
44 | 44 | ||
45 | static struct bt_sock_list cmtp_sk_list = { | ||
46 | .lock = __RW_LOCK_UNLOCKED(cmtp_sk_list.lock) | ||
47 | }; | ||
48 | |||
45 | static int cmtp_sock_release(struct socket *sock) | 49 | static int cmtp_sock_release(struct socket *sock) |
46 | { | 50 | { |
47 | struct sock *sk = sock->sk; | 51 | struct sock *sk = sock->sk; |
@@ -51,6 +55,8 @@ static int cmtp_sock_release(struct socket *sock) | |||
51 | if (!sk) | 55 | if (!sk) |
52 | return 0; | 56 | return 0; |
53 | 57 | ||
58 | bt_sock_unlink(&cmtp_sk_list, sk); | ||
59 | |||
54 | sock_orphan(sk); | 60 | sock_orphan(sk); |
55 | sock_put(sk); | 61 | sock_put(sk); |
56 | 62 | ||
@@ -72,7 +78,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
72 | switch (cmd) { | 78 | switch (cmd) { |
73 | case CMTPCONNADD: | 79 | case CMTPCONNADD: |
74 | if (!capable(CAP_NET_ADMIN)) | 80 | if (!capable(CAP_NET_ADMIN)) |
75 | return -EACCES; | 81 | return -EPERM; |
76 | 82 | ||
77 | if (copy_from_user(&ca, argp, sizeof(ca))) | 83 | if (copy_from_user(&ca, argp, sizeof(ca))) |
78 | return -EFAULT; | 84 | return -EFAULT; |
@@ -97,7 +103,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
97 | 103 | ||
98 | case CMTPCONNDEL: | 104 | case CMTPCONNDEL: |
99 | if (!capable(CAP_NET_ADMIN)) | 105 | if (!capable(CAP_NET_ADMIN)) |
100 | return -EACCES; | 106 | return -EPERM; |
101 | 107 | ||
102 | if (copy_from_user(&cd, argp, sizeof(cd))) | 108 | if (copy_from_user(&cd, argp, sizeof(cd))) |
103 | return -EFAULT; | 109 | return -EFAULT; |
@@ -214,6 +220,8 @@ static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol, | |||
214 | sk->sk_protocol = protocol; | 220 | sk->sk_protocol = protocol; |
215 | sk->sk_state = BT_OPEN; | 221 | sk->sk_state = BT_OPEN; |
216 | 222 | ||
223 | bt_sock_link(&cmtp_sk_list, sk); | ||
224 | |||
217 | return 0; | 225 | return 0; |
218 | } | 226 | } |
219 | 227 | ||
@@ -232,19 +240,30 @@ int cmtp_init_sockets(void) | |||
232 | return err; | 240 | return err; |
233 | 241 | ||
234 | err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops); | 242 | err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops); |
235 | if (err < 0) | 243 | if (err < 0) { |
244 | BT_ERR("Can't register CMTP socket"); | ||
236 | goto error; | 245 | goto error; |
246 | } | ||
247 | |||
248 | err = bt_procfs_init(THIS_MODULE, &init_net, "cmtp", &cmtp_sk_list, NULL); | ||
249 | if (err < 0) { | ||
250 | BT_ERR("Failed to create CMTP proc file"); | ||
251 | bt_sock_unregister(BTPROTO_HIDP); | ||
252 | goto error; | ||
253 | } | ||
254 | |||
255 | BT_INFO("CMTP socket layer initialized"); | ||
237 | 256 | ||
238 | return 0; | 257 | return 0; |
239 | 258 | ||
240 | error: | 259 | error: |
241 | BT_ERR("Can't register CMTP socket"); | ||
242 | proto_unregister(&cmtp_proto); | 260 | proto_unregister(&cmtp_proto); |
243 | return err; | 261 | return err; |
244 | } | 262 | } |
245 | 263 | ||
246 | void cmtp_cleanup_sockets(void) | 264 | void cmtp_cleanup_sockets(void) |
247 | { | 265 | { |
266 | bt_procfs_cleanup(&init_net, "cmtp"); | ||
248 | if (bt_sock_unregister(BTPROTO_CMTP) < 0) | 267 | if (bt_sock_unregister(BTPROTO_CMTP) < 0) |
249 | BT_ERR("Can't unregister CMTP socket"); | 268 | BT_ERR("Can't unregister CMTP socket"); |
250 | 269 | ||