aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.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 18:56:55 -0500
commit14fbf50d695207754daeb96270b3027a3821121f (patch)
tree05e80aa7e5e6a6bc07a9354f744ba9c599699569 /fs/cifs/misc.c
parente7ddee9037e7dd43de1ad08b51727e552aedd836 (diff)
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/misc.c')
-rw-r--r--fs/cifs/misc.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 88786ba02d27..46c8c7baccba 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -75,12 +75,11 @@ sesInfoAlloc(void)
75 75
76 ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL); 76 ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
77 if (ret_buf) { 77 if (ret_buf) {
78 write_lock(&GlobalSMBSeslock);
79 atomic_inc(&sesInfoAllocCount); 78 atomic_inc(&sesInfoAllocCount);
80 ret_buf->status = CifsNew; 79 ret_buf->status = CifsNew;
81 list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList); 80 ++ret_buf->ses_count;
81 INIT_LIST_HEAD(&ret_buf->smb_ses_list);
82 init_MUTEX(&ret_buf->sesSem); 82 init_MUTEX(&ret_buf->sesSem);
83 write_unlock(&GlobalSMBSeslock);
84 } 83 }
85 return ret_buf; 84 return ret_buf;
86} 85}
@@ -93,10 +92,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
93 return; 92 return;
94 } 93 }
95 94
96 write_lock(&GlobalSMBSeslock);
97 atomic_dec(&sesInfoAllocCount); 95 atomic_dec(&sesInfoAllocCount);
98 list_del(&buf_to_free->cifsSessionList);
99 write_unlock(&GlobalSMBSeslock);
100 kfree(buf_to_free->serverOS); 96 kfree(buf_to_free->serverOS);
101 kfree(buf_to_free->serverDomain); 97 kfree(buf_to_free->serverDomain);
102 kfree(buf_to_free->serverNOS); 98 kfree(buf_to_free->serverNOS);
@@ -350,9 +346,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
350 if (current->fsuid != treeCon->ses->linux_uid) { 346 if (current->fsuid != treeCon->ses->linux_uid) {
351 cFYI(1, ("Multiuser mode and UID " 347 cFYI(1, ("Multiuser mode and UID "
352 "did not match tcon uid")); 348 "did not match tcon uid"));
353 read_lock(&GlobalSMBSeslock); 349 read_lock(&cifs_tcp_ses_lock);
354 list_for_each(temp_item, &GlobalSMBSessionList) { 350 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
355 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); 351 ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
356 if (ses->linux_uid == current->fsuid) { 352 if (ses->linux_uid == current->fsuid) {
357 if (ses->server == treeCon->ses->server) { 353 if (ses->server == treeCon->ses->server) {
358 cFYI(1, ("found matching uid substitute right smb_uid")); 354 cFYI(1, ("found matching uid substitute right smb_uid"));
@@ -364,7 +360,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
364 } 360 }
365 } 361 }
366 } 362 }
367 read_unlock(&GlobalSMBSeslock); 363 read_unlock(&cifs_tcp_ses_lock);
368 } 364 }
369 } 365 }
370 } 366 }