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/cifs_debug.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/cifs_debug.c')
-rw-r--r-- | fs/cifs/cifs_debug.c | 53 |
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 |
108 | static int cifs_debug_data_proc_show(struct seq_file *m, void *v) | 108 | static 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:"); |