summaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-11-14 13:53:46 -0500
committerSteve French <sfrench@us.ibm.com>2008-11-14 23:56:55 +0000
commit14fbf50d695207754daeb96270b3027a3821121f (patch)
tree05e80aa7e5e6a6bc07a9354f744ba9c599699569 /fs/cifs/cifssmb.c
parente7ddee9037e7dd43de1ad08b51727e552aedd836 (diff)
downloadlinux-14fbf50d695207754daeb96270b3027a3821121f.tar.gz
linux-14fbf50d695207754daeb96270b3027a3821121f.tar.bz2
linux-14fbf50d695207754daeb96270b3027a3821121f.zip
cifs: reinstate sharing of SMB sessions sans races
We do this by abandoning the global list of SMB sessions and instead moving to a per-server list. This entails adding a new list head to the TCP_Server_Info struct. The refcounting for the cifsSesInfo is moved to a non-atomic variable. We have to protect it by a lock anyway, so there's no benefit to making it an atomic. The list and refcount are protected by the global cifs_tcp_ses_lock. The patch also adds a new routines to find and put SMB sessions and that properly take and put references under the lock. 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.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index cd9e9a145e4d..9c95617baa4d 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -799,20 +799,16 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
int rc = 0;
cFYI(1, ("In SMBLogoff for session disconnect"));
- if (ses)
- down(&ses->sesSem);
- else
- return -EIO;
-
- atomic_dec(&ses->inUse);
- if (atomic_read(&ses->inUse) > 0) {
- up(&ses->sesSem);
- return -EBUSY;
- }
- if (ses->server == NULL)
+ /*
+ * BB: do we need to check validity of ses and server? They should
+ * always be valid since we have an active reference. If not, that
+ * should probably be a BUG()
+ */
+ if (!ses || !ses->server)
return -EIO;
+ down(&ses->sesSem);
if (ses->need_reconnect)
goto session_already_dead; /* no need to send SMBlogoff if uid
already closed due to reconnect */
@@ -833,10 +829,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
pSMB->AndXCommand = 0xFF;
rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
session_already_dead:
- if (ses->server) {
- cifs_put_tcp_session(ses->server);
- rc = 0;
- }
up(&ses->sesSem);
/* if session dead then we do not need to do ulogoff,