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 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 61 int ksmbd_set_netbios_name(char *v) 62 { 63 return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v); 64 } 65 66 int ksmbd_set_server_string(char *v) 67 { 68 return ___server_conf_set(SERVER_CONF_SERVER_STRING, v); 69 } 70 71 int ksmbd_set_work_group(char *v) 72 { 73 return ___server_conf_set(SERVER_CONF_WORK_GROUP, v); 74 } 75 76 char *ksmbd_netbios_name(void) 77 { 78 return server_conf.conf[SERVER_CONF_NETBIOS_NAME]; 79 } 80 81 char *ksmbd_server_string(void) 82 { 83 return server_conf.conf[SERVER_CONF_SERVER_STRING]; 84 } 85 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 */ 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 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 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 */ 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 */ 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 410 static int ksmbd_server_process_request(struct ksmbd_conn *conn) 411 { 412 return queue_ksmbd_work(conn); 413 } 414 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 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 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 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 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 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 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 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 519 int server_queue_ctrl_init_work(void) 520 { 521 return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT); 522 } 523 524 int server_queue_ctrl_reset_work(void) 525 { 526 return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET); 527 } 528 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 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 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 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 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 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 */ 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