diff options
author | Jeff Layton <jlayton@redhat.com> | 2008-11-14 13:53:46 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-11-14 18:56:55 -0500 |
commit | 14fbf50d695207754daeb96270b3027a3821121f (patch) | |
tree | 05e80aa7e5e6a6bc07a9354f744ba9c599699569 /fs/cifs/cifsfs.c | |
parent | e7ddee9037e7dd43de1ad08b51727e552aedd836 (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/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 2946dab0718f..a1e96620b097 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -1031,24 +1031,24 @@ static int cifs_oplock_thread(void *dummyarg) | |||
1031 | static int cifs_dnotify_thread(void *dummyarg) | 1031 | static int cifs_dnotify_thread(void *dummyarg) |
1032 | { | 1032 | { |
1033 | struct list_head *tmp; | 1033 | struct list_head *tmp; |
1034 | struct cifsSesInfo *ses; | 1034 | struct TCP_Server_Info *server; |
1035 | 1035 | ||
1036 | do { | 1036 | do { |
1037 | if (try_to_freeze()) | 1037 | if (try_to_freeze()) |
1038 | continue; | 1038 | continue; |
1039 | set_current_state(TASK_INTERRUPTIBLE); | 1039 | set_current_state(TASK_INTERRUPTIBLE); |
1040 | schedule_timeout(15*HZ); | 1040 | schedule_timeout(15*HZ); |
1041 | read_lock(&GlobalSMBSeslock); | ||
1042 | /* check if any stuck requests that need | 1041 | /* check if any stuck requests that need |
1043 | to be woken up and wakeq so the | 1042 | to be woken up and wakeq so the |
1044 | thread can wake up and error out */ | 1043 | thread can wake up and error out */ |
1045 | list_for_each(tmp, &GlobalSMBSessionList) { | 1044 | read_lock(&cifs_tcp_ses_lock); |
1046 | ses = list_entry(tmp, struct cifsSesInfo, | 1045 | list_for_each(tmp, &cifs_tcp_ses_list) { |
1047 | cifsSessionList); | 1046 | server = list_entry(tmp, struct TCP_Server_Info, |
1048 | if (ses->server && atomic_read(&ses->server->inFlight)) | 1047 | tcp_ses_list); |
1049 | wake_up_all(&ses->server->response_q); | 1048 | if (atomic_read(&server->inFlight)) |
1049 | wake_up_all(&server->response_q); | ||
1050 | } | 1050 | } |
1051 | read_unlock(&GlobalSMBSeslock); | 1051 | read_unlock(&cifs_tcp_ses_lock); |
1052 | } while (!kthread_should_stop()); | 1052 | } while (!kthread_should_stop()); |
1053 | 1053 | ||
1054 | return 0; | 1054 | return 0; |
@@ -1060,7 +1060,6 @@ init_cifs(void) | |||
1060 | int rc = 0; | 1060 | int rc = 0; |
1061 | cifs_proc_init(); | 1061 | cifs_proc_init(); |
1062 | INIT_LIST_HEAD(&cifs_tcp_ses_list); | 1062 | INIT_LIST_HEAD(&cifs_tcp_ses_list); |
1063 | INIT_LIST_HEAD(&GlobalSMBSessionList); /* BB to be removed by jl */ | ||
1064 | INIT_LIST_HEAD(&GlobalTreeConnectionList); /* BB to be removed by jl */ | 1063 | INIT_LIST_HEAD(&GlobalTreeConnectionList); /* BB to be removed by jl */ |
1065 | INIT_LIST_HEAD(&GlobalOplock_Q); | 1064 | INIT_LIST_HEAD(&GlobalOplock_Q); |
1066 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 1065 | #ifdef CONFIG_CIFS_EXPERIMENTAL |