aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifs_debug.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/cifs_debug.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/cifs_debug.c')
-rw-r--r--fs/cifs/cifs_debug.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 40b5108fb4f9..59841a68b0b6 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -107,9 +107,9 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
107#ifdef CONFIG_PROC_FS 107#ifdef CONFIG_PROC_FS
108static int cifs_debug_data_proc_show(struct seq_file *m, void *v) 108static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
109{ 109{
110 struct list_head *tmp; 110 struct list_head *tmp, *tmp2, *tmp3;
111 struct list_head *tmp1;
112 struct mid_q_entry *mid_entry; 111 struct mid_q_entry *mid_entry;
112 struct TCP_Server_Info *server;
113 struct cifsSesInfo *ses; 113 struct cifsSesInfo *ses;
114 struct cifsTconInfo *tcon; 114 struct cifsTconInfo *tcon;
115 int i; 115 int i;
@@ -122,43 +122,45 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
122 seq_printf(m, "Servers:"); 122 seq_printf(m, "Servers:");
123 123
124 i = 0; 124 i = 0;
125 read_lock(&GlobalSMBSeslock); 125 read_lock(&cifs_tcp_ses_lock);
126 list_for_each(tmp, &GlobalSMBSessionList) { 126 list_for_each(tmp, &cifs_tcp_ses_list) {
127 server = list_entry(tmp, struct TCP_Server_Info,
128 tcp_ses_list);
127 i++; 129 i++;
128 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); 130 list_for_each(tmp2, &server->smb_ses_list) {
129 if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) || 131 ses = list_entry(tmp2, struct cifsSesInfo,
130 (ses->serverNOS == NULL)) { 132 smb_ses_list);
131 seq_printf(m, "\nentry for %s not fully " 133 if ((ses->serverDomain == NULL) ||
132 "displayed\n\t", ses->serverName); 134 (ses->serverOS == NULL) ||
133 } else { 135 (ses->serverNOS == NULL)) {
134 seq_printf(m, 136 seq_printf(m, "\nentry for %s not fully "
137 "displayed\n\t", ses->serverName);
138 } else {
139 seq_printf(m,
135 "\n%d) Name: %s Domain: %s Mounts: %d OS:" 140 "\n%d) Name: %s Domain: %s Mounts: %d OS:"
136 " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB" 141 " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB"
137 " session status: %d\t", 142 " session status: %d\t",
138 i, ses->serverName, ses->serverDomain, 143 i, ses->serverName, ses->serverDomain,
139 atomic_read(&ses->inUse), 144 ses->ses_count, ses->serverOS, ses->serverNOS,
140 ses->serverOS, ses->serverNOS,
141 ses->capabilities, ses->status); 145 ses->capabilities, ses->status);
142 } 146 }
143 if (ses->server) {
144 seq_printf(m, "TCP status: %d\n\tLocal Users To " 147 seq_printf(m, "TCP status: %d\n\tLocal Users To "
145 "Server: %d SecMode: 0x%x Req On Wire: %d", 148 "Server: %d SecMode: 0x%x Req On Wire: %d",
146 ses->server->tcpStatus, 149 server->tcpStatus, server->srv_count,
147 ses->server->srv_count, 150 server->secMode,
148 ses->server->secMode, 151 atomic_read(&server->inFlight));
149 atomic_read(&ses->server->inFlight));
150 152
151#ifdef CONFIG_CIFS_STATS2 153#ifdef CONFIG_CIFS_STATS2
152 seq_printf(m, " In Send: %d In MaxReq Wait: %d", 154 seq_printf(m, " In Send: %d In MaxReq Wait: %d",
153 atomic_read(&ses->server->inSend), 155 atomic_read(&server->inSend),
154 atomic_read(&ses->server->num_waiters)); 156 atomic_read(&server->num_waiters));
155#endif 157#endif
156 158
157 seq_puts(m, "\nMIDs:\n"); 159 seq_puts(m, "\nMIDs:\n");
158 160
159 spin_lock(&GlobalMid_Lock); 161 spin_lock(&GlobalMid_Lock);
160 list_for_each(tmp1, &ses->server->pending_mid_q) { 162 list_for_each(tmp3, &server->pending_mid_q) {
161 mid_entry = list_entry(tmp1, struct 163 mid_entry = list_entry(tmp3, struct
162 mid_q_entry, 164 mid_q_entry,
163 qhead); 165 qhead);
164 seq_printf(m, "State: %d com: %d pid:" 166 seq_printf(m, "State: %d com: %d pid:"
@@ -171,9 +173,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
171 } 173 }
172 spin_unlock(&GlobalMid_Lock); 174 spin_unlock(&GlobalMid_Lock);
173 } 175 }
174
175 } 176 }
176 read_unlock(&GlobalSMBSeslock); 177 read_unlock(&cifs_tcp_ses_lock);
177 seq_putc(m, '\n'); 178 seq_putc(m, '\n');
178 179
179 seq_puts(m, "Shares:"); 180 seq_puts(m, "Shares:");