aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/server.c')
-rw-r--r--net/tipc/server.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/net/tipc/server.c b/net/tipc/server.c
index eadd4ed45905..ab6183cdb121 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,19 @@ 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 sockaddr_tipc *saddr = con->server->saddr;
94 struct socket *sock = con->sock;
95 struct sock *sk;
91 96
92 if (con->sock) { 97 if (sock) {
93 tipc_sock_release_local(con->sock); 98 sk = sock->sk;
99 if (test_bit(CF_SERVER, &con->flags)) {
100 __module_get(sock->ops->owner);
101 __module_get(sk->sk_prot_creator->owner);
102 }
103 saddr->scope = -TIPC_NODE_SCOPE;
104 kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr));
105 sk_release_kernel(sk);
94 con->sock = NULL; 106 con->sock = NULL;
95 } 107 }
96 108
@@ -281,7 +293,7 @@ static int tipc_accept_from_sock(struct tipc_conn *con)
281 struct tipc_conn *newcon; 293 struct tipc_conn *newcon;
282 int ret; 294 int ret;
283 295
284 ret = tipc_sock_accept_local(sock, &newsock, O_NONBLOCK); 296 ret = kernel_accept(sock, &newsock, O_NONBLOCK);
285 if (ret < 0) 297 if (ret < 0)
286 return ret; 298 return ret;
287 299
@@ -309,9 +321,12 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
309 struct socket *sock = NULL; 321 struct socket *sock = NULL;
310 int ret; 322 int ret;
311 323
312 ret = tipc_sock_create_local(s->net, s->type, &sock); 324 ret = sock_create_kern(AF_TIPC, SOCK_SEQPACKET, 0, &sock);
313 if (ret < 0) 325 if (ret < 0)
314 return NULL; 326 return NULL;
327
328 sk_change_net(sock->sk, s->net);
329
315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE, 330 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
316 (char *)&s->imp, sizeof(s->imp)); 331 (char *)&s->imp, sizeof(s->imp));
317 if (ret < 0) 332 if (ret < 0)
@@ -337,11 +352,31 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
337 pr_err("Unknown socket type %d\n", s->type); 352 pr_err("Unknown socket type %d\n", s->type);
338 goto create_err; 353 goto create_err;
339 } 354 }
355
356 /* As server's listening socket owner and creator is the same module,
357 * we have to decrease TIPC module reference count to guarantee that
358 * it remains zero after the server socket is created, otherwise,
359 * executing "rmmod" command is unable to make TIPC module deleted
360 * after TIPC module is inserted successfully.
361 *
362 * However, the reference count is ever increased twice in
363 * sock_create_kern(): one is to increase the reference count of owner
364 * of TIPC socket's proto_ops struct; another is to increment the
365 * reference count of owner of TIPC proto struct. Therefore, we must
366 * decrement the module reference count twice to ensure that it keeps
367 * zero after server's listening socket is created. Of course, we
368 * must bump the module reference count twice as well before the socket
369 * is closed.
370 */
371 module_put(sock->ops->owner);
372 module_put(sock->sk->sk_prot_creator->owner);
373 set_bit(CF_SERVER, &con->flags);
374
340 return sock; 375 return sock;
341 376
342create_err: 377create_err:
343 sock_release(sock); 378 kernel_sock_shutdown(sock, SHUT_RDWR);
344 con->sock = NULL; 379 sk_release_kernel(sock->sk);
345 return NULL; 380 return NULL;
346} 381}
347 382