1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4 * Copyright (C) 2018 Samsung Electronics Co., Ltd.
5 */
6
7 #include "glob.h"
8 #include "oplock.h"
9 #include "misc.h"
10 #include <linux/sched/signal.h>
11 #include <linux/workqueue.h>
12 #include <linux/sysfs.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15
16 #include "server.h"
17 #include "smb_common.h"
18 #include "smb2pdu.h"
19 #include "../common/smb2status.h"
20 #include "connection.h"
21 #include "transport_ipc.h"
22 #include "mgmt/user_session.h"
23 #include "crypto_ctx.h"
24 #include "auth.h"
25 #include "stats.h"
26 #include "compress.h"
27 #include "mgmt/share_config.h"
28 #include "mgmt/tree_connect.h"
29
30 int ksmbd_debug_types;
31
32 struct ksmbd_server_config server_conf;
33
34 enum SERVER_CTRL_TYPE {
35 SERVER_CTRL_TYPE_INIT,
36 SERVER_CTRL_TYPE_RESET,
37 };
38
39 struct server_ctrl_struct {
40 int type;
41 struct work_struct ctrl_work;
42 };
43
44 static DEFINE_MUTEX(ctrl_lock);
45
___server_conf_set(int idx,char * val)46 static int ___server_conf_set(int idx, char *val)
47 {
48 if (idx >= ARRAY_SIZE(server_conf.conf))
49 return -EINVAL;
50
51 if (!val || val[0] == 0x00)
52 return -EINVAL;
53
54 kfree(server_conf.conf[idx]);
55 server_conf.conf[idx] = kstrdup(val, KSMBD_DEFAULT_GFP);
56 if (!server_conf.conf[idx])
57 return -ENOMEM;
58 return 0;
59 }
60
ksmbd_set_netbios_name(char * v)61 int ksmbd_set_netbios_name(char *v)
62 {
63 return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v);
64 }
65
ksmbd_set_server_string(char * v)66 int ksmbd_set_server_string(char *v)
67 {
68 return ___server_conf_set(SERVER_CONF_SERVER_STRING, v);
69 }
70
ksmbd_set_work_group(char * v)71 int ksmbd_set_work_group(char *v)
72 {
73 return ___server_conf_set(SERVER_CONF_WORK_GROUP, v);
74 }
75
ksmbd_netbios_name(void)76 char *ksmbd_netbios_name(void)
77 {
78 return server_conf.conf[SERVER_CONF_NETBIOS_NAME];
79 }
80
ksmbd_server_string(void)81 char *ksmbd_server_string(void)
82 {
83 return server_conf.conf[SERVER_CONF_SERVER_STRING];
84 }
85
ksmbd_work_group(void)86 char *ksmbd_work_group(void)
87 {
88 return server_conf.conf[SERVER_CONF_WORK_GROUP];
89 }
90
91 /**
92 * check_conn_state() - check state of server thread connection
93 * @work: smb work containing server thread information
94 *
95 * Return: 0 on valid connection, otherwise 1 to reconnect
96 */
check_conn_state(struct ksmbd_work * work)97 static inline int check_conn_state(struct ksmbd_work *work)
98 {
99 struct smb_hdr *rsp_hdr;
100
101 if (ksmbd_conn_exiting(work->conn) ||
102 ksmbd_conn_need_reconnect(work->conn)) {
103 rsp_hdr = smb_get_msg(work->response_buf);
104 rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED;
105 return 1;
106 }
107 return 0;
108 }
109
110 #define SERVER_HANDLER_CONTINUE 0
111 #define SERVER_HANDLER_ABORT 1
112
__process_request(struct ksmbd_work * work,struct ksmbd_conn * conn,u16 * cmd)113 static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
114 u16 *cmd)
115 {
116 struct smb_version_cmds *cmds;
117 u16 command;
118 bool signed_req;
119 int ret;
120
121 if (check_conn_state(work))
122 return SERVER_HANDLER_CONTINUE;
123
124 if (ksmbd_verify_smb_message(work)) {
125 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
126 return SERVER_HANDLER_ABORT;
127 }
128
129 command = conn->ops->get_cmd_val(work);
130 *cmd = command;
131
132 andx_again:
133 if (command >= conn->max_cmds) {
134 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
135 return SERVER_HANDLER_ABORT;
136 }
137
138 cmds = &conn->cmds[command];
139 if (!cmds->proc) {
140 ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command);
141 conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED);
142 return SERVER_HANDLER_ABORT;
143 }
144
145 signed_req = conn->ops->is_sign_req && conn->ops->is_sign_req(work, command);
146 if (work->sess && work->sess->sign && !work->encrypted &&
147 !signed_req) {
148 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
149 return SERVER_HANDLER_ABORT;
150 }
151
152 if (work->sess && signed_req) {
153 ret = conn->ops->check_sign_req(work);
154 if (!ret) {
155 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
156 return SERVER_HANDLER_ABORT;
157 }
158 }
159
160 ret = cmds->proc(work);
161 if (conn->ops->inc_reqs) {
162 struct smb2_hdr *rsp = ksmbd_resp_buf_curr(work);
163
164 conn->ops->inc_reqs(command, rsp->Status);
165 }
166
167 if (ret < 0)
168 ksmbd_debug(CONN, "Failed to process %u [%d]\n", command, ret);
169 /* AndX commands - chained request can return positive values */
170 else if (ret > 0) {
171 command = ret;
172 *cmd = command;
173 goto andx_again;
174 }
175
176 if (work->send_no_response)
177 return SERVER_HANDLER_ABORT;
178 return SERVER_HANDLER_CONTINUE;
179 }
180
__handle_ksmbd_work(struct ksmbd_work * work,struct ksmbd_conn * conn)181 static void __handle_ksmbd_work(struct ksmbd_work *work,
182 struct ksmbd_conn *conn)
183 {
184 u16 command = 0;
185 int rc;
186 bool is_chained = false;
187
188 if (conn->ops->is_transform_hdr &&
189 conn->ops->is_transform_hdr(work->request_buf)) {
190 rc = conn->ops->decrypt_req(work);
191 if (rc < 0) {
192 ksmbd_conn_abort(conn);
193 return;
194 }
195 work->encrypted = true;
196
197 /*
198 * SMB3 applies compression before encryption. The receive loop
199 * handles a plain compression transform before allocating work, but
200 * an encrypted request exposes that transform only after decryption.
201 */
202 if (((struct smb2_hdr *)smb_get_msg(work->request_buf))->ProtocolId ==
203 SMB2_COMPRESSION_TRANSFORM_ID) {
204 rc = ksmbd_decompress_work_request(work);
205 if (rc < 0) {
206 ksmbd_conn_abort(conn);
207 return;
208 }
209 }
210
211 /* The decrypted payload must now be a complete SMB2 request. */
212 if (((struct smb2_hdr *)smb_get_msg(work->request_buf))->ProtocolId !=
213 SMB2_PROTO_NUMBER ||
214 get_rfc1002_len(work->request_buf) < sizeof(struct smb2_pdu)) {
215 ksmbd_conn_abort(conn);
216 return;
217 }
218 }
219
220 if (conn->ops->allocate_rsp_buf(work))
221 return;
222
223 rc = conn->ops->init_rsp_hdr(work);
224 if (rc) {
225 /* either uid or tid is not correct */
226 conn->ops->set_rsp_status(work, STATUS_INVALID_HANDLE);
227 goto send;
228 }
229
230 do {
231 if (conn->ops->check_user_session) {
232 rc = conn->ops->check_user_session(work);
233 if (rc < 0) {
234 if (rc == -EINVAL)
235 conn->ops->set_rsp_status(work,
236 STATUS_INVALID_PARAMETER);
237 else if (rc == -EKEYEXPIRED)
238 conn->ops->set_rsp_status(work,
239 STATUS_NETWORK_SESSION_EXPIRED);
240 else
241 conn->ops->set_rsp_status(work,
242 STATUS_USER_SESSION_DELETED);
243 if (conn->ops->is_sign_req(work, conn->ops->get_cmd_val(work))) {
244 struct smb2_hdr *rsp_hdr;
245
246 rsp_hdr = ksmbd_resp_buf_curr(work);
247 if (rc == -EKEYEXPIRED && work->sess &&
248 conn->ops->set_sign_rsp)
249 conn->ops->set_sign_rsp(work);
250 else
251 rsp_hdr->Flags |= SMB2_FLAGS_SIGNED;
252 }
253 goto send;
254 } else if (rc > 0) {
255 rc = conn->ops->get_ksmbd_tcon(work);
256 if (rc < 0) {
257 if (rc == -EINVAL)
258 conn->ops->set_rsp_status(work,
259 STATUS_INVALID_PARAMETER);
260 else
261 conn->ops->set_rsp_status(work,
262 STATUS_NETWORK_NAME_DELETED);
263 goto send;
264 }
265
266 if (work->tcon &&
267 test_share_config_flag(work->tcon->share_conf,
268 KSMBD_SHARE_FLAG_ENCRYPT_DATA) &&
269 !work->encrypted) {
270 conn->ops->set_rsp_status(work,
271 STATUS_ACCESS_DENIED);
272 goto send;
273 }
274 }
275 }
276
277 rc = __process_request(work, conn, &command);
278 if (rc == SERVER_HANDLER_ABORT) {
279 smb2_complete_request_open(work);
280 break;
281 }
282
283 /*
284 * Call smb2_set_rsp_credits() function to set number of credits
285 * granted in hdr of smb2 response.
286 */
287 if (conn->ops->set_rsp_credits) {
288 spin_lock(&conn->credits_lock);
289 rc = conn->ops->set_rsp_credits(work);
290 spin_unlock(&conn->credits_lock);
291 if (rc < 0) {
292 conn->ops->set_rsp_status(work,
293 STATUS_INVALID_PARAMETER);
294 smb2_complete_request_open(work);
295 goto send;
296 }
297 }
298
299 smb2_complete_request_open(work);
300
301 is_chained = is_chained_smb2_message(work);
302
303 if (work->sess &&
304 (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
305 conn->ops->is_sign_req(work, command))) {
306 if (command == SMB2_SESSION_SETUP_HE &&
307 work->sess->dialect >= SMB30_PROT_ID &&
308 conn->dialect < SMB30_PROT_ID)
309 smb3_set_sign_rsp(work);
310 else
311 conn->ops->set_sign_rsp(work);
312 }
313 } while (is_chained == true);
314
315 send:
316 smb2_complete_request_open(work);
317 /*
318 * Release any credit charge still outstanding for this request. On
319 * the normal path smb2_set_rsp_credits() already returned it, but the
320 * abort, error and send-no-response paths skip that call, so the
321 * charge would otherwise leak and eventually exhaust the connection's
322 * outstanding credit window.
323 */
324 if (work->credit_charge) {
325 spin_lock(&conn->credits_lock);
326 conn->outstanding_credits -= work->credit_charge;
327 work->credit_charge = 0;
328 spin_unlock(&conn->credits_lock);
329 }
330
331 if (work->tcon)
332 ksmbd_tree_connect_put(work->tcon);
333 smb3_preauth_hash_rsp(work);
334 /*
335 * Preauthentication hashes cover the original SMB2 response. Apply the
336 * transport compression wrapper only after updating the hash.
337 */
338 if (work->compress_response) {
339 rc = ksmbd_compress_response(work);
340 if (rc < 0)
341 ksmbd_debug(CONN, "Failed to compress response: %d\n", rc);
342 }
343 if (work->sess && work->sess->enc && work->encrypted &&
344 conn->ops->encrypt_resp) {
345 rc = conn->ops->encrypt_resp(work);
346 if (rc < 0)
347 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
348 }
349 if (work->sess)
350 ksmbd_user_session_put(work->sess);
351
352 ksmbd_conn_write(work);
353 }
354
355 /**
356 * handle_ksmbd_work() - process pending smb work requests
357 * @wk: smb work containing request command buffer
358 *
359 * called by kworker threads to processing remaining smb work requests
360 */
handle_ksmbd_work(struct work_struct * wk)361 static void handle_ksmbd_work(struct work_struct *wk)
362 {
363 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
364 struct ksmbd_conn *conn = work->conn;
365
366 atomic64_inc(&conn->stats.request_served);
367
368 __handle_ksmbd_work(work, conn);
369
370 ksmbd_conn_try_dequeue_request(work);
371 ksmbd_free_work_struct(work);
372 ksmbd_conn_r_count_dec(conn);
373 }
374
375 /**
376 * queue_ksmbd_work() - queue a smb request to worker thread queue
377 * for processing smb command and sending response
378 * @conn: connection instance
379 *
380 * read remaining data from socket create and submit work.
381 */
queue_ksmbd_work(struct ksmbd_conn * conn)382 static int queue_ksmbd_work(struct ksmbd_conn *conn)
383 {
384 struct ksmbd_work *work;
385 int err;
386
387 err = ksmbd_init_smb_server(conn);
388 if (err)
389 return 0;
390
391 work = ksmbd_alloc_work_struct();
392 if (!work) {
393 pr_err("allocation for work failed\n");
394 return -ENOMEM;
395 }
396
397 work->conn = conn;
398 work->request_buf = conn->request_buf;
399 conn->request_buf = NULL;
400
401 ksmbd_conn_enqueue_request(work);
402 ksmbd_conn_r_count_inc(conn);
403 /* update activity on connection */
404 conn->last_active = jiffies;
405 INIT_WORK(&work->work, handle_ksmbd_work);
406 ksmbd_queue_work(work);
407 return 0;
408 }
409
ksmbd_server_process_request(struct ksmbd_conn * conn)410 static int ksmbd_server_process_request(struct ksmbd_conn *conn)
411 {
412 return queue_ksmbd_work(conn);
413 }
414
ksmbd_server_terminate_conn(struct ksmbd_conn * conn)415 static int ksmbd_server_terminate_conn(struct ksmbd_conn *conn)
416 {
417 ksmbd_sessions_deregister(conn);
418 destroy_lease_table(conn);
419 return 0;
420 }
421
ksmbd_server_tcp_callbacks_init(void)422 static void ksmbd_server_tcp_callbacks_init(void)
423 {
424 struct ksmbd_conn_ops ops;
425
426 ops.process_fn = ksmbd_server_process_request;
427 ops.terminate_fn = ksmbd_server_terminate_conn;
428
429 ksmbd_conn_init_server_callbacks(&ops);
430 }
431
server_conf_free(void)432 static void server_conf_free(void)
433 {
434 int i;
435
436 for (i = 0; i < ARRAY_SIZE(server_conf.conf); i++) {
437 kfree(server_conf.conf[i]);
438 server_conf.conf[i] = NULL;
439 }
440 }
441
server_conf_init(void)442 static int server_conf_init(void)
443 {
444 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
445 server_conf.enforced_signing = 0;
446 server_conf.min_protocol = ksmbd_min_protocol();
447 server_conf.max_protocol = ksmbd_max_protocol();
448 server_conf.auth_mechs = KSMBD_AUTH_NTLMSSP;
449 #ifdef CONFIG_SMB_SERVER_KERBEROS5
450 server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
451 KSMBD_AUTH_MSKRB5;
452 #endif
453 server_conf.max_inflight_req = SMB2_MAX_CREDITS;
454 return 0;
455 }
456
server_ctrl_handle_init(struct server_ctrl_struct * ctrl)457 static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl)
458 {
459 int ret;
460
461 ksmbd_proc_reset();
462 ret = ksmbd_conn_transport_init();
463 if (ret) {
464 server_queue_ctrl_reset_work();
465 return;
466 }
467
468 pr_info("running\n");
469 WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING);
470 }
471
server_ctrl_handle_reset(struct server_ctrl_struct * ctrl)472 static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
473 {
474 ksmbd_ipc_soft_reset();
475 ksmbd_conn_transport_destroy();
476 ksmbd_stop_durable_scavenger();
477 server_conf_free();
478 server_conf_init();
479 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
480 }
481
server_ctrl_handle_work(struct work_struct * work)482 static void server_ctrl_handle_work(struct work_struct *work)
483 {
484 struct server_ctrl_struct *ctrl;
485
486 ctrl = container_of(work, struct server_ctrl_struct, ctrl_work);
487
488 mutex_lock(&ctrl_lock);
489 switch (ctrl->type) {
490 case SERVER_CTRL_TYPE_INIT:
491 server_ctrl_handle_init(ctrl);
492 break;
493 case SERVER_CTRL_TYPE_RESET:
494 server_ctrl_handle_reset(ctrl);
495 break;
496 default:
497 pr_err("Unknown server work type: %d\n", ctrl->type);
498 }
499 mutex_unlock(&ctrl_lock);
500 kfree(ctrl);
501 module_put(THIS_MODULE);
502 }
503
__queue_ctrl_work(int type)504 static int __queue_ctrl_work(int type)
505 {
506 struct server_ctrl_struct *ctrl;
507
508 ctrl = kmalloc_obj(struct server_ctrl_struct, KSMBD_DEFAULT_GFP);
509 if (!ctrl)
510 return -ENOMEM;
511
512 __module_get(THIS_MODULE);
513 ctrl->type = type;
514 INIT_WORK(&ctrl->ctrl_work, server_ctrl_handle_work);
515 queue_work(system_long_wq, &ctrl->ctrl_work);
516 return 0;
517 }
518
server_queue_ctrl_init_work(void)519 int server_queue_ctrl_init_work(void)
520 {
521 return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT);
522 }
523
server_queue_ctrl_reset_work(void)524 int server_queue_ctrl_reset_work(void)
525 {
526 return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
527 }
528
stats_show(const struct class * class,const struct class_attribute * attr,char * buf)529 static ssize_t stats_show(const struct class *class, const struct class_attribute *attr,
530 char *buf)
531 {
532 /*
533 * Inc this each time you change stats output format,
534 * so user space will know what to do.
535 */
536 static int stats_version = 2;
537 static const char * const state[] = {
538 "startup",
539 "running",
540 "reset",
541 "shutdown"
542 };
543 return sysfs_emit(buf, "%d %s %d %lu\n", stats_version,
544 state[server_conf.state], server_conf.tcp_port,
545 server_conf.ipc_last_active / HZ);
546 }
547
kill_server_store(const struct class * class,const struct class_attribute * attr,const char * buf,size_t len)548 static ssize_t kill_server_store(const struct class *class,
549 const struct class_attribute *attr, const char *buf,
550 size_t len)
551 {
552 if (!sysfs_streq(buf, "hard"))
553 return len;
554
555 pr_info("kill command received\n");
556 mutex_lock(&ctrl_lock);
557 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
558 __module_get(THIS_MODULE);
559 server_ctrl_handle_reset(NULL);
560 module_put(THIS_MODULE);
561 mutex_unlock(&ctrl_lock);
562 return len;
563 }
564
565 static const char * const debug_type_strings[] = {"smb", "auth", "vfs",
566 "oplock", "ipc", "conn",
567 "rdma"};
568
debug_show(const struct class * class,const struct class_attribute * attr,char * buf)569 static ssize_t debug_show(const struct class *class, const struct class_attribute *attr,
570 char *buf)
571 {
572 ssize_t sz = 0;
573 int i, pos = 0;
574
575 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
576 if ((ksmbd_debug_types >> i) & 1) {
577 pos = sysfs_emit_at(buf, sz, "[%s] ", debug_type_strings[i]);
578 } else {
579 pos = sysfs_emit_at(buf, sz, "%s ", debug_type_strings[i]);
580 }
581 sz += pos;
582 }
583 sz += sysfs_emit_at(buf, sz, "\n");
584 return sz;
585 }
586
debug_store(const struct class * class,const struct class_attribute * attr,const char * buf,size_t len)587 static ssize_t debug_store(const struct class *class, const struct class_attribute *attr,
588 const char *buf, size_t len)
589 {
590 int i;
591
592 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
593 if (sysfs_streq(buf, "all")) {
594 if (ksmbd_debug_types == KSMBD_DEBUG_ALL)
595 ksmbd_debug_types = 0;
596 else
597 ksmbd_debug_types = KSMBD_DEBUG_ALL;
598 break;
599 }
600
601 if (sysfs_streq(buf, debug_type_strings[i])) {
602 if (ksmbd_debug_types & (1 << i))
603 ksmbd_debug_types &= ~(1 << i);
604 else
605 ksmbd_debug_types |= (1 << i);
606 break;
607 }
608 }
609
610 return len;
611 }
612
613 static CLASS_ATTR_RO(stats);
614 static CLASS_ATTR_WO(kill_server);
615 static CLASS_ATTR_RW(debug);
616
617 static struct attribute *ksmbd_control_class_attrs[] = {
618 &class_attr_stats.attr,
619 &class_attr_kill_server.attr,
620 &class_attr_debug.attr,
621 NULL,
622 };
623 ATTRIBUTE_GROUPS(ksmbd_control_class);
624
625 static struct class ksmbd_control_class = {
626 .name = "ksmbd-control",
627 .class_groups = ksmbd_control_class_groups,
628 };
629
ksmbd_server_shutdown(void)630 static int ksmbd_server_shutdown(void)
631 {
632 WRITE_ONCE(server_conf.state, SERVER_STATE_SHUTTING_DOWN);
633
634 class_unregister(&ksmbd_control_class);
635 ksmbd_workqueue_destroy();
636 ksmbd_ipc_release();
637 ksmbd_conn_transport_destroy();
638 /*
639 * ksmbd_conn_transport_destroy() calls delete_proc_clients() and destroys
640 * sessions. ksmbd_session_destroy() removes each session's proc entry.
641 * Keep the procfs tree alive until these entries have been removed.
642 */
643 ksmbd_proc_cleanup();
644 ksmbd_crypto_destroy();
645 ksmbd_free_global_file_table();
646 destroy_lease_table(NULL);
647 ksmbd_work_pool_destroy();
648 ksmbd_exit_file_cache();
649 server_conf_free();
650 return 0;
651 }
652
ksmbd_server_init(void)653 static int __init ksmbd_server_init(void)
654 {
655 int ret;
656
657 ret = class_register(&ksmbd_control_class);
658 if (ret) {
659 pr_err("Unable to register ksmbd-control class\n");
660 return ret;
661 }
662
663 ret = ksmbd_proc_init();
664 if (ret)
665 goto err_unregister;
666
667 if (create_proc_sessions())
668 pr_warn("Unable to create sessions procfs entry\n");
669
670 if (create_proc_shares())
671 pr_warn("Unable to create shares procfs entry\n");
672
673 ksmbd_server_tcp_callbacks_init();
674
675 ret = server_conf_init();
676 if (ret)
677 goto err_proc_cleanup;
678
679 ret = ksmbd_work_pool_init();
680 if (ret)
681 goto err_proc_cleanup;
682
683 ret = ksmbd_init_file_cache();
684 if (ret)
685 goto err_destroy_work_pools;
686
687 ret = ksmbd_ipc_init();
688 if (ret)
689 goto err_exit_file_cache;
690
691 ret = ksmbd_init_global_file_table();
692 if (ret)
693 goto err_ipc_release;
694
695 ret = ksmbd_inode_hash_init();
696 if (ret)
697 goto err_destroy_file_table;
698
699 ret = ksmbd_crypto_create();
700 if (ret)
701 goto err_release_inode_hash;
702
703 ret = ksmbd_workqueue_init();
704 if (ret)
705 goto err_crypto_destroy;
706
707 ret = ksmbd_conn_wq_init();
708 if (ret)
709 goto err_workqueue_destroy;
710
711 return 0;
712
713 err_workqueue_destroy:
714 ksmbd_workqueue_destroy();
715 err_crypto_destroy:
716 ksmbd_crypto_destroy();
717 err_release_inode_hash:
718 ksmbd_release_inode_hash();
719 err_destroy_file_table:
720 ksmbd_free_global_file_table();
721 err_ipc_release:
722 ksmbd_ipc_release();
723 err_exit_file_cache:
724 ksmbd_exit_file_cache();
725 err_destroy_work_pools:
726 ksmbd_work_pool_destroy();
727 err_proc_cleanup:
728 ksmbd_proc_cleanup();
729 err_unregister:
730 class_unregister(&ksmbd_control_class);
731
732 return ret;
733 }
734
735 /**
736 * ksmbd_server_exit() - shutdown forker thread and free memory at module exit
737 */
ksmbd_server_exit(void)738 static void __exit ksmbd_server_exit(void)
739 {
740 ksmbd_server_shutdown();
741 rcu_barrier();
742 /*
743 * ksmbd_conn_put() defers the final release onto ksmbd_conn_wq,
744 * so drain it after rcu_barrier() has fired any pending RCU
745 * callbacks that may have queued a release.
746 */
747 ksmbd_conn_wq_destroy();
748 ksmbd_release_inode_hash();
749 }
750
751 MODULE_AUTHOR("Namjae Jeon <linkinjeon@kernel.org>");
752 MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
753 MODULE_LICENSE("GPL");
754 MODULE_SOFTDEP("pre: nls");
755 MODULE_SOFTDEP("pre: aes");
756 MODULE_SOFTDEP("pre: aead2");
757 MODULE_SOFTDEP("pre: ccm");
758 MODULE_SOFTDEP("pre: gcm");
759 module_init(ksmbd_server_init)
760 module_exit(ksmbd_server_exit)
761