1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Functions to handle the cached directory entries 4 * 5 * Copyright (c) 2022, Ronnie Sahlberg <lsahlber@redhat.com> 6 */ 7 8 #include <linux/namei.h> 9 #include "cifsglob.h" 10 #include "cifsproto.h" 11 #include "../common/smb2status.h" 12 #include "cifs_debug.h" 13 #include "smb2proto.h" 14 #include "cached_dir.h" 15 16 static struct cached_fid *init_cached_dir(const char *path); 17 static void free_cached_dir(struct cached_fid *cfid); 18 static void smb2_close_cached_fid(struct kref *ref); 19 static void cfids_laundromat_worker(struct work_struct *work); 20 static void close_cached_dir_locked(struct cached_fid *cfid); 21 22 struct cached_dir_dentry { 23 struct list_head entry; 24 struct dentry *dentry; 25 }; 26 27 static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, 28 const char *path, 29 bool lookup_only, 30 __u32 max_cached_dirs) 31 { 32 struct cached_fid *cfid; 33 34 list_for_each_entry(cfid, &cfids->entries, entry) { 35 if (!strcmp(cfid->path, path)) { 36 /* 37 * If it doesn't have a lease it is either not yet 38 * fully cached or it may be in the process of 39 * being deleted due to a lease break. 40 */ 41 if (!is_valid_cached_dir(cfid)) 42 return NULL; 43 kref_get(&cfid->refcount); 44 return cfid; 45 } 46 } 47 if (lookup_only) { 48 return NULL; 49 } 50 if (cfids->num_entries >= max_cached_dirs) { 51 return NULL; 52 } 53 cfid = init_cached_dir(path); 54 if (cfid == NULL) { 55 return NULL; 56 } 57 cfid->cfids = cfids; 58 cfids->num_entries++; 59 list_add(&cfid->entry, &cfids->entries); 60 cfid->on_list = true; 61 kref_get(&cfid->refcount); 62 /* 63 * Set @cfid->has_lease to true during construction so that the lease 64 * reference can be put in cached_dir_lease_break() due to a potential 65 * lease break right after the request is sent or while @cfid is still 66 * being cached, or if a reconnection is triggered during construction. 67 * Concurrent processes won't be to use it yet due to @cfid->time being 68 * zero. 69 */ 70 cfid->has_lease = true; 71 72 return cfid; 73 } 74 75 static struct dentry * 76 path_to_dentry(struct cifs_sb_info *cifs_sb, const char *path) 77 { 78 struct dentry *dentry; 79 const char *s, *p; 80 char sep; 81 82 sep = CIFS_DIR_SEP(cifs_sb); 83 dentry = dget(cifs_sb->root); 84 s = path; 85 86 do { 87 struct inode *dir = d_inode(dentry); 88 struct dentry *child; 89 90 if (!S_ISDIR(dir->i_mode)) { 91 dput(dentry); 92 dentry = ERR_PTR(-ENOTDIR); 93 break; 94 } 95 96 /* skip separators */ 97 while (*s == sep) 98 s++; 99 if (!*s) 100 break; 101 p = s++; 102 /* next separator */ 103 while (*s && *s != sep) 104 s++; 105 106 child = lookup_noperm_positive_unlocked(&QSTR_LEN(p, s - p), 107 dentry); 108 dput(dentry); 109 dentry = child; 110 } while (!IS_ERR(dentry)); 111 return dentry; 112 } 113 114 static const char *path_no_prefix(struct cifs_sb_info *cifs_sb, 115 const char *path) 116 { 117 size_t len = 0; 118 119 if (!*path) 120 return path; 121 122 if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH) && 123 cifs_sb->prepath) { 124 len = strlen(cifs_sb->prepath) + 1; 125 if (unlikely(len > strlen(path))) 126 return ERR_PTR(-EINVAL); 127 } 128 return path + len; 129 } 130 131 /* 132 * Open the and cache a directory handle. 133 * If error then *cfid is not initialized. 134 */ 135 int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, 136 const char *path, 137 struct cifs_sb_info *cifs_sb, 138 bool lookup_only, struct cached_fid **ret_cfid) 139 { 140 struct cifs_ses *ses; 141 struct TCP_Server_Info *server; 142 struct cifs_open_parms oparms; 143 struct smb2_create_rsp *o_rsp = NULL; 144 struct smb2_query_info_rsp *qi_rsp = NULL; 145 int resp_buftype[2]; 146 struct smb_rqst rqst[2]; 147 struct kvec rsp_iov[2]; 148 struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; 149 struct kvec qi_iov[1]; 150 int rc, flags = 0; 151 __le16 *utf16_path = NULL; 152 u8 oplock = SMB2_OPLOCK_LEVEL_II; 153 struct cifs_fid *pfid; 154 struct dentry *dentry = NULL; 155 struct cached_fid *cfid; 156 struct cached_fids *cfids; 157 const char *npath; 158 int retries = 0, cur_sleep = 0; 159 __le32 lease_flags = 0; 160 161 if (cifs_sb->root == NULL) 162 return -ENOENT; 163 164 if (tcon == NULL) 165 return -EOPNOTSUPP; 166 167 ses = tcon->ses; 168 cfids = tcon->cfids; 169 170 if (cfids == NULL) 171 return -EOPNOTSUPP; 172 173 replay_again: 174 /* reinitialize for possible replay */ 175 flags = 0; 176 oplock = SMB2_OPLOCK_LEVEL_II; 177 server = cifs_pick_channel(ses); 178 179 if (!server->ops->new_lease_key) 180 return smb_EIO(smb_eio_trace_no_lease_key); 181 182 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 183 if (!utf16_path) 184 return -ENOMEM; 185 186 spin_lock(&cfids->cfid_list_lock); 187 cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs); 188 if (cfid == NULL) { 189 spin_unlock(&cfids->cfid_list_lock); 190 kfree(utf16_path); 191 return -ENOENT; 192 } 193 /* 194 * Return cached fid if it is valid (has a lease and has a time). 195 * Otherwise, it is either a new entry or laundromat worker removed it 196 * from @cfids->entries. Caller will put last reference if the latter. 197 */ 198 if (is_valid_cached_dir(cfid)) { 199 cfid->last_access_time = jiffies; 200 spin_unlock(&cfids->cfid_list_lock); 201 *ret_cfid = cfid; 202 kfree(utf16_path); 203 return 0; 204 } 205 spin_unlock(&cfids->cfid_list_lock); 206 207 pfid = &cfid->fid; 208 209 /* 210 * Skip any prefix paths in @path as lookup_noperm_positive_unlocked() ends up 211 * calling ->lookup() which already adds those through 212 * build_path_from_dentry(). Also, do it earlier as we might reconnect 213 * below when trying to send compounded request and then potentially 214 * having a different prefix path (e.g. after DFS failover). 215 */ 216 npath = path_no_prefix(cifs_sb, path); 217 if (IS_ERR(npath)) { 218 rc = PTR_ERR(npath); 219 goto out; 220 } 221 222 if (!npath[0]) { 223 dentry = dget(cifs_sb->root); 224 } else { 225 dentry = path_to_dentry(cifs_sb, npath); 226 if (IS_ERR(dentry)) { 227 rc = -ENOENT; 228 goto out; 229 } 230 if (dentry->d_parent && server->dialect >= SMB30_PROT_ID) { 231 struct cached_fid *parent_cfid; 232 233 spin_lock(&cfids->cfid_list_lock); 234 list_for_each_entry(parent_cfid, &cfids->entries, entry) { 235 if (parent_cfid->dentry == dentry->d_parent) { 236 cifs_dbg(FYI, "found a parent cached file handle\n"); 237 if (is_valid_cached_dir(parent_cfid)) { 238 lease_flags 239 |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE; 240 memcpy(pfid->parent_lease_key, 241 parent_cfid->fid.lease_key, 242 SMB2_LEASE_KEY_SIZE); 243 } 244 break; 245 } 246 } 247 spin_unlock(&cfids->cfid_list_lock); 248 } 249 } 250 cfid->dentry = dentry; 251 cfid->tcon = tcon; 252 253 /* 254 * We do not hold the lock for the open because in case 255 * SMB2_open needs to reconnect. 256 * This is safe because no other thread will be able to get a ref 257 * to the cfid until we have finished opening the file and (possibly) 258 * acquired a lease. 259 */ 260 if (smb3_encryption_required(tcon)) 261 flags |= CIFS_TRANSFORM_REQ; 262 263 server->ops->new_lease_key(pfid); 264 265 memset(rqst, 0, sizeof(rqst)); 266 resp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER; 267 memset(rsp_iov, 0, sizeof(rsp_iov)); 268 269 /* Open */ 270 memset(&open_iov, 0, sizeof(open_iov)); 271 rqst[0].rq_iov = open_iov; 272 rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; 273 274 oparms = (struct cifs_open_parms) { 275 .tcon = tcon, 276 .path = path, 277 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE), 278 .desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES | 279 FILE_READ_EA, 280 .disposition = FILE_OPEN, 281 .fid = pfid, 282 .lease_flags = lease_flags, 283 .replay = !!(retries), 284 }; 285 286 rc = SMB2_open_init(tcon, server, 287 &rqst[0], &oplock, &oparms, utf16_path); 288 if (rc) 289 goto oshr_free; 290 291 if (oplock != SMB2_OPLOCK_LEVEL_II) { 292 rc = -EINVAL; 293 cifs_dbg(FYI, "%s: Oplock level %d not suitable for cached directory\n", 294 __func__, oplock); 295 goto oshr_free; 296 } 297 298 smb2_set_next_command(tcon, &rqst[0]); 299 300 memset(&qi_iov, 0, sizeof(qi_iov)); 301 rqst[1].rq_iov = qi_iov; 302 rqst[1].rq_nvec = 1; 303 304 rc = SMB2_query_info_init(tcon, server, 305 &rqst[1], COMPOUND_FID, 306 COMPOUND_FID, FILE_ALL_INFORMATION, 307 SMB2_O_INFO_FILE, 0, 308 sizeof(struct smb2_file_all_info) + 309 PATH_MAX * 2, 0, NULL); 310 if (rc) 311 goto oshr_free; 312 313 smb2_set_related(&rqst[1]); 314 315 if (retries) { 316 /* Back-off before retry */ 317 if (cur_sleep) 318 msleep(cur_sleep); 319 320 smb2_set_replay(server, &rqst[0]); 321 smb2_set_replay(server, &rqst[1]); 322 } 323 324 rc = compound_send_recv(xid, ses, server, 325 flags, 2, rqst, 326 resp_buftype, rsp_iov); 327 if (rc == -EREMCHG) { 328 tcon->need_reconnect = true; 329 pr_warn_once("server share %s deleted\n", 330 tcon->tree_name); 331 } 332 333 if (!rsp_iov[0].iov_base || rsp_iov[0].iov_len < sizeof(*o_rsp)) { 334 if (!rc) 335 rc = -EIO; 336 goto oshr_free; 337 } 338 339 o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base; 340 if (o_rsp->hdr.Status != STATUS_SUCCESS) { 341 if (!rc) 342 rc = -EIO; 343 goto oshr_free; 344 } 345 346 oparms.fid->persistent_fid = o_rsp->PersistentFileId; 347 oparms.fid->volatile_fid = o_rsp->VolatileFileId; 348 #ifdef CONFIG_CIFS_DEBUG2 349 oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId); 350 #endif /* CIFS_DEBUG2 */ 351 cfid->is_open = true; 352 atomic_inc(&tcon->num_remote_opens); 353 354 if (rc) 355 goto oshr_free; 356 357 spin_lock(&cfids->cfid_list_lock); 358 359 if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) { 360 spin_unlock(&cfids->cfid_list_lock); 361 rc = -EINVAL; 362 goto oshr_free; 363 } 364 365 rc = smb2_parse_contexts(server, rsp_iov, 366 &oparms.fid->epoch, 367 oparms.fid->lease_key, 368 &oplock, NULL, NULL); 369 if (rc) { 370 spin_unlock(&cfids->cfid_list_lock); 371 goto oshr_free; 372 } 373 374 rc = -EINVAL; 375 if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) { 376 spin_unlock(&cfids->cfid_list_lock); 377 goto oshr_free; 378 } 379 qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; 380 if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) { 381 spin_unlock(&cfids->cfid_list_lock); 382 goto oshr_free; 383 } 384 if (!smb2_validate_and_copy_iov( 385 le16_to_cpu(qi_rsp->OutputBufferOffset), 386 sizeof(struct smb2_file_all_info), 387 &rsp_iov[1], sizeof(struct smb2_file_all_info), 388 (char *)&cfid->file_all_info)) 389 cfid->file_all_info_is_valid = true; 390 391 cfid->time = jiffies; 392 cfid->last_access_time = jiffies; 393 spin_unlock(&cfids->cfid_list_lock); 394 /* At this point the directory handle is fully cached */ 395 rc = 0; 396 397 oshr_free: 398 SMB2_open_free(&rqst[0]); 399 SMB2_query_info_free(&rqst[1]); 400 free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); 401 free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 402 out: 403 if (rc) { 404 spin_lock(&cfids->cfid_list_lock); 405 if (cfid->on_list) { 406 list_del(&cfid->entry); 407 cfid->on_list = false; 408 cfids->num_entries--; 409 } 410 if (cfid->has_lease) { 411 /* 412 * We are guaranteed to have two references at this 413 * point. One for the caller and one for a potential 414 * lease. Release one here, and the second below. 415 */ 416 cfid->has_lease = false; 417 close_cached_dir_locked(cfid); 418 } 419 spin_unlock(&cfids->cfid_list_lock); 420 421 close_cached_dir(cfid); 422 } else { 423 *ret_cfid = cfid; 424 } 425 kfree(utf16_path); 426 427 if (is_replayable_error(rc) && 428 smb2_should_replay(tcon, &retries, &cur_sleep)) 429 goto replay_again; 430 431 return rc; 432 } 433 434 int open_cached_dir_by_dentry(struct cifs_tcon *tcon, 435 struct dentry *dentry, 436 struct cached_fid **ret_cfid) 437 { 438 struct cached_fid *cfid; 439 struct cached_fids *cfids = tcon->cfids; 440 441 if (cfids == NULL) 442 return -EOPNOTSUPP; 443 444 if (!dentry) 445 return -ENOENT; 446 447 spin_lock(&cfids->cfid_list_lock); 448 list_for_each_entry(cfid, &cfids->entries, entry) { 449 if (cfid->dentry == dentry) { 450 if (!is_valid_cached_dir(cfid)) 451 break; 452 cifs_dbg(FYI, "found a cached file handle by dentry\n"); 453 kref_get(&cfid->refcount); 454 *ret_cfid = cfid; 455 cfid->last_access_time = jiffies; 456 spin_unlock(&cfids->cfid_list_lock); 457 return 0; 458 } 459 } 460 spin_unlock(&cfids->cfid_list_lock); 461 return -ENOENT; 462 } 463 464 static void 465 smb2_close_cached_fid(struct kref *ref) 466 __releases(&cfid->cfids->cfid_list_lock) 467 { 468 struct cached_fid *cfid = container_of(ref, struct cached_fid, 469 refcount); 470 int rc; 471 472 lockdep_assert_held(&cfid->cfids->cfid_list_lock); 473 474 if (cfid->on_list) { 475 list_del(&cfid->entry); 476 cfid->on_list = false; 477 cfid->cfids->num_entries--; 478 } 479 spin_unlock(&cfid->cfids->cfid_list_lock); 480 481 dput(cfid->dentry); 482 cfid->dentry = NULL; 483 484 if (cfid->is_open) { 485 rc = SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid, 486 cfid->fid.volatile_fid); 487 if (rc) /* should we retry on -EBUSY or -EAGAIN? */ 488 cifs_dbg(VFS, "close cached dir rc %d\n", rc); 489 } 490 491 free_cached_dir(cfid); 492 } 493 494 void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon, 495 const char *name, struct cifs_sb_info *cifs_sb) 496 { 497 struct cached_fid *cfid = NULL; 498 int rc; 499 500 rc = open_cached_dir(xid, tcon, name, cifs_sb, true, &cfid); 501 if (rc) { 502 cifs_dbg(FYI, "no cached dir found for rmdir(%s)\n", name); 503 return; 504 } 505 spin_lock(&cfid->cfids->cfid_list_lock); 506 if (cfid->has_lease) { 507 cfid->has_lease = false; 508 close_cached_dir_locked(cfid); 509 } 510 spin_unlock(&cfid->cfids->cfid_list_lock); 511 close_cached_dir(cfid); 512 } 513 514 /** 515 * close_cached_dir - drop a reference of a cached dir 516 * 517 * The release function will be called with cfid_list_lock held to remove the 518 * cached dirs from the list before any other thread can take another @cfid 519 * ref. Must not be called with cfid_list_lock held; use 520 * close_cached_dir_locked() called instead. 521 * 522 * @cfid: cached dir 523 */ 524 void close_cached_dir(struct cached_fid *cfid) 525 { 526 lockdep_assert_not_held(&cfid->cfids->cfid_list_lock); 527 kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock); 528 } 529 530 /** 531 * close_cached_dir_locked - put a reference of a cached dir with 532 * cfid_list_lock held 533 * 534 * Calling close_cached_dir() with cfid_list_lock held has the potential effect 535 * of causing a deadlock if the invariant of refcount >= 2 is false. 536 * 537 * This function is used in paths that hold cfid_list_lock and expect at least 538 * two references. If that invariant is violated, WARNs and returns without 539 * dropping a reference; the final put must still go through 540 * close_cached_dir(). 541 * 542 * @cfid: cached dir 543 */ 544 static void close_cached_dir_locked(struct cached_fid *cfid) 545 { 546 lockdep_assert_held(&cfid->cfids->cfid_list_lock); 547 548 if (WARN_ON(kref_read(&cfid->refcount) < 2)) 549 return; 550 551 kref_put(&cfid->refcount, smb2_close_cached_fid); 552 } 553 554 /* 555 * Called from cifs_kill_sb when we unmount a share 556 */ 557 void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) 558 { 559 struct rb_root *root = &cifs_sb->tlink_tree; 560 struct rb_node *node; 561 struct cached_fid *cfid; 562 struct cifs_tcon *tcon; 563 struct tcon_link *tlink; 564 struct cached_fids *cfids; 565 struct cached_dir_dentry *tmp_list, *q; 566 LIST_HEAD(entry); 567 568 spin_lock(&cifs_sb->tlink_tree_lock); 569 for (node = rb_first(root); node; node = rb_next(node)) { 570 tlink = rb_entry(node, struct tcon_link, tl_rbnode); 571 tcon = tlink_tcon(tlink); 572 if (IS_ERR(tcon)) 573 continue; 574 cfids = tcon->cfids; 575 if (cfids == NULL) 576 continue; 577 spin_lock(&cfids->cfid_list_lock); 578 list_for_each_entry(cfid, &cfids->entries, entry) { 579 tmp_list = kmalloc_obj(*tmp_list, GFP_ATOMIC); 580 if (tmp_list == NULL) { 581 /* 582 * If the malloc() fails, we won't drop all 583 * dentries, and unmounting is likely to trigger 584 * a 'Dentry still in use' error. 585 */ 586 cifs_tcon_dbg(VFS, "Out of memory while dropping dentries\n"); 587 spin_unlock(&cfids->cfid_list_lock); 588 spin_unlock(&cifs_sb->tlink_tree_lock); 589 goto done; 590 } 591 592 tmp_list->dentry = cfid->dentry; 593 cfid->dentry = NULL; 594 595 list_add_tail(&tmp_list->entry, &entry); 596 } 597 spin_unlock(&cfids->cfid_list_lock); 598 } 599 spin_unlock(&cifs_sb->tlink_tree_lock); 600 601 done: 602 list_for_each_entry_safe(tmp_list, q, &entry, entry) { 603 list_del(&tmp_list->entry); 604 dput(tmp_list->dentry); 605 kfree(tmp_list); 606 } 607 608 /* Flush any pending work that will drop dentries */ 609 flush_workqueue(cfid_put_wq); 610 } 611 612 /* 613 * Invalidate all cached dirs when a TCON has been reset 614 * due to a session loss. 615 */ 616 void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync) 617 { 618 struct cached_fids *cfids = tcon->cfids; 619 struct cached_fid *cfid, *q; 620 621 if (cfids == NULL) 622 return; 623 624 /* 625 * Mark all the cfids as closed, and move them to the cfids->dying list. 626 * They'll be cleaned up by laundromat. Take a reference to each cfid 627 * during this process. 628 */ 629 spin_lock(&cfids->cfid_list_lock); 630 list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { 631 list_move(&cfid->entry, &cfids->dying); 632 cfids->num_entries--; 633 cfid->is_open = false; 634 cfid->on_list = false; 635 if (cfid->has_lease) { 636 /* 637 * The lease was never cancelled from the server, 638 * so steal that reference. 639 */ 640 cfid->has_lease = false; 641 } else 642 kref_get(&cfid->refcount); 643 } 644 spin_unlock(&cfids->cfid_list_lock); 645 646 /* run laundromat unconditionally now as there might have been previously queued work */ 647 mod_delayed_work(cfid_put_wq, &cfids->laundromat_work, 0); 648 if (sync) 649 flush_delayed_work(&cfids->laundromat_work); 650 } 651 652 static void 653 cached_dir_offload_close(struct work_struct *work) 654 { 655 struct cached_fid *cfid = container_of(work, 656 struct cached_fid, close_work); 657 struct cifs_tcon *tcon = cfid->tcon; 658 659 WARN_ON(cfid->on_list); 660 661 close_cached_dir(cfid); 662 cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close); 663 } 664 665 /* 666 * Release the cached directory's dentry, and then queue work to drop cached 667 * directory itself (closing on server if needed). 668 * 669 * Must be called with a reference to the cached_fid and a reference to the 670 * tcon. 671 */ 672 static void cached_dir_put_work(struct work_struct *work) 673 { 674 struct cached_fid *cfid = container_of(work, struct cached_fid, 675 put_work); 676 dput(cfid->dentry); 677 cfid->dentry = NULL; 678 679 queue_work(serverclose_wq, &cfid->close_work); 680 } 681 682 bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]) 683 { 684 struct cached_fids *cfids = tcon->cfids; 685 struct cached_fid *cfid; 686 687 if (cfids == NULL) 688 return false; 689 690 spin_lock(&cfids->cfid_list_lock); 691 list_for_each_entry(cfid, &cfids->entries, entry) { 692 if (cfid->has_lease && 693 !memcmp(lease_key, 694 cfid->fid.lease_key, 695 SMB2_LEASE_KEY_SIZE)) { 696 cfid->has_lease = false; 697 cfid->time = 0; 698 /* 699 * We found a lease remove it from the list 700 * so no threads can access it. 701 */ 702 list_del(&cfid->entry); 703 cfid->on_list = false; 704 cfids->num_entries--; 705 706 ++tcon->tc_count; 707 trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count, 708 netfs_trace_tcon_ref_get_cached_lease_break); 709 queue_work(cfid_put_wq, &cfid->put_work); 710 spin_unlock(&cfids->cfid_list_lock); 711 return true; 712 } 713 } 714 spin_unlock(&cfids->cfid_list_lock); 715 return false; 716 } 717 718 static struct cached_fid *init_cached_dir(const char *path) 719 { 720 struct cached_fid *cfid; 721 722 cfid = kzalloc_obj(*cfid, GFP_ATOMIC); 723 if (!cfid) 724 return NULL; 725 cfid->path = kstrdup(path, GFP_ATOMIC); 726 if (!cfid->path) { 727 kfree(cfid); 728 return NULL; 729 } 730 731 INIT_WORK(&cfid->close_work, cached_dir_offload_close); 732 INIT_WORK(&cfid->put_work, cached_dir_put_work); 733 INIT_LIST_HEAD(&cfid->entry); 734 INIT_LIST_HEAD(&cfid->dirents.entries); 735 mutex_init(&cfid->dirents.de_mutex); 736 kref_init(&cfid->refcount); 737 return cfid; 738 } 739 740 static void free_cached_dir(struct cached_fid *cfid) 741 { 742 struct cached_dirent *dirent, *q; 743 744 WARN_ON(work_pending(&cfid->close_work)); 745 WARN_ON(work_pending(&cfid->put_work)); 746 747 dput(cfid->dentry); 748 cfid->dentry = NULL; 749 750 /* 751 * Delete all cached dirent names 752 */ 753 list_for_each_entry_safe(dirent, q, &cfid->dirents.entries, entry) { 754 list_del(&dirent->entry); 755 kfree(dirent->name); 756 kfree(dirent); 757 } 758 759 /* adjust tcon-level counters and reset per-dir accounting */ 760 if (cfid->cfids) { 761 if (cfid->dirents.entries_count) 762 atomic_long_sub((long)cfid->dirents.entries_count, 763 &cfid->cfids->total_dirents_entries); 764 if (cfid->dirents.bytes_used) { 765 atomic64_sub((long long)cfid->dirents.bytes_used, 766 &cfid->cfids->total_dirents_bytes); 767 atomic64_sub((long long)cfid->dirents.bytes_used, 768 &cifs_dircache_bytes_used); 769 } 770 } 771 cfid->dirents.entries_count = 0; 772 cfid->dirents.bytes_used = 0; 773 774 kfree(cfid->path); 775 cfid->path = NULL; 776 kfree(cfid); 777 } 778 779 static void cfids_laundromat_worker(struct work_struct *work) 780 { 781 struct cached_fids *cfids; 782 struct cached_fid *cfid, *q; 783 LIST_HEAD(entry); 784 785 cfids = container_of(work, struct cached_fids, laundromat_work.work); 786 787 spin_lock(&cfids->cfid_list_lock); 788 /* move cfids->dying to the local list */ 789 list_cut_before(&entry, &cfids->dying, &cfids->dying); 790 791 list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { 792 if (cfid->last_access_time && 793 time_after(jiffies, cfid->last_access_time + HZ * dir_cache_timeout)) { 794 cfid->on_list = false; 795 list_move(&cfid->entry, &entry); 796 cfids->num_entries--; 797 if (cfid->has_lease) { 798 /* 799 * Our lease has not yet been cancelled from the 800 * server. Steal that reference. 801 */ 802 cfid->has_lease = false; 803 } else 804 kref_get(&cfid->refcount); 805 } 806 } 807 spin_unlock(&cfids->cfid_list_lock); 808 809 list_for_each_entry_safe(cfid, q, &entry, entry) { 810 list_del(&cfid->entry); 811 812 dput(cfid->dentry); 813 cfid->dentry = NULL; 814 815 if (cfid->is_open) { 816 spin_lock(&cfid->tcon->tc_lock); 817 ++cfid->tcon->tc_count; 818 trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count, 819 netfs_trace_tcon_ref_get_cached_laundromat); 820 spin_unlock(&cfid->tcon->tc_lock); 821 queue_work(serverclose_wq, &cfid->close_work); 822 } else 823 /* 824 * Drop the ref-count from above, either the lease-ref (if there 825 * was one) or the extra one acquired. 826 */ 827 close_cached_dir(cfid); 828 } 829 queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, 830 dir_cache_timeout * HZ); 831 } 832 833 struct cached_fids *init_cached_dirs(void) 834 { 835 struct cached_fids *cfids; 836 837 cfids = kzalloc_obj(*cfids); 838 if (!cfids) 839 return NULL; 840 spin_lock_init(&cfids->cfid_list_lock); 841 INIT_LIST_HEAD(&cfids->entries); 842 INIT_LIST_HEAD(&cfids->dying); 843 844 INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker); 845 queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, 846 dir_cache_timeout * HZ); 847 848 atomic_long_set(&cfids->total_dirents_entries, 0); 849 atomic64_set(&cfids->total_dirents_bytes, 0); 850 851 return cfids; 852 } 853 854 /* 855 * Called from tconInfoFree when we are tearing down the tcon. 856 * There are no active users or open files/directories at this point. 857 */ 858 void free_cached_dirs(struct cached_fids *cfids) 859 { 860 struct cached_fid *cfid, *q; 861 LIST_HEAD(entry); 862 863 if (cfids == NULL) 864 return; 865 866 cancel_delayed_work_sync(&cfids->laundromat_work); 867 868 spin_lock(&cfids->cfid_list_lock); 869 list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { 870 cfid->on_list = false; 871 cfid->is_open = false; 872 list_move(&cfid->entry, &entry); 873 } 874 list_for_each_entry_safe(cfid, q, &cfids->dying, entry) { 875 cfid->on_list = false; 876 cfid->is_open = false; 877 list_move(&cfid->entry, &entry); 878 } 879 spin_unlock(&cfids->cfid_list_lock); 880 881 list_for_each_entry_safe(cfid, q, &entry, entry) { 882 list_del(&cfid->entry); 883 free_cached_dir(cfid); 884 } 885 886 kfree(cfids); 887 } 888