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 ---