summaryrefslogtreecommitdiffstats
path: root/net/tipc/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/server.c')
-rw-r--r--net/tipc/server.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/net/tipc/server.c b/net/tipc/server.c
index eadd4ed45905..a57c8407cbf3 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -37,11 +37,13 @@
37#include "core.h" 37#include "core.h"
38#include "socket.h" 38#include "socket.h"
39#include <net/sock.h> 39#include <net/sock.h>
40#include <linux/module.h>
40 41
41/* Number of messages to send before rescheduling */ 42/* Number of messages to send before rescheduling */
42#define MAX_SEND_MSG_COUNT 25 43#define MAX_SEND_MSG_COUNT 25
43#define MAX_RECV_MSG_COUNT 25 44#define MAX_RECV_MSG_COUNT 25
44#define CF_CONNECTED 1 45#define CF_CONNECTED 1
46#define CF_SERVER 2
45 47
46#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data) 48#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data)
47 49
@@ -88,9 +90,16 @@ static void tipc_clean_outqueues(struct tipc_conn *con);
88static void tipc_conn_kref_release(struct kref *kref) 90static void tipc_conn_kref_release(struct kref *kref)
89{ 91{
90 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); 92 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
93 struct socket *sock = con->sock;
94 struct sock *sk;
91 95
92 if (con->sock) { 96 if (sock) {
93 tipc_sock_release_local(con->sock); 97 sk = sock->sk;
98 if (test_bit(CF_SERVER, &con->flags)) {
99 __module_get(sock->ops->owner);
100 __module_get(sk->sk_prot_creator->owner);
101 }
102 sk_release_kernel(sk);
94 con->sock = NULL; 103 con->sock = NULL;
95 } 104 }
96 105
@@ -281,7 +290,7 @@ static int tipc_accept_from_sock(struct tipc_conn *con)
281 struct tipc_conn *newcon; 290 struct tipc_conn *newcon;
282 int ret; 291 int ret;
283 292
284 ret = tipc_sock_accept_local(sock, &newsock, O_NONBLOCK); 293 ret = kernel_accept(sock, &newsock, O_NONBLOCK);
285 if (ret < 0) 294 if (ret < 0)
286 return ret; 295 return ret;
287 296
@@ -309,9 +318,12 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
309 struct socket *sock = NULL; 318 struct socket *sock = NULL;
310 int ret; 319 int ret;
311 320
312 ret = tipc_sock_create_local(s->net, s->type, &sock); 321 ret = sock_create_kern(AF_TIPC, SOCK_SEQPACKET, 0, &sock);
313 if (ret < 0) 322 if (ret < 0)
314 return NULL; 323 return NULL;
324
325 sk_change_net(sock->sk, s->net);
326
315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE, 327 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
316 (char *)&s->imp, sizeof(s->imp)); 328 (char *)&s->imp, sizeof(s->imp));
317 if (ret < 0) 329 if (ret < 0)
@@ -337,11 +349,31 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
337 pr_err("Unknown socket type %d\n", s->type); 349 pr_err("Unknown socket type %d\n", s->type);
338 goto create_err; 350 goto create_err;
339 } 351 }
352
353 /* As server's listening socket owner and creator is the same module,
354 * we have to decrease TIPC module reference count to guarantee that
355 * it remains zero after the server socket is created, otherwise,
356 * executing "rmmod" command is unable to make TIPC module deleted
357 * after TIPC module is inserted successfully.
358 *
359 * However, the reference count is ever increased twice in
360 * sock_create_kern(): one is to increase the reference count of owner
361 * of TIPC socket's proto_ops struct; another is to increment the
362 * reference count of owner of TIPC proto struct. Therefore, we must
363 * decrement the module reference count twice to ensure that it keeps
364 * zero after server's listening socket is created. Of course, we
365 * must bump the module reference count twice as well before the socket
366 * is closed.
367 */
368 module_put(sock->ops->owner);
369 module_put(sock->sk->sk_prot_creator->owner);
370 set_bit(CF_SERVER, &con->flags);
371
340 return sock; 372 return sock;
341 373
342create_err: 374create_err:
343 sock_release(sock); 375 kernel_sock_shutdown(sock, SHUT_RDWR);
344 con->sock = NULL; 376 sk_release_kernel(sock->sk);
345 return NULL; 377 return NULL;
346} 378}
347 379