file.c (0fdada1ef5b10ea73bf618d0498723c7860b5be9) | file.c (6f17163b9339fac92023a1d9bef22128db3b9a4b) |
---|---|
1// SPDX-License-Identifier: LGPL-2.1 2/* 3 * 4 * vfs operations that deal with files 5 * 6 * Copyright (C) International Business Machines Corp., 2002,2010 7 * Author(s): Steve French (sfrench@us.ibm.com) 8 * Jeremy Allison (jra@samba.org) --- 445 unchanged lines hidden (view full) --- 454void 455cifs_down_write(struct rw_semaphore *sem) 456{ 457 while (!down_write_trylock(sem)) 458 msleep(10); 459} 460 461static void cifsFileInfo_put_work(struct work_struct *work); | 1// SPDX-License-Identifier: LGPL-2.1 2/* 3 * 4 * vfs operations that deal with files 5 * 6 * Copyright (C) International Business Machines Corp., 2002,2010 7 * Author(s): Steve French (sfrench@us.ibm.com) 8 * Jeremy Allison (jra@samba.org) --- 445 unchanged lines hidden (view full) --- 454void 455cifs_down_write(struct rw_semaphore *sem) 456{ 457 while (!down_write_trylock(sem)) 458 msleep(10); 459} 460 461static void cifsFileInfo_put_work(struct work_struct *work); |
462void serverclose_work(struct work_struct *work); |
|
462 463struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, 464 struct tcon_link *tlink, __u32 oplock, 465 const char *symlink_target) 466{ 467 struct dentry *dentry = file_dentry(file); 468 struct inode *inode = d_inode(dentry); 469 struct cifsInodeInfo *cinode = CIFS_I(inode); --- 30 unchanged lines hidden (view full) --- 500 cfile->uid = current_fsuid(); 501 cfile->dentry = dget(dentry); 502 cfile->f_flags = file->f_flags; 503 cfile->invalidHandle = false; 504 cfile->deferred_close_scheduled = false; 505 cfile->tlink = cifs_get_tlink(tlink); 506 INIT_WORK(&cfile->oplock_break, cifs_oplock_break); 507 INIT_WORK(&cfile->put, cifsFileInfo_put_work); | 463 464struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, 465 struct tcon_link *tlink, __u32 oplock, 466 const char *symlink_target) 467{ 468 struct dentry *dentry = file_dentry(file); 469 struct inode *inode = d_inode(dentry); 470 struct cifsInodeInfo *cinode = CIFS_I(inode); --- 30 unchanged lines hidden (view full) --- 501 cfile->uid = current_fsuid(); 502 cfile->dentry = dget(dentry); 503 cfile->f_flags = file->f_flags; 504 cfile->invalidHandle = false; 505 cfile->deferred_close_scheduled = false; 506 cfile->tlink = cifs_get_tlink(tlink); 507 INIT_WORK(&cfile->oplock_break, cifs_oplock_break); 508 INIT_WORK(&cfile->put, cifsFileInfo_put_work); |
509 INIT_WORK(&cfile->serverclose, serverclose_work); |
|
508 INIT_DELAYED_WORK(&cfile->deferred, smb2_deferred_work_close); 509 mutex_init(&cfile->fh_mutex); 510 spin_lock_init(&cfile->file_info_lock); 511 512 cifs_sb_active(inode->i_sb); 513 514 /* 515 * If the server returned a read oplock and we have mandatory brlocks, --- 75 unchanged lines hidden (view full) --- 591static void cifsFileInfo_put_work(struct work_struct *work) 592{ 593 struct cifsFileInfo *cifs_file = container_of(work, 594 struct cifsFileInfo, put); 595 596 cifsFileInfo_put_final(cifs_file); 597} 598 | 510 INIT_DELAYED_WORK(&cfile->deferred, smb2_deferred_work_close); 511 mutex_init(&cfile->fh_mutex); 512 spin_lock_init(&cfile->file_info_lock); 513 514 cifs_sb_active(inode->i_sb); 515 516 /* 517 * If the server returned a read oplock and we have mandatory brlocks, --- 75 unchanged lines hidden (view full) --- 593static void cifsFileInfo_put_work(struct work_struct *work) 594{ 595 struct cifsFileInfo *cifs_file = container_of(work, 596 struct cifsFileInfo, put); 597 598 cifsFileInfo_put_final(cifs_file); 599} 600 |
601void serverclose_work(struct work_struct *work) 602{ 603 struct cifsFileInfo *cifs_file = container_of(work, 604 struct cifsFileInfo, serverclose); 605 606 struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); 607 608 struct TCP_Server_Info *server = tcon->ses->server; 609 int rc = 0; 610 int retries = 0; 611 int MAX_RETRIES = 4; 612 613 do { 614 if (server->ops->close_getattr) 615 rc = server->ops->close_getattr(0, tcon, cifs_file); 616 else if (server->ops->close) 617 rc = server->ops->close(0, tcon, &cifs_file->fid); 618 619 if (rc == -EBUSY || rc == -EAGAIN) { 620 retries++; 621 msleep(250); 622 } 623 } while ((rc == -EBUSY || rc == -EAGAIN) && (retries < MAX_RETRIES) 624 ); 625 626 if (retries == MAX_RETRIES) 627 pr_warn("Serverclose failed %d times, giving up\n", MAX_RETRIES); 628 629 if (cifs_file->offload) 630 queue_work(fileinfo_put_wq, &cifs_file->put); 631 else 632 cifsFileInfo_put_final(cifs_file); 633} 634 |
|
599/** 600 * cifsFileInfo_put - release a reference of file priv data 601 * 602 * Always potentially wait for oplock handler. See _cifsFileInfo_put(). 603 * 604 * @cifs_file: cifs/smb3 specific info (eg refcounts) for an open file 605 */ 606void cifsFileInfo_put(struct cifsFileInfo *cifs_file) --- 24 unchanged lines hidden (view full) --- 631 struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); 632 struct TCP_Server_Info *server = tcon->ses->server; 633 struct cifsInodeInfo *cifsi = CIFS_I(inode); 634 struct super_block *sb = inode->i_sb; 635 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 636 struct cifs_fid fid = {}; 637 struct cifs_pending_open open; 638 bool oplock_break_cancelled; | 635/** 636 * cifsFileInfo_put - release a reference of file priv data 637 * 638 * Always potentially wait for oplock handler. See _cifsFileInfo_put(). 639 * 640 * @cifs_file: cifs/smb3 specific info (eg refcounts) for an open file 641 */ 642void cifsFileInfo_put(struct cifsFileInfo *cifs_file) --- 24 unchanged lines hidden (view full) --- 667 struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); 668 struct TCP_Server_Info *server = tcon->ses->server; 669 struct cifsInodeInfo *cifsi = CIFS_I(inode); 670 struct super_block *sb = inode->i_sb; 671 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 672 struct cifs_fid fid = {}; 673 struct cifs_pending_open open; 674 bool oplock_break_cancelled; |
675 bool serverclose_offloaded = false; |
|
639 640 spin_lock(&tcon->open_file_lock); 641 spin_lock(&cifsi->open_file_lock); 642 spin_lock(&cifs_file->file_info_lock); | 676 677 spin_lock(&tcon->open_file_lock); 678 spin_lock(&cifsi->open_file_lock); 679 spin_lock(&cifs_file->file_info_lock); |
680 681 cifs_file->offload = offload; |
|
643 if (--cifs_file->count > 0) { 644 spin_unlock(&cifs_file->file_info_lock); 645 spin_unlock(&cifsi->open_file_lock); 646 spin_unlock(&tcon->open_file_lock); 647 return; 648 } 649 spin_unlock(&cifs_file->file_info_lock); 650 --- 25 unchanged lines hidden (view full) --- 676 spin_unlock(&tcon->open_file_lock); 677 678 oplock_break_cancelled = wait_oplock_handler ? 679 cancel_work_sync(&cifs_file->oplock_break) : false; 680 681 if (!tcon->need_reconnect && !cifs_file->invalidHandle) { 682 struct TCP_Server_Info *server = tcon->ses->server; 683 unsigned int xid; | 682 if (--cifs_file->count > 0) { 683 spin_unlock(&cifs_file->file_info_lock); 684 spin_unlock(&cifsi->open_file_lock); 685 spin_unlock(&tcon->open_file_lock); 686 return; 687 } 688 spin_unlock(&cifs_file->file_info_lock); 689 --- 25 unchanged lines hidden (view full) --- 715 spin_unlock(&tcon->open_file_lock); 716 717 oplock_break_cancelled = wait_oplock_handler ? 718 cancel_work_sync(&cifs_file->oplock_break) : false; 719 720 if (!tcon->need_reconnect && !cifs_file->invalidHandle) { 721 struct TCP_Server_Info *server = tcon->ses->server; 722 unsigned int xid; |
723 int rc = 0; |
|
684 685 xid = get_xid(); 686 if (server->ops->close_getattr) | 724 725 xid = get_xid(); 726 if (server->ops->close_getattr) |
687 server->ops->close_getattr(xid, tcon, cifs_file); | 727 rc = server->ops->close_getattr(xid, tcon, cifs_file); |
688 else if (server->ops->close) | 728 else if (server->ops->close) |
689 server->ops->close(xid, tcon, &cifs_file->fid); | 729 rc = server->ops->close(xid, tcon, &cifs_file->fid); |
690 _free_xid(xid); | 730 _free_xid(xid); |
731 732 if (rc == -EBUSY || rc == -EAGAIN) { 733 // Server close failed, hence offloading it as an async op 734 queue_work(serverclose_wq, &cifs_file->serverclose); 735 serverclose_offloaded = true; 736 } |
|
691 } 692 693 if (oplock_break_cancelled) 694 cifs_done_oplock_break(cifsi); 695 696 cifs_del_pending_open(&open); 697 | 737 } 738 739 if (oplock_break_cancelled) 740 cifs_done_oplock_break(cifsi); 741 742 cifs_del_pending_open(&open); 743 |
698 if (offload) 699 queue_work(fileinfo_put_wq, &cifs_file->put); 700 else 701 cifsFileInfo_put_final(cifs_file); | 744 // if serverclose has been offloaded to wq (on failure), it will 745 // handle offloading put as well. If serverclose not offloaded, 746 // we need to handle offloading put here. 747 if (!serverclose_offloaded) { 748 if (offload) 749 queue_work(fileinfo_put_wq, &cifs_file->put); 750 else 751 cifsFileInfo_put_final(cifs_file); 752 } |
702} 703 704int cifs_open(struct inode *inode, struct file *file) 705 706{ 707 int rc = -EACCES; 708 unsigned int xid; 709 __u32 oplock; --- 4448 unchanged lines hidden --- | 753} 754 755int cifs_open(struct inode *inode, struct file *file) 756 757{ 758 int rc = -EACCES; 759 unsigned int xid; 760 __u32 oplock; --- 4448 unchanged lines hidden --- |