1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org> 4 * Copyright (C) 2019 Samsung Electronics Co., Ltd. 5 */ 6 7 #include <linux/fs.h> 8 #include <linux/filelock.h> 9 #include <linux/slab.h> 10 #include <linux/vmalloc.h> 11 #include <linux/kthread.h> 12 #include <linux/freezer.h> 13 14 #include "glob.h" 15 #include "vfs_cache.h" 16 #include "oplock.h" 17 #include "vfs.h" 18 #include "connection.h" 19 #include "mgmt/tree_connect.h" 20 #include "mgmt/user_session.h" 21 #include "smb_common.h" 22 #include "server.h" 23 24 #define S_DEL_PENDING 1 25 #define S_DEL_ON_CLS 2 26 #define S_DEL_ON_CLS_STREAM 8 27 28 static unsigned int inode_hash_mask __read_mostly; 29 static unsigned int inode_hash_shift __read_mostly; 30 static struct hlist_head *inode_hashtable __read_mostly; 31 static DEFINE_RWLOCK(inode_hash_lock); 32 33 static struct ksmbd_file_table global_ft; 34 static atomic_long_t fd_limit; 35 static struct kmem_cache *filp_cache; 36 37 static bool durable_scavenger_running; 38 static DEFINE_MUTEX(durable_scavenger_lock); 39 static wait_queue_head_t dh_wq; 40 41 void ksmbd_set_fd_limit(unsigned long limit) 42 { 43 limit = min(limit, get_max_files()); 44 atomic_long_set(&fd_limit, limit); 45 } 46 47 static bool fd_limit_depleted(void) 48 { 49 long v = atomic_long_dec_return(&fd_limit); 50 51 if (v >= 0) 52 return false; 53 atomic_long_inc(&fd_limit); 54 return true; 55 } 56 57 static void fd_limit_close(void) 58 { 59 atomic_long_inc(&fd_limit); 60 } 61 62 /* 63 * INODE hash 64 */ 65 66 static unsigned long inode_hash(struct super_block *sb, unsigned long hashval) 67 { 68 unsigned long tmp; 69 70 tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / 71 L1_CACHE_BYTES; 72 tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> inode_hash_shift); 73 return tmp & inode_hash_mask; 74 } 75 76 static struct ksmbd_inode *__ksmbd_inode_lookup(struct dentry *de) 77 { 78 struct hlist_head *head = inode_hashtable + 79 inode_hash(d_inode(de)->i_sb, (unsigned long)de); 80 struct ksmbd_inode *ci = NULL, *ret_ci = NULL; 81 82 hlist_for_each_entry(ci, head, m_hash) { 83 if (ci->m_de == de) { 84 if (atomic_inc_not_zero(&ci->m_count)) 85 ret_ci = ci; 86 break; 87 } 88 } 89 return ret_ci; 90 } 91 92 static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp) 93 { 94 return __ksmbd_inode_lookup(fp->filp->f_path.dentry); 95 } 96 97 struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d) 98 { 99 struct ksmbd_inode *ci; 100 101 read_lock(&inode_hash_lock); 102 ci = __ksmbd_inode_lookup(d); 103 read_unlock(&inode_hash_lock); 104 105 return ci; 106 } 107 108 int ksmbd_query_inode_status(struct dentry *dentry) 109 { 110 struct ksmbd_inode *ci; 111 int ret = KSMBD_INODE_STATUS_UNKNOWN; 112 113 read_lock(&inode_hash_lock); 114 ci = __ksmbd_inode_lookup(dentry); 115 if (ci) { 116 ret = KSMBD_INODE_STATUS_OK; 117 if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) 118 ret = KSMBD_INODE_STATUS_PENDING_DELETE; 119 atomic_dec(&ci->m_count); 120 } 121 read_unlock(&inode_hash_lock); 122 return ret; 123 } 124 125 bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) 126 { 127 return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); 128 } 129 130 void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) 131 { 132 fp->f_ci->m_flags |= S_DEL_PENDING; 133 } 134 135 void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp) 136 { 137 fp->f_ci->m_flags &= ~S_DEL_PENDING; 138 } 139 140 void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, 141 int file_info) 142 { 143 if (ksmbd_stream_fd(fp)) { 144 fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM; 145 return; 146 } 147 148 fp->f_ci->m_flags |= S_DEL_ON_CLS; 149 } 150 151 static void ksmbd_inode_hash(struct ksmbd_inode *ci) 152 { 153 struct hlist_head *b = inode_hashtable + 154 inode_hash(d_inode(ci->m_de)->i_sb, (unsigned long)ci->m_de); 155 156 hlist_add_head(&ci->m_hash, b); 157 } 158 159 static void ksmbd_inode_unhash(struct ksmbd_inode *ci) 160 { 161 write_lock(&inode_hash_lock); 162 hlist_del_init(&ci->m_hash); 163 write_unlock(&inode_hash_lock); 164 } 165 166 static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) 167 { 168 atomic_set(&ci->m_count, 1); 169 atomic_set(&ci->op_count, 0); 170 atomic_set(&ci->sop_count, 0); 171 ci->m_flags = 0; 172 ci->m_fattr = 0; 173 INIT_LIST_HEAD(&ci->m_fp_list); 174 INIT_LIST_HEAD(&ci->m_op_list); 175 init_rwsem(&ci->m_lock); 176 ci->m_de = fp->filp->f_path.dentry; 177 return 0; 178 } 179 180 static struct ksmbd_inode *ksmbd_inode_get(struct ksmbd_file *fp) 181 { 182 struct ksmbd_inode *ci, *tmpci; 183 int rc; 184 185 read_lock(&inode_hash_lock); 186 ci = ksmbd_inode_lookup(fp); 187 read_unlock(&inode_hash_lock); 188 if (ci) 189 return ci; 190 191 ci = kmalloc(sizeof(struct ksmbd_inode), GFP_KERNEL); 192 if (!ci) 193 return NULL; 194 195 rc = ksmbd_inode_init(ci, fp); 196 if (rc) { 197 pr_err("inode initialized failed\n"); 198 kfree(ci); 199 return NULL; 200 } 201 202 write_lock(&inode_hash_lock); 203 tmpci = ksmbd_inode_lookup(fp); 204 if (!tmpci) { 205 ksmbd_inode_hash(ci); 206 } else { 207 kfree(ci); 208 ci = tmpci; 209 } 210 write_unlock(&inode_hash_lock); 211 return ci; 212 } 213 214 static void ksmbd_inode_free(struct ksmbd_inode *ci) 215 { 216 ksmbd_inode_unhash(ci); 217 kfree(ci); 218 } 219 220 void ksmbd_inode_put(struct ksmbd_inode *ci) 221 { 222 if (atomic_dec_and_test(&ci->m_count)) 223 ksmbd_inode_free(ci); 224 } 225 226 int __init ksmbd_inode_hash_init(void) 227 { 228 unsigned int loop; 229 unsigned long numentries = 16384; 230 unsigned long bucketsize = sizeof(struct hlist_head); 231 unsigned long size; 232 233 inode_hash_shift = ilog2(numentries); 234 inode_hash_mask = (1 << inode_hash_shift) - 1; 235 236 size = bucketsize << inode_hash_shift; 237 238 /* init master fp hash table */ 239 inode_hashtable = vmalloc(size); 240 if (!inode_hashtable) 241 return -ENOMEM; 242 243 for (loop = 0; loop < (1U << inode_hash_shift); loop++) 244 INIT_HLIST_HEAD(&inode_hashtable[loop]); 245 return 0; 246 } 247 248 void ksmbd_release_inode_hash(void) 249 { 250 vfree(inode_hashtable); 251 } 252 253 static void __ksmbd_inode_close(struct ksmbd_file *fp) 254 { 255 struct ksmbd_inode *ci = fp->f_ci; 256 int err; 257 struct file *filp; 258 259 filp = fp->filp; 260 if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { 261 ci->m_flags &= ~S_DEL_ON_CLS_STREAM; 262 err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), 263 &filp->f_path, 264 fp->stream.name, 265 true); 266 if (err) 267 pr_err("remove xattr failed : %s\n", 268 fp->stream.name); 269 } 270 271 if (atomic_dec_and_test(&ci->m_count)) { 272 down_write(&ci->m_lock); 273 if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { 274 ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); 275 up_write(&ci->m_lock); 276 ksmbd_vfs_unlink(filp); 277 down_write(&ci->m_lock); 278 } 279 up_write(&ci->m_lock); 280 281 ksmbd_inode_free(ci); 282 } 283 } 284 285 static void __ksmbd_remove_durable_fd(struct ksmbd_file *fp) 286 { 287 if (!has_file_id(fp->persistent_id)) 288 return; 289 290 idr_remove(global_ft.idr, fp->persistent_id); 291 } 292 293 static void ksmbd_remove_durable_fd(struct ksmbd_file *fp) 294 { 295 write_lock(&global_ft.lock); 296 __ksmbd_remove_durable_fd(fp); 297 write_unlock(&global_ft.lock); 298 if (waitqueue_active(&dh_wq)) 299 wake_up(&dh_wq); 300 } 301 302 static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp) 303 { 304 if (!has_file_id(fp->volatile_id)) 305 return; 306 307 down_write(&fp->f_ci->m_lock); 308 list_del_init(&fp->node); 309 up_write(&fp->f_ci->m_lock); 310 311 write_lock(&ft->lock); 312 idr_remove(ft->idr, fp->volatile_id); 313 write_unlock(&ft->lock); 314 } 315 316 static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp) 317 { 318 struct file *filp; 319 struct ksmbd_lock *smb_lock, *tmp_lock; 320 321 fd_limit_close(); 322 ksmbd_remove_durable_fd(fp); 323 if (ft) 324 __ksmbd_remove_fd(ft, fp); 325 326 close_id_del_oplock(fp); 327 filp = fp->filp; 328 329 __ksmbd_inode_close(fp); 330 if (!IS_ERR_OR_NULL(filp)) 331 fput(filp); 332 333 /* because the reference count of fp is 0, it is guaranteed that 334 * there are not accesses to fp->lock_list. 335 */ 336 list_for_each_entry_safe(smb_lock, tmp_lock, &fp->lock_list, flist) { 337 spin_lock(&fp->conn->llist_lock); 338 list_del(&smb_lock->clist); 339 spin_unlock(&fp->conn->llist_lock); 340 341 list_del(&smb_lock->flist); 342 locks_free_lock(smb_lock->fl); 343 kfree(smb_lock); 344 } 345 346 if (ksmbd_stream_fd(fp)) 347 kfree(fp->stream.name); 348 kmem_cache_free(filp_cache, fp); 349 } 350 351 static struct ksmbd_file *ksmbd_fp_get(struct ksmbd_file *fp) 352 { 353 if (fp->f_state != FP_INITED) 354 return NULL; 355 356 if (!atomic_inc_not_zero(&fp->refcount)) 357 return NULL; 358 return fp; 359 } 360 361 static struct ksmbd_file *__ksmbd_lookup_fd(struct ksmbd_file_table *ft, 362 u64 id) 363 { 364 struct ksmbd_file *fp; 365 366 if (!has_file_id(id)) 367 return NULL; 368 369 read_lock(&ft->lock); 370 fp = idr_find(ft->idr, id); 371 if (fp) 372 fp = ksmbd_fp_get(fp); 373 read_unlock(&ft->lock); 374 return fp; 375 } 376 377 static void __put_fd_final(struct ksmbd_work *work, struct ksmbd_file *fp) 378 { 379 __ksmbd_close_fd(&work->sess->file_table, fp); 380 atomic_dec(&work->conn->stats.open_files_count); 381 } 382 383 static void set_close_state_blocked_works(struct ksmbd_file *fp) 384 { 385 struct ksmbd_work *cancel_work; 386 387 spin_lock(&fp->f_lock); 388 list_for_each_entry(cancel_work, &fp->blocked_works, 389 fp_entry) { 390 cancel_work->state = KSMBD_WORK_CLOSED; 391 cancel_work->cancel_fn(cancel_work->cancel_argv); 392 } 393 spin_unlock(&fp->f_lock); 394 } 395 396 int ksmbd_close_fd(struct ksmbd_work *work, u64 id) 397 { 398 struct ksmbd_file *fp; 399 struct ksmbd_file_table *ft; 400 401 if (!has_file_id(id)) 402 return 0; 403 404 ft = &work->sess->file_table; 405 write_lock(&ft->lock); 406 fp = idr_find(ft->idr, id); 407 if (fp) { 408 set_close_state_blocked_works(fp); 409 410 if (fp->f_state != FP_INITED) 411 fp = NULL; 412 else { 413 fp->f_state = FP_CLOSED; 414 if (!atomic_dec_and_test(&fp->refcount)) 415 fp = NULL; 416 } 417 } 418 write_unlock(&ft->lock); 419 420 if (!fp) 421 return -EINVAL; 422 423 __put_fd_final(work, fp); 424 return 0; 425 } 426 427 void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp) 428 { 429 if (!fp) 430 return; 431 432 if (!atomic_dec_and_test(&fp->refcount)) 433 return; 434 __put_fd_final(work, fp); 435 } 436 437 static bool __sanity_check(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp) 438 { 439 if (!fp) 440 return false; 441 if (fp->tcon != tcon) 442 return false; 443 return true; 444 } 445 446 struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id) 447 { 448 return __ksmbd_lookup_fd(&work->sess->file_table, id); 449 } 450 451 struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id) 452 { 453 struct ksmbd_file *fp = __ksmbd_lookup_fd(&work->sess->file_table, id); 454 455 if (__sanity_check(work->tcon, fp)) 456 return fp; 457 458 ksmbd_fd_put(work, fp); 459 return NULL; 460 } 461 462 struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, 463 u64 pid) 464 { 465 struct ksmbd_file *fp; 466 467 if (!has_file_id(id)) { 468 id = work->compound_fid; 469 pid = work->compound_pfid; 470 } 471 472 fp = __ksmbd_lookup_fd(&work->sess->file_table, id); 473 if (!__sanity_check(work->tcon, fp)) { 474 ksmbd_fd_put(work, fp); 475 return NULL; 476 } 477 if (fp->persistent_id != pid) { 478 ksmbd_fd_put(work, fp); 479 return NULL; 480 } 481 return fp; 482 } 483 484 struct ksmbd_file *ksmbd_lookup_global_fd(unsigned long long id) 485 { 486 return __ksmbd_lookup_fd(&global_ft, id); 487 } 488 489 struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id) 490 { 491 struct ksmbd_file *fp; 492 493 fp = __ksmbd_lookup_fd(&global_ft, id); 494 if (fp && (fp->conn || 495 (fp->durable_scavenger_timeout && 496 (fp->durable_scavenger_timeout < 497 jiffies_to_msecs(jiffies))))) { 498 ksmbd_put_durable_fd(fp); 499 fp = NULL; 500 } 501 502 return fp; 503 } 504 505 void ksmbd_put_durable_fd(struct ksmbd_file *fp) 506 { 507 if (!atomic_dec_and_test(&fp->refcount)) 508 return; 509 510 __ksmbd_close_fd(NULL, fp); 511 } 512 513 struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid) 514 { 515 struct ksmbd_file *fp = NULL; 516 unsigned int id; 517 518 read_lock(&global_ft.lock); 519 idr_for_each_entry(global_ft.idr, fp, id) { 520 if (!memcmp(fp->create_guid, 521 cguid, 522 SMB2_CREATE_GUID_SIZE)) { 523 fp = ksmbd_fp_get(fp); 524 break; 525 } 526 } 527 read_unlock(&global_ft.lock); 528 529 return fp; 530 } 531 532 struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry) 533 { 534 struct ksmbd_file *lfp; 535 struct ksmbd_inode *ci; 536 struct inode *inode = d_inode(dentry); 537 538 read_lock(&inode_hash_lock); 539 ci = __ksmbd_inode_lookup(dentry); 540 read_unlock(&inode_hash_lock); 541 if (!ci) 542 return NULL; 543 544 down_read(&ci->m_lock); 545 list_for_each_entry(lfp, &ci->m_fp_list, node) { 546 if (inode == file_inode(lfp->filp)) { 547 atomic_dec(&ci->m_count); 548 lfp = ksmbd_fp_get(lfp); 549 up_read(&ci->m_lock); 550 return lfp; 551 } 552 } 553 atomic_dec(&ci->m_count); 554 up_read(&ci->m_lock); 555 return NULL; 556 } 557 558 #define OPEN_ID_TYPE_VOLATILE_ID (0) 559 #define OPEN_ID_TYPE_PERSISTENT_ID (1) 560 561 static void __open_id_set(struct ksmbd_file *fp, u64 id, int type) 562 { 563 if (type == OPEN_ID_TYPE_VOLATILE_ID) 564 fp->volatile_id = id; 565 if (type == OPEN_ID_TYPE_PERSISTENT_ID) 566 fp->persistent_id = id; 567 } 568 569 static int __open_id(struct ksmbd_file_table *ft, struct ksmbd_file *fp, 570 int type) 571 { 572 u64 id = 0; 573 int ret; 574 575 if (type == OPEN_ID_TYPE_VOLATILE_ID && fd_limit_depleted()) { 576 __open_id_set(fp, KSMBD_NO_FID, type); 577 return -EMFILE; 578 } 579 580 idr_preload(GFP_KERNEL); 581 write_lock(&ft->lock); 582 ret = idr_alloc_cyclic(ft->idr, fp, 0, INT_MAX - 1, GFP_NOWAIT); 583 if (ret >= 0) { 584 id = ret; 585 ret = 0; 586 } else { 587 id = KSMBD_NO_FID; 588 fd_limit_close(); 589 } 590 591 __open_id_set(fp, id, type); 592 write_unlock(&ft->lock); 593 idr_preload_end(); 594 return ret; 595 } 596 597 unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp) 598 { 599 __open_id(&global_ft, fp, OPEN_ID_TYPE_PERSISTENT_ID); 600 return fp->persistent_id; 601 } 602 603 struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) 604 { 605 struct ksmbd_file *fp; 606 int ret; 607 608 fp = kmem_cache_zalloc(filp_cache, GFP_KERNEL); 609 if (!fp) { 610 pr_err("Failed to allocate memory\n"); 611 return ERR_PTR(-ENOMEM); 612 } 613 614 INIT_LIST_HEAD(&fp->blocked_works); 615 INIT_LIST_HEAD(&fp->node); 616 INIT_LIST_HEAD(&fp->lock_list); 617 spin_lock_init(&fp->f_lock); 618 atomic_set(&fp->refcount, 1); 619 620 fp->filp = filp; 621 fp->conn = work->conn; 622 fp->tcon = work->tcon; 623 fp->volatile_id = KSMBD_NO_FID; 624 fp->persistent_id = KSMBD_NO_FID; 625 fp->f_state = FP_NEW; 626 fp->f_ci = ksmbd_inode_get(fp); 627 628 if (!fp->f_ci) { 629 ret = -ENOMEM; 630 goto err_out; 631 } 632 633 ret = __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID); 634 if (ret) { 635 ksmbd_inode_put(fp->f_ci); 636 goto err_out; 637 } 638 639 atomic_inc(&work->conn->stats.open_files_count); 640 return fp; 641 642 err_out: 643 kmem_cache_free(filp_cache, fp); 644 return ERR_PTR(ret); 645 } 646 647 void ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, 648 unsigned int state) 649 { 650 if (!fp) 651 return; 652 653 write_lock(&ft->lock); 654 fp->f_state = state; 655 write_unlock(&ft->lock); 656 } 657 658 static int 659 __close_file_table_ids(struct ksmbd_file_table *ft, 660 struct ksmbd_tree_connect *tcon, 661 bool (*skip)(struct ksmbd_tree_connect *tcon, 662 struct ksmbd_file *fp)) 663 { 664 unsigned int id; 665 struct ksmbd_file *fp; 666 int num = 0; 667 668 idr_for_each_entry(ft->idr, fp, id) { 669 if (skip(tcon, fp)) 670 continue; 671 672 set_close_state_blocked_works(fp); 673 674 if (!atomic_dec_and_test(&fp->refcount)) 675 continue; 676 __ksmbd_close_fd(ft, fp); 677 num++; 678 } 679 return num; 680 } 681 682 static inline bool is_reconnectable(struct ksmbd_file *fp) 683 { 684 struct oplock_info *opinfo = opinfo_get(fp); 685 bool reconn = false; 686 687 if (!opinfo) 688 return false; 689 690 if (opinfo->op_state != OPLOCK_STATE_NONE) { 691 opinfo_put(opinfo); 692 return false; 693 } 694 695 if (fp->is_resilient || fp->is_persistent) 696 reconn = true; 697 else if (fp->is_durable && opinfo->is_lease && 698 opinfo->o_lease->state & SMB2_LEASE_HANDLE_CACHING_LE) 699 reconn = true; 700 701 else if (fp->is_durable && opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) 702 reconn = true; 703 704 opinfo_put(opinfo); 705 return reconn; 706 } 707 708 static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon, 709 struct ksmbd_file *fp) 710 { 711 return fp->tcon != tcon; 712 } 713 714 static bool ksmbd_durable_scavenger_alive(void) 715 { 716 mutex_lock(&durable_scavenger_lock); 717 if (!durable_scavenger_running) { 718 mutex_unlock(&durable_scavenger_lock); 719 return false; 720 } 721 mutex_unlock(&durable_scavenger_lock); 722 723 if (kthread_should_stop()) 724 return false; 725 726 if (idr_is_empty(global_ft.idr)) 727 return false; 728 729 return true; 730 } 731 732 static void ksmbd_scavenger_dispose_dh(struct list_head *head) 733 { 734 while (!list_empty(head)) { 735 struct ksmbd_file *fp; 736 737 fp = list_first_entry(head, struct ksmbd_file, node); 738 list_del_init(&fp->node); 739 __ksmbd_close_fd(NULL, fp); 740 } 741 } 742 743 static int ksmbd_durable_scavenger(void *dummy) 744 { 745 struct ksmbd_file *fp = NULL; 746 unsigned int id; 747 unsigned int min_timeout = 1; 748 bool found_fp_timeout; 749 LIST_HEAD(scavenger_list); 750 unsigned long remaining_jiffies; 751 752 __module_get(THIS_MODULE); 753 754 set_freezable(); 755 while (ksmbd_durable_scavenger_alive()) { 756 if (try_to_freeze()) 757 continue; 758 759 found_fp_timeout = false; 760 761 remaining_jiffies = wait_event_timeout(dh_wq, 762 ksmbd_durable_scavenger_alive() == false, 763 __msecs_to_jiffies(min_timeout)); 764 if (remaining_jiffies) 765 min_timeout = jiffies_to_msecs(remaining_jiffies); 766 else 767 min_timeout = DURABLE_HANDLE_MAX_TIMEOUT; 768 769 write_lock(&global_ft.lock); 770 idr_for_each_entry(global_ft.idr, fp, id) { 771 if (!fp->durable_timeout) 772 continue; 773 774 if (atomic_read(&fp->refcount) > 1 || 775 fp->conn) 776 continue; 777 778 found_fp_timeout = true; 779 if (fp->durable_scavenger_timeout <= 780 jiffies_to_msecs(jiffies)) { 781 __ksmbd_remove_durable_fd(fp); 782 list_add(&fp->node, &scavenger_list); 783 } else { 784 unsigned long durable_timeout; 785 786 durable_timeout = 787 fp->durable_scavenger_timeout - 788 jiffies_to_msecs(jiffies); 789 790 if (min_timeout > durable_timeout) 791 min_timeout = durable_timeout; 792 } 793 } 794 write_unlock(&global_ft.lock); 795 796 ksmbd_scavenger_dispose_dh(&scavenger_list); 797 798 if (found_fp_timeout == false) 799 break; 800 } 801 802 mutex_lock(&durable_scavenger_lock); 803 durable_scavenger_running = false; 804 mutex_unlock(&durable_scavenger_lock); 805 806 module_put(THIS_MODULE); 807 808 return 0; 809 } 810 811 void ksmbd_launch_ksmbd_durable_scavenger(void) 812 { 813 if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)) 814 return; 815 816 mutex_lock(&durable_scavenger_lock); 817 if (durable_scavenger_running == true) { 818 mutex_unlock(&durable_scavenger_lock); 819 return; 820 } 821 822 durable_scavenger_running = true; 823 824 server_conf.dh_task = kthread_run(ksmbd_durable_scavenger, 825 (void *)NULL, "ksmbd-durable-scavenger"); 826 if (IS_ERR(server_conf.dh_task)) 827 pr_err("cannot start conn thread, err : %ld\n", 828 PTR_ERR(server_conf.dh_task)); 829 mutex_unlock(&durable_scavenger_lock); 830 } 831 832 void ksmbd_stop_durable_scavenger(void) 833 { 834 if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)) 835 return; 836 837 mutex_lock(&durable_scavenger_lock); 838 if (!durable_scavenger_running) { 839 mutex_unlock(&durable_scavenger_lock); 840 return; 841 } 842 843 durable_scavenger_running = false; 844 if (waitqueue_active(&dh_wq)) 845 wake_up(&dh_wq); 846 mutex_unlock(&durable_scavenger_lock); 847 kthread_stop(server_conf.dh_task); 848 } 849 850 static bool session_fd_check(struct ksmbd_tree_connect *tcon, 851 struct ksmbd_file *fp) 852 { 853 struct ksmbd_inode *ci; 854 struct oplock_info *op; 855 struct ksmbd_conn *conn; 856 857 if (!is_reconnectable(fp)) 858 return false; 859 860 conn = fp->conn; 861 ci = fp->f_ci; 862 down_write(&ci->m_lock); 863 list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) { 864 if (op->conn != conn) 865 continue; 866 if (op->conn && atomic_dec_and_test(&op->conn->refcnt)) 867 kfree(op->conn); 868 op->conn = NULL; 869 } 870 up_write(&ci->m_lock); 871 872 fp->conn = NULL; 873 fp->tcon = NULL; 874 fp->volatile_id = KSMBD_NO_FID; 875 876 if (fp->durable_timeout) 877 fp->durable_scavenger_timeout = 878 jiffies_to_msecs(jiffies) + fp->durable_timeout; 879 880 return true; 881 } 882 883 void ksmbd_close_tree_conn_fds(struct ksmbd_work *work) 884 { 885 int num = __close_file_table_ids(&work->sess->file_table, 886 work->tcon, 887 tree_conn_fd_check); 888 889 atomic_sub(num, &work->conn->stats.open_files_count); 890 } 891 892 void ksmbd_close_session_fds(struct ksmbd_work *work) 893 { 894 int num = __close_file_table_ids(&work->sess->file_table, 895 work->tcon, 896 session_fd_check); 897 898 atomic_sub(num, &work->conn->stats.open_files_count); 899 } 900 901 int ksmbd_init_global_file_table(void) 902 { 903 return ksmbd_init_file_table(&global_ft); 904 } 905 906 void ksmbd_free_global_file_table(void) 907 { 908 struct ksmbd_file *fp = NULL; 909 unsigned int id; 910 911 idr_for_each_entry(global_ft.idr, fp, id) { 912 ksmbd_remove_durable_fd(fp); 913 __ksmbd_close_fd(NULL, fp); 914 } 915 916 idr_destroy(global_ft.idr); 917 kfree(global_ft.idr); 918 } 919 920 int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share, 921 struct ksmbd_file *fp, char *name) 922 { 923 char *pathname, *ab_pathname; 924 int ret = 0; 925 926 pathname = kmalloc(PATH_MAX, GFP_KERNEL); 927 if (!pathname) 928 return -EACCES; 929 930 ab_pathname = d_path(&fp->filp->f_path, pathname, PATH_MAX); 931 if (IS_ERR(ab_pathname)) { 932 kfree(pathname); 933 return -EACCES; 934 } 935 936 if (name && strcmp(&ab_pathname[share->path_sz + 1], name)) { 937 ksmbd_debug(SMB, "invalid name reconnect %s\n", name); 938 ret = -EINVAL; 939 } 940 941 kfree(pathname); 942 943 return ret; 944 } 945 946 int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp) 947 { 948 struct ksmbd_inode *ci; 949 struct oplock_info *op; 950 951 if (!fp->is_durable || fp->conn || fp->tcon) { 952 pr_err("Invalid durable fd [%p:%p]\n", fp->conn, fp->tcon); 953 return -EBADF; 954 } 955 956 if (has_file_id(fp->volatile_id)) { 957 pr_err("Still in use durable fd: %llu\n", fp->volatile_id); 958 return -EBADF; 959 } 960 961 fp->conn = work->conn; 962 fp->tcon = work->tcon; 963 964 ci = fp->f_ci; 965 down_write(&ci->m_lock); 966 list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) { 967 if (op->conn) 968 continue; 969 op->conn = fp->conn; 970 atomic_inc(&op->conn->refcnt); 971 } 972 up_write(&ci->m_lock); 973 974 fp->f_state = FP_NEW; 975 __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID); 976 if (!has_file_id(fp->volatile_id)) { 977 fp->conn = NULL; 978 fp->tcon = NULL; 979 return -EBADF; 980 } 981 return 0; 982 } 983 984 int ksmbd_init_file_table(struct ksmbd_file_table *ft) 985 { 986 ft->idr = kzalloc(sizeof(struct idr), GFP_KERNEL); 987 if (!ft->idr) 988 return -ENOMEM; 989 990 idr_init(ft->idr); 991 rwlock_init(&ft->lock); 992 return 0; 993 } 994 995 void ksmbd_destroy_file_table(struct ksmbd_file_table *ft) 996 { 997 if (!ft->idr) 998 return; 999 1000 __close_file_table_ids(ft, NULL, session_fd_check); 1001 idr_destroy(ft->idr); 1002 kfree(ft->idr); 1003 ft->idr = NULL; 1004 } 1005 1006 int ksmbd_init_file_cache(void) 1007 { 1008 filp_cache = kmem_cache_create("ksmbd_file_cache", 1009 sizeof(struct ksmbd_file), 0, 1010 SLAB_HWCACHE_ALIGN, NULL); 1011 if (!filp_cache) 1012 goto out; 1013 1014 init_waitqueue_head(&dh_wq); 1015 1016 return 0; 1017 1018 out: 1019 pr_err("failed to allocate file cache\n"); 1020 return -ENOMEM; 1021 } 1022 1023 void ksmbd_exit_file_cache(void) 1024 { 1025 kmem_cache_destroy(filp_cache); 1026 } 1027
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.