diff options
author | Jeff Layton <jlayton@redhat.com> | 2008-11-15 11:12:47 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-11-16 22:14:12 -0500 |
commit | f1987b44f642e96176adc88b7ce23a1d74806f89 (patch) | |
tree | fceaebf6b6d7eb1d1150120c44a842cbce8347f6 /fs/cifs/cifssmb.c | |
parent | d82c2df54e2f7e447476350848d8eccc8d2fe46a (diff) |
cifs: reinstate sharing of tree connections
Use a similar approach to the SMB session sharing. Add a list of tcons
attached to each SMB session. Move the refcount to non-atomic. Protect
all of the above with the cifs_tcp_ses_lock. Add functions to
properly find and put references to the tcons.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 43 |
1 files changed, 12 insertions, 31 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9c95617baa4d..e6bb2d9d5b09 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -742,50 +742,31 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) | |||
742 | int rc = 0; | 742 | int rc = 0; |
743 | 743 | ||
744 | cFYI(1, ("In tree disconnect")); | 744 | cFYI(1, ("In tree disconnect")); |
745 | /* | ||
746 | * If last user of the connection and | ||
747 | * connection alive - disconnect it | ||
748 | * If this is the last connection on the server session disconnect it | ||
749 | * (and inside session disconnect we should check if tcp socket needs | ||
750 | * to be freed and kernel thread woken up). | ||
751 | */ | ||
752 | if (tcon) | ||
753 | down(&tcon->tconSem); | ||
754 | else | ||
755 | return -EIO; | ||
756 | 745 | ||
757 | atomic_dec(&tcon->useCount); | 746 | /* BB: do we need to check this? These should never be NULL. */ |
758 | if (atomic_read(&tcon->useCount) > 0) { | 747 | if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) |
759 | up(&tcon->tconSem); | 748 | return -EIO; |
760 | return -EBUSY; | ||
761 | } | ||
762 | 749 | ||
763 | /* No need to return error on this operation if tid invalidated and | 750 | /* |
764 | closed on server already e.g. due to tcp session crashing */ | 751 | * No need to return error on this operation if tid invalidated and |
765 | if (tcon->need_reconnect) { | 752 | * closed on server already e.g. due to tcp session crashing. Also, |
766 | up(&tcon->tconSem); | 753 | * the tcon is no longer on the list, so no need to take lock before |
754 | * checking this. | ||
755 | */ | ||
756 | if (tcon->need_reconnect) | ||
767 | return 0; | 757 | return 0; |
768 | } | ||
769 | 758 | ||
770 | if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) { | ||
771 | up(&tcon->tconSem); | ||
772 | return -EIO; | ||
773 | } | ||
774 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, | 759 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, |
775 | (void **)&smb_buffer); | 760 | (void **)&smb_buffer); |
776 | if (rc) { | 761 | if (rc) |
777 | up(&tcon->tconSem); | ||
778 | return rc; | 762 | return rc; |
779 | } | ||
780 | 763 | ||
781 | rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0); | 764 | rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0); |
782 | if (rc) | 765 | if (rc) |
783 | cFYI(1, ("Tree disconnect failed %d", rc)); | 766 | cFYI(1, ("Tree disconnect failed %d", rc)); |
784 | 767 | ||
785 | up(&tcon->tconSem); | ||
786 | |||
787 | /* No need to return error on this operation if tid invalidated and | 768 | /* No need to return error on this operation if tid invalidated and |
788 | closed on server already e.g. due to tcp session crashing */ | 769 | closed on server already e.g. due to tcp session crashing */ |
789 | if (rc == -EAGAIN) | 770 | if (rc == -EAGAIN) |
790 | rc = 0; | 771 | rc = 0; |
791 | 772 | ||