smb3: display security information in /proc/fs/cifs/DebugData more accurately
[sfrench/cifs-2.6.git] / fs / cifs / cifs_debug.c
1 /*
2  *   fs/cifs_debug.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2000,2005
5  *
6  *   Modified by Steve French (sfrench@us.ibm.com)
7  *
8  *   This program is free software;  you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16  *   the GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program;  if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 #include <linux/fs.h>
23 #include <linux/string.h>
24 #include <linux/ctype.h>
25 #include <linux/module.h>
26 #include <linux/proc_fs.h>
27 #include <linux/uaccess.h>
28 #include "cifspdu.h"
29 #include "cifsglob.h"
30 #include "cifsproto.h"
31 #include "cifs_debug.h"
32 #include "cifsfs.h"
33 #ifdef CONFIG_CIFS_DFS_UPCALL
34 #include "dfs_cache.h"
35 #endif
36 #ifdef CONFIG_CIFS_SMB_DIRECT
37 #include "smbdirect.h"
38 #endif
39
40 void
41 cifs_dump_mem(char *label, void *data, int length)
42 {
43         pr_debug("%s: dump of %d bytes of data at 0x%p\n", label, length, data);
44         print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
45                        data, length, true);
46 }
47
48 void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
49 {
50 #ifdef CONFIG_CIFS_DEBUG2
51         struct smb_hdr *smb = (struct smb_hdr *)buf;
52
53         cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n",
54                  smb->Command, smb->Status.CifsError,
55                  smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
56         cifs_dbg(VFS, "smb buf %p len %u\n", smb,
57                  server->ops->calc_smb_size(smb, server));
58 #endif /* CONFIG_CIFS_DEBUG2 */
59 }
60
61 void cifs_dump_mids(struct TCP_Server_Info *server)
62 {
63 #ifdef CONFIG_CIFS_DEBUG2
64         struct list_head *tmp;
65         struct mid_q_entry *mid_entry;
66
67         if (server == NULL)
68                 return;
69
70         cifs_dbg(VFS, "Dump pending requests:\n");
71         spin_lock(&GlobalMid_Lock);
72         list_for_each(tmp, &server->pending_mid_q) {
73                 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
74                 cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
75                          mid_entry->mid_state,
76                          le16_to_cpu(mid_entry->command),
77                          mid_entry->pid,
78                          mid_entry->callback_data,
79                          mid_entry->mid);
80 #ifdef CONFIG_CIFS_STATS2
81                 cifs_dbg(VFS, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n",
82                          mid_entry->large_buf,
83                          mid_entry->resp_buf,
84                          mid_entry->when_received,
85                          jiffies);
86 #endif /* STATS2 */
87                 cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n",
88                          mid_entry->multiRsp, mid_entry->multiEnd);
89                 if (mid_entry->resp_buf) {
90                         cifs_dump_detail(mid_entry->resp_buf, server);
91                         cifs_dump_mem("existing buf: ",
92                                 mid_entry->resp_buf, 62);
93                 }
94         }
95         spin_unlock(&GlobalMid_Lock);
96 #endif /* CONFIG_CIFS_DEBUG2 */
97 }
98
99 #ifdef CONFIG_PROC_FS
100 static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
101 {
102         __u32 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
103
104         seq_printf(m, "%s Mounts: %d ", tcon->treeName, tcon->tc_count);
105         if (tcon->nativeFileSystem)
106                 seq_printf(m, "Type: %s ", tcon->nativeFileSystem);
107         seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d",
108                    le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
109                    le32_to_cpu(tcon->fsAttrInfo.Attributes),
110                    le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
111                    tcon->tidStatus);
112         if (dev_type == FILE_DEVICE_DISK)
113                 seq_puts(m, " type: DISK ");
114         else if (dev_type == FILE_DEVICE_CD_ROM)
115                 seq_puts(m, " type: CDROM ");
116         else
117                 seq_printf(m, " type: %d ", dev_type);
118         if ((tcon->seal) ||
119             (tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
120             (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
121                 seq_printf(m, " Encrypted");
122         if (tcon->nocase)
123                 seq_printf(m, " nocase");
124         if (tcon->unix_ext)
125                 seq_printf(m, " POSIX Extensions");
126         if (tcon->ses->server->ops->dump_share_caps)
127                 tcon->ses->server->ops->dump_share_caps(m, tcon);
128
129         if (tcon->need_reconnect)
130                 seq_puts(m, "\tDISCONNECTED ");
131         seq_putc(m, '\n');
132 }
133
134 static void
135 cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface)
136 {
137         struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
138         struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
139
140         seq_printf(m, "\tSpeed: %zu bps\n", iface->speed);
141         seq_puts(m, "\t\tCapabilities: ");
142         if (iface->rdma_capable)
143                 seq_puts(m, "rdma ");
144         if (iface->rss_capable)
145                 seq_puts(m, "rss ");
146         seq_putc(m, '\n');
147         if (iface->sockaddr.ss_family == AF_INET)
148                 seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr);
149         else if (iface->sockaddr.ss_family == AF_INET6)
150                 seq_printf(m, "\t\tIPv6: %pI6\n", &ipv6->sin6_addr);
151 }
152
153 static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
154 {
155         struct list_head *stmp, *tmp, *tmp1, *tmp2;
156         struct TCP_Server_Info *server;
157         struct cifs_ses *ses;
158         struct cifs_tcon *tcon;
159         struct cifsFileInfo *cfile;
160
161         seq_puts(m, "# Version:1\n");
162         seq_puts(m, "# Format:\n");
163         seq_puts(m, "# <tree id> <persistent fid> <flags> <count> <pid> <uid>");
164 #ifdef CONFIG_CIFS_DEBUG2
165         seq_printf(m, " <filename> <mid>\n");
166 #else
167         seq_printf(m, " <filename>\n");
168 #endif /* CIFS_DEBUG2 */
169         spin_lock(&cifs_tcp_ses_lock);
170         list_for_each(stmp, &cifs_tcp_ses_list) {
171                 server = list_entry(stmp, struct TCP_Server_Info,
172                                     tcp_ses_list);
173                 list_for_each(tmp, &server->smb_ses_list) {
174                         ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
175                         list_for_each(tmp1, &ses->tcon_list) {
176                                 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
177                                 spin_lock(&tcon->open_file_lock);
178                                 list_for_each(tmp2, &tcon->openFileList) {
179                                         cfile = list_entry(tmp2, struct cifsFileInfo,
180                                                      tlist);
181                                         seq_printf(m,
182                                                 "0x%x 0x%llx 0x%x %d %d %d %s",
183                                                 tcon->tid,
184                                                 cfile->fid.persistent_fid,
185                                                 cfile->f_flags,
186                                                 cfile->count,
187                                                 cfile->pid,
188                                                 from_kuid(&init_user_ns, cfile->uid),
189                                                 cfile->dentry->d_name.name);
190 #ifdef CONFIG_CIFS_DEBUG2
191                                         seq_printf(m, " 0x%llx\n", cfile->fid.mid);
192 #else
193                                         seq_printf(m, "\n");
194 #endif /* CIFS_DEBUG2 */
195                                 }
196                                 spin_unlock(&tcon->open_file_lock);
197                         }
198                 }
199         }
200         spin_unlock(&cifs_tcp_ses_lock);
201         seq_putc(m, '\n');
202         return 0;
203 }
204
205 static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
206 {
207         struct list_head *tmp1, *tmp2, *tmp3;
208         struct mid_q_entry *mid_entry;
209         struct TCP_Server_Info *server;
210         struct cifs_ses *ses;
211         struct cifs_tcon *tcon;
212         int i, j;
213
214         seq_puts(m,
215                     "Display Internal CIFS Data Structures for Debugging\n"
216                     "---------------------------------------------------\n");
217         seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
218         seq_printf(m, "Features:");
219 #ifdef CONFIG_CIFS_DFS_UPCALL
220         seq_printf(m, " DFS");
221 #endif
222 #ifdef CONFIG_CIFS_FSCACHE
223         seq_printf(m, ",FSCACHE");
224 #endif
225 #ifdef CONFIG_CIFS_SMB_DIRECT
226         seq_printf(m, ",SMB_DIRECT");
227 #endif
228 #ifdef CONFIG_CIFS_STATS2
229         seq_printf(m, ",STATS2");
230 #else
231         seq_printf(m, ",STATS");
232 #endif
233 #ifdef CONFIG_CIFS_DEBUG2
234         seq_printf(m, ",DEBUG2");
235 #elif defined(CONFIG_CIFS_DEBUG)
236         seq_printf(m, ",DEBUG");
237 #endif
238 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
239         seq_printf(m, ",ALLOW_INSECURE_LEGACY");
240 #endif
241 #ifdef CONFIG_CIFS_WEAK_PW_HASH
242         seq_printf(m, ",WEAK_PW_HASH");
243 #endif
244 #ifdef CONFIG_CIFS_POSIX
245         seq_printf(m, ",CIFS_POSIX");
246 #endif
247 #ifdef CONFIG_CIFS_UPCALL
248         seq_printf(m, ",UPCALL(SPNEGO)");
249 #endif
250 #ifdef CONFIG_CIFS_XATTR
251         seq_printf(m, ",XATTR");
252 #endif
253 #ifdef CONFIG_CIFS_ACL
254         seq_printf(m, ",ACL");
255 #endif
256         seq_putc(m, '\n');
257         seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize);
258         seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
259         seq_printf(m, "Servers:");
260
261         i = 0;
262         spin_lock(&cifs_tcp_ses_lock);
263         list_for_each(tmp1, &cifs_tcp_ses_list) {
264                 server = list_entry(tmp1, struct TCP_Server_Info,
265                                     tcp_ses_list);
266
267 #ifdef CONFIG_CIFS_SMB_DIRECT
268                 if (!server->rdma)
269                         goto skip_rdma;
270
271                 seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
272                         "transport status: %x",
273                         server->smbd_conn->protocol,
274                         server->smbd_conn->transport_status);
275                 seq_printf(m, "\nConn receive_credit_max: %x "
276                         "send_credit_target: %x max_send_size: %x",
277                         server->smbd_conn->receive_credit_max,
278                         server->smbd_conn->send_credit_target,
279                         server->smbd_conn->max_send_size);
280                 seq_printf(m, "\nConn max_fragmented_recv_size: %x "
281                         "max_fragmented_send_size: %x max_receive_size:%x",
282                         server->smbd_conn->max_fragmented_recv_size,
283                         server->smbd_conn->max_fragmented_send_size,
284                         server->smbd_conn->max_receive_size);
285                 seq_printf(m, "\nConn keep_alive_interval: %x "
286                         "max_readwrite_size: %x rdma_readwrite_threshold: %x",
287                         server->smbd_conn->keep_alive_interval,
288                         server->smbd_conn->max_readwrite_size,
289                         server->smbd_conn->rdma_readwrite_threshold);
290                 seq_printf(m, "\nDebug count_get_receive_buffer: %x "
291                         "count_put_receive_buffer: %x count_send_empty: %x",
292                         server->smbd_conn->count_get_receive_buffer,
293                         server->smbd_conn->count_put_receive_buffer,
294                         server->smbd_conn->count_send_empty);
295                 seq_printf(m, "\nRead Queue count_reassembly_queue: %x "
296                         "count_enqueue_reassembly_queue: %x "
297                         "count_dequeue_reassembly_queue: %x "
298                         "fragment_reassembly_remaining: %x "
299                         "reassembly_data_length: %x "
300                         "reassembly_queue_length: %x",
301                         server->smbd_conn->count_reassembly_queue,
302                         server->smbd_conn->count_enqueue_reassembly_queue,
303                         server->smbd_conn->count_dequeue_reassembly_queue,
304                         server->smbd_conn->fragment_reassembly_remaining,
305                         server->smbd_conn->reassembly_data_length,
306                         server->smbd_conn->reassembly_queue_length);
307                 seq_printf(m, "\nCurrent Credits send_credits: %x "
308                         "receive_credits: %x receive_credit_target: %x",
309                         atomic_read(&server->smbd_conn->send_credits),
310                         atomic_read(&server->smbd_conn->receive_credits),
311                         server->smbd_conn->receive_credit_target);
312                 seq_printf(m, "\nPending send_pending: %x send_payload_pending:"
313                         " %x smbd_send_pending: %x smbd_recv_pending: %x",
314                         atomic_read(&server->smbd_conn->send_pending),
315                         atomic_read(&server->smbd_conn->send_payload_pending),
316                         server->smbd_conn->smbd_send_pending,
317                         server->smbd_conn->smbd_recv_pending);
318                 seq_printf(m, "\nReceive buffers count_receive_queue: %x "
319                         "count_empty_packet_queue: %x",
320                         server->smbd_conn->count_receive_queue,
321                         server->smbd_conn->count_empty_packet_queue);
322                 seq_printf(m, "\nMR responder_resources: %x "
323                         "max_frmr_depth: %x mr_type: %x",
324                         server->smbd_conn->responder_resources,
325                         server->smbd_conn->max_frmr_depth,
326                         server->smbd_conn->mr_type);
327                 seq_printf(m, "\nMR mr_ready_count: %x mr_used_count: %x",
328                         atomic_read(&server->smbd_conn->mr_ready_count),
329                         atomic_read(&server->smbd_conn->mr_used_count));
330 skip_rdma:
331 #endif
332                 seq_printf(m, "\nNumber of credits: %d Dialect 0x%x",
333                         server->credits,  server->dialect);
334                 if (server->sign)
335                         seq_printf(m, " signed");
336                 if (server->posix_ext_supported)
337                         seq_printf(m, " posix");
338
339                 i++;
340                 list_for_each(tmp2, &server->smb_ses_list) {
341                         ses = list_entry(tmp2, struct cifs_ses,
342                                          smb_ses_list);
343                         if ((ses->serverDomain == NULL) ||
344                                 (ses->serverOS == NULL) ||
345                                 (ses->serverNOS == NULL)) {
346                                 seq_printf(m, "\n%d) Name: %s Uses: %d Capability: 0x%x\tSession Status: %d ",
347                                         i, ses->serverName, ses->ses_count,
348                                         ses->capabilities, ses->status);
349                                 if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
350                                         seq_printf(m, "Guest\t");
351                                 else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
352                                         seq_printf(m, "Anonymous\t");
353                         } else {
354                                 seq_printf(m,
355                                     "\n%d) Name: %s  Domain: %s Uses: %d OS:"
356                                     " %s\n\tNOS: %s\tCapability: 0x%x\n\tSMB"
357                                     " session status: %d ",
358                                 i, ses->serverName, ses->serverDomain,
359                                 ses->ses_count, ses->serverOS, ses->serverNOS,
360                                 ses->capabilities, ses->status);
361                         }
362                         if (server->rdma)
363                                 seq_printf(m, "RDMA\n\t");
364                         seq_printf(m, "TCP status: %d Instance: %d\n\tLocal Users To "
365                                    "Server: %d SecMode: 0x%x Req On Wire: %d",
366                                    server->tcpStatus,
367                                    server->reconnect_instance,
368                                    server->srv_count,
369                                    server->sec_mode, in_flight(server));
370
371 #ifdef CONFIG_CIFS_STATS2
372                         seq_printf(m, " In Send: %d In MaxReq Wait: %d",
373                                 atomic_read(&server->in_send),
374                                 atomic_read(&server->num_waiters));
375 #endif
376                         if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
377                                 seq_puts(m, " encrypted");
378                         if (ses->sign)
379                                 seq_puts(m, " signed");
380
381                         seq_puts(m, "\n\tShares:");
382                         j = 0;
383
384                         seq_printf(m, "\n\t%d) IPC: ", j);
385                         if (ses->tcon_ipc)
386                                 cifs_debug_tcon(m, ses->tcon_ipc);
387                         else
388                                 seq_puts(m, "none\n");
389
390                         list_for_each(tmp3, &ses->tcon_list) {
391                                 tcon = list_entry(tmp3, struct cifs_tcon,
392                                                   tcon_list);
393                                 ++j;
394                                 seq_printf(m, "\n\t%d) ", j);
395                                 cifs_debug_tcon(m, tcon);
396                         }
397
398                         seq_puts(m, "\n\tMIDs:\n");
399
400                         spin_lock(&GlobalMid_Lock);
401                         list_for_each(tmp3, &server->pending_mid_q) {
402                                 mid_entry = list_entry(tmp3, struct mid_q_entry,
403                                         qhead);
404                                 seq_printf(m, "\tState: %d com: %d pid:"
405                                               " %d cbdata: %p mid %llu\n",
406                                               mid_entry->mid_state,
407                                               le16_to_cpu(mid_entry->command),
408                                               mid_entry->pid,
409                                               mid_entry->callback_data,
410                                               mid_entry->mid);
411                         }
412                         spin_unlock(&GlobalMid_Lock);
413
414                         spin_lock(&ses->iface_lock);
415                         if (ses->iface_count)
416                                 seq_printf(m, "\n\tServer interfaces: %zu\n",
417                                            ses->iface_count);
418                         for (j = 0; j < ses->iface_count; j++) {
419                                 seq_printf(m, "\t%d)", j);
420                                 cifs_dump_iface(m, &ses->iface_list[j]);
421                         }
422                         spin_unlock(&ses->iface_lock);
423                 }
424         }
425         spin_unlock(&cifs_tcp_ses_lock);
426         seq_putc(m, '\n');
427
428         /* BB add code to dump additional info such as TCP session info now */
429         return 0;
430 }
431
432 static ssize_t cifs_stats_proc_write(struct file *file,
433                 const char __user *buffer, size_t count, loff_t *ppos)
434 {
435         bool bv;
436         int rc;
437         struct list_head *tmp1, *tmp2, *tmp3;
438         struct TCP_Server_Info *server;
439         struct cifs_ses *ses;
440         struct cifs_tcon *tcon;
441
442         rc = kstrtobool_from_user(buffer, count, &bv);
443         if (rc == 0) {
444 #ifdef CONFIG_CIFS_STATS2
445                 int i;
446
447                 atomic_set(&totBufAllocCount, 0);
448                 atomic_set(&totSmBufAllocCount, 0);
449 #endif /* CONFIG_CIFS_STATS2 */
450                 atomic_set(&tcpSesReconnectCount, 0);
451                 atomic_set(&tconInfoReconnectCount, 0);
452
453                 spin_lock(&GlobalMid_Lock);
454                 GlobalMaxActiveXid = 0;
455                 GlobalCurrentXid = 0;
456                 spin_unlock(&GlobalMid_Lock);
457                 spin_lock(&cifs_tcp_ses_lock);
458                 list_for_each(tmp1, &cifs_tcp_ses_list) {
459                         server = list_entry(tmp1, struct TCP_Server_Info,
460                                             tcp_ses_list);
461 #ifdef CONFIG_CIFS_STATS2
462                         for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++)
463                                 atomic_set(&server->smb2slowcmd[i], 0);
464 #endif /* CONFIG_CIFS_STATS2 */
465                         list_for_each(tmp2, &server->smb_ses_list) {
466                                 ses = list_entry(tmp2, struct cifs_ses,
467                                                  smb_ses_list);
468                                 list_for_each(tmp3, &ses->tcon_list) {
469                                         tcon = list_entry(tmp3,
470                                                           struct cifs_tcon,
471                                                           tcon_list);
472                                         atomic_set(&tcon->num_smbs_sent, 0);
473                                         spin_lock(&tcon->stat_lock);
474                                         tcon->bytes_read = 0;
475                                         tcon->bytes_written = 0;
476                                         spin_unlock(&tcon->stat_lock);
477                                         if (server->ops->clear_stats)
478                                                 server->ops->clear_stats(tcon);
479                                 }
480                         }
481                 }
482                 spin_unlock(&cifs_tcp_ses_lock);
483         } else {
484                 return rc;
485         }
486
487         return count;
488 }
489
490 static int cifs_stats_proc_show(struct seq_file *m, void *v)
491 {
492         int i;
493 #ifdef CONFIG_CIFS_STATS2
494         int j;
495 #endif /* STATS2 */
496         struct list_head *tmp1, *tmp2, *tmp3;
497         struct TCP_Server_Info *server;
498         struct cifs_ses *ses;
499         struct cifs_tcon *tcon;
500
501         seq_printf(m, "Resources in use\nCIFS Session: %d\n",
502                         sesInfoAllocCount.counter);
503         seq_printf(m, "Share (unique mount targets): %d\n",
504                         tconInfoAllocCount.counter);
505         seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",
506                         bufAllocCount.counter,
507                         cifs_min_rcv + tcpSesAllocCount.counter);
508         seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
509                         smBufAllocCount.counter, cifs_min_small);
510 #ifdef CONFIG_CIFS_STATS2
511         seq_printf(m, "Total Large %d Small %d Allocations\n",
512                                 atomic_read(&totBufAllocCount),
513                                 atomic_read(&totSmBufAllocCount));
514 #endif /* CONFIG_CIFS_STATS2 */
515
516         seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&midCount));
517         seq_printf(m,
518                 "\n%d session %d share reconnects\n",
519                 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
520
521         seq_printf(m,
522                 "Total vfs operations: %d maximum at one time: %d\n",
523                 GlobalCurrentXid, GlobalMaxActiveXid);
524
525         i = 0;
526         spin_lock(&cifs_tcp_ses_lock);
527         list_for_each(tmp1, &cifs_tcp_ses_list) {
528                 server = list_entry(tmp1, struct TCP_Server_Info,
529                                     tcp_ses_list);
530 #ifdef CONFIG_CIFS_STATS2
531                 for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
532                         if (atomic_read(&server->smb2slowcmd[j]))
533                                 seq_printf(m, "%d slow responses from %s for command %d\n",
534                                         atomic_read(&server->smb2slowcmd[j]),
535                                         server->hostname, j);
536 #endif /* STATS2 */
537                 list_for_each(tmp2, &server->smb_ses_list) {
538                         ses = list_entry(tmp2, struct cifs_ses,
539                                          smb_ses_list);
540                         list_for_each(tmp3, &ses->tcon_list) {
541                                 tcon = list_entry(tmp3,
542                                                   struct cifs_tcon,
543                                                   tcon_list);
544                                 i++;
545                                 seq_printf(m, "\n%d) %s", i, tcon->treeName);
546                                 if (tcon->need_reconnect)
547                                         seq_puts(m, "\tDISCONNECTED ");
548                                 seq_printf(m, "\nSMBs: %d",
549                                            atomic_read(&tcon->num_smbs_sent));
550                                 if (server->ops->print_stats)
551                                         server->ops->print_stats(m, tcon);
552                         }
553                 }
554         }
555         spin_unlock(&cifs_tcp_ses_lock);
556
557         seq_putc(m, '\n');
558         return 0;
559 }
560
561 static int cifs_stats_proc_open(struct inode *inode, struct file *file)
562 {
563         return single_open(file, cifs_stats_proc_show, NULL);
564 }
565
566 static const struct file_operations cifs_stats_proc_fops = {
567         .open           = cifs_stats_proc_open,
568         .read           = seq_read,
569         .llseek         = seq_lseek,
570         .release        = single_release,
571         .write          = cifs_stats_proc_write,
572 };
573
574 #ifdef CONFIG_CIFS_SMB_DIRECT
575 #define PROC_FILE_DEFINE(name) \
576 static ssize_t name##_write(struct file *file, const char __user *buffer, \
577         size_t count, loff_t *ppos) \
578 { \
579         int rc; \
580         rc = kstrtoint_from_user(buffer, count, 10, & name); \
581         if (rc) \
582                 return rc; \
583         return count; \
584 } \
585 static int name##_proc_show(struct seq_file *m, void *v) \
586 { \
587         seq_printf(m, "%d\n", name ); \
588         return 0; \
589 } \
590 static int name##_open(struct inode *inode, struct file *file) \
591 { \
592         return single_open(file, name##_proc_show, NULL); \
593 } \
594 \
595 static const struct file_operations cifs_##name##_proc_fops = { \
596         .open           = name##_open, \
597         .read           = seq_read, \
598         .llseek         = seq_lseek, \
599         .release        = single_release, \
600         .write          = name##_write, \
601 }
602
603 PROC_FILE_DEFINE(rdma_readwrite_threshold);
604 PROC_FILE_DEFINE(smbd_max_frmr_depth);
605 PROC_FILE_DEFINE(smbd_keep_alive_interval);
606 PROC_FILE_DEFINE(smbd_max_receive_size);
607 PROC_FILE_DEFINE(smbd_max_fragmented_recv_size);
608 PROC_FILE_DEFINE(smbd_max_send_size);
609 PROC_FILE_DEFINE(smbd_send_credit_target);
610 PROC_FILE_DEFINE(smbd_receive_credit_max);
611 #endif
612
613 static struct proc_dir_entry *proc_fs_cifs;
614 static const struct file_operations cifsFYI_proc_fops;
615 static const struct file_operations cifs_lookup_cache_proc_fops;
616 static const struct file_operations traceSMB_proc_fops;
617 static const struct file_operations cifs_security_flags_proc_fops;
618 static const struct file_operations cifs_linux_ext_proc_fops;
619
620 void
621 cifs_proc_init(void)
622 {
623         proc_fs_cifs = proc_mkdir("fs/cifs", NULL);
624         if (proc_fs_cifs == NULL)
625                 return;
626
627         proc_create_single("DebugData", 0, proc_fs_cifs,
628                         cifs_debug_data_proc_show);
629
630         proc_create_single("open_files", 0400, proc_fs_cifs,
631                         cifs_debug_files_proc_show);
632
633         proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_fops);
634         proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_fops);
635         proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_fops);
636         proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
637                     &cifs_linux_ext_proc_fops);
638         proc_create("SecurityFlags", 0644, proc_fs_cifs,
639                     &cifs_security_flags_proc_fops);
640         proc_create("LookupCacheEnabled", 0644, proc_fs_cifs,
641                     &cifs_lookup_cache_proc_fops);
642
643 #ifdef CONFIG_CIFS_DFS_UPCALL
644         proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_fops);
645 #endif
646
647 #ifdef CONFIG_CIFS_SMB_DIRECT
648         proc_create("rdma_readwrite_threshold", 0644, proc_fs_cifs,
649                 &cifs_rdma_readwrite_threshold_proc_fops);
650         proc_create("smbd_max_frmr_depth", 0644, proc_fs_cifs,
651                 &cifs_smbd_max_frmr_depth_proc_fops);
652         proc_create("smbd_keep_alive_interval", 0644, proc_fs_cifs,
653                 &cifs_smbd_keep_alive_interval_proc_fops);
654         proc_create("smbd_max_receive_size", 0644, proc_fs_cifs,
655                 &cifs_smbd_max_receive_size_proc_fops);
656         proc_create("smbd_max_fragmented_recv_size", 0644, proc_fs_cifs,
657                 &cifs_smbd_max_fragmented_recv_size_proc_fops);
658         proc_create("smbd_max_send_size", 0644, proc_fs_cifs,
659                 &cifs_smbd_max_send_size_proc_fops);
660         proc_create("smbd_send_credit_target", 0644, proc_fs_cifs,
661                 &cifs_smbd_send_credit_target_proc_fops);
662         proc_create("smbd_receive_credit_max", 0644, proc_fs_cifs,
663                 &cifs_smbd_receive_credit_max_proc_fops);
664 #endif
665 }
666
667 void
668 cifs_proc_clean(void)
669 {
670         if (proc_fs_cifs == NULL)
671                 return;
672
673         remove_proc_entry("DebugData", proc_fs_cifs);
674         remove_proc_entry("open_files", proc_fs_cifs);
675         remove_proc_entry("cifsFYI", proc_fs_cifs);
676         remove_proc_entry("traceSMB", proc_fs_cifs);
677         remove_proc_entry("Stats", proc_fs_cifs);
678         remove_proc_entry("SecurityFlags", proc_fs_cifs);
679         remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
680         remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
681
682 #ifdef CONFIG_CIFS_DFS_UPCALL
683         remove_proc_entry("dfscache", proc_fs_cifs);
684 #endif
685 #ifdef CONFIG_CIFS_SMB_DIRECT
686         remove_proc_entry("rdma_readwrite_threshold", proc_fs_cifs);
687         remove_proc_entry("smbd_max_frmr_depth", proc_fs_cifs);
688         remove_proc_entry("smbd_keep_alive_interval", proc_fs_cifs);
689         remove_proc_entry("smbd_max_receive_size", proc_fs_cifs);
690         remove_proc_entry("smbd_max_fragmented_recv_size", proc_fs_cifs);
691         remove_proc_entry("smbd_max_send_size", proc_fs_cifs);
692         remove_proc_entry("smbd_send_credit_target", proc_fs_cifs);
693         remove_proc_entry("smbd_receive_credit_max", proc_fs_cifs);
694 #endif
695         remove_proc_entry("fs/cifs", NULL);
696 }
697
698 static int cifsFYI_proc_show(struct seq_file *m, void *v)
699 {
700         seq_printf(m, "%d\n", cifsFYI);
701         return 0;
702 }
703
704 static int cifsFYI_proc_open(struct inode *inode, struct file *file)
705 {
706         return single_open(file, cifsFYI_proc_show, NULL);
707 }
708
709 static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
710                 size_t count, loff_t *ppos)
711 {
712         char c[2] = { '\0' };
713         bool bv;
714         int rc;
715
716         rc = get_user(c[0], buffer);
717         if (rc)
718                 return rc;
719         if (strtobool(c, &bv) == 0)
720                 cifsFYI = bv;
721         else if ((c[0] > '1') && (c[0] <= '9'))
722                 cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings */
723         else
724                 return -EINVAL;
725
726         return count;
727 }
728
729 static const struct file_operations cifsFYI_proc_fops = {
730         .open           = cifsFYI_proc_open,
731         .read           = seq_read,
732         .llseek         = seq_lseek,
733         .release        = single_release,
734         .write          = cifsFYI_proc_write,
735 };
736
737 static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
738 {
739         seq_printf(m, "%d\n", linuxExtEnabled);
740         return 0;
741 }
742
743 static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file)
744 {
745         return single_open(file, cifs_linux_ext_proc_show, NULL);
746 }
747
748 static ssize_t cifs_linux_ext_proc_write(struct file *file,
749                 const char __user *buffer, size_t count, loff_t *ppos)
750 {
751         int rc;
752
753         rc = kstrtobool_from_user(buffer, count, &linuxExtEnabled);
754         if (rc)
755                 return rc;
756
757         return count;
758 }
759
760 static const struct file_operations cifs_linux_ext_proc_fops = {
761         .open           = cifs_linux_ext_proc_open,
762         .read           = seq_read,
763         .llseek         = seq_lseek,
764         .release        = single_release,
765         .write          = cifs_linux_ext_proc_write,
766 };
767
768 static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v)
769 {
770         seq_printf(m, "%d\n", lookupCacheEnabled);
771         return 0;
772 }
773
774 static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file)
775 {
776         return single_open(file, cifs_lookup_cache_proc_show, NULL);
777 }
778
779 static ssize_t cifs_lookup_cache_proc_write(struct file *file,
780                 const char __user *buffer, size_t count, loff_t *ppos)
781 {
782         int rc;
783
784         rc = kstrtobool_from_user(buffer, count, &lookupCacheEnabled);
785         if (rc)
786                 return rc;
787
788         return count;
789 }
790
791 static const struct file_operations cifs_lookup_cache_proc_fops = {
792         .open           = cifs_lookup_cache_proc_open,
793         .read           = seq_read,
794         .llseek         = seq_lseek,
795         .release        = single_release,
796         .write          = cifs_lookup_cache_proc_write,
797 };
798
799 static int traceSMB_proc_show(struct seq_file *m, void *v)
800 {
801         seq_printf(m, "%d\n", traceSMB);
802         return 0;
803 }
804
805 static int traceSMB_proc_open(struct inode *inode, struct file *file)
806 {
807         return single_open(file, traceSMB_proc_show, NULL);
808 }
809
810 static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer,
811                 size_t count, loff_t *ppos)
812 {
813         int rc;
814
815         rc = kstrtobool_from_user(buffer, count, &traceSMB);
816         if (rc)
817                 return rc;
818
819         return count;
820 }
821
822 static const struct file_operations traceSMB_proc_fops = {
823         .open           = traceSMB_proc_open,
824         .read           = seq_read,
825         .llseek         = seq_lseek,
826         .release        = single_release,
827         .write          = traceSMB_proc_write,
828 };
829
830 static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
831 {
832         seq_printf(m, "0x%x\n", global_secflags);
833         return 0;
834 }
835
836 static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
837 {
838         return single_open(file, cifs_security_flags_proc_show, NULL);
839 }
840
841 /*
842  * Ensure that if someone sets a MUST flag, that we disable all other MAY
843  * flags except for the ones corresponding to the given MUST flag. If there are
844  * multiple MUST flags, then try to prefer more secure ones.
845  */
846 static void
847 cifs_security_flags_handle_must_flags(unsigned int *flags)
848 {
849         unsigned int signflags = *flags & CIFSSEC_MUST_SIGN;
850
851         if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
852                 *flags = CIFSSEC_MUST_KRB5;
853         else if ((*flags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
854                 *flags = CIFSSEC_MUST_NTLMSSP;
855         else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
856                 *flags = CIFSSEC_MUST_NTLMV2;
857         else if ((*flags & CIFSSEC_MUST_NTLM) == CIFSSEC_MUST_NTLM)
858                 *flags = CIFSSEC_MUST_NTLM;
859         else if (CIFSSEC_MUST_LANMAN &&
860                  (*flags & CIFSSEC_MUST_LANMAN) == CIFSSEC_MUST_LANMAN)
861                 *flags = CIFSSEC_MUST_LANMAN;
862         else if (CIFSSEC_MUST_PLNTXT &&
863                  (*flags & CIFSSEC_MUST_PLNTXT) == CIFSSEC_MUST_PLNTXT)
864                 *flags = CIFSSEC_MUST_PLNTXT;
865
866         *flags |= signflags;
867 }
868
869 static ssize_t cifs_security_flags_proc_write(struct file *file,
870                 const char __user *buffer, size_t count, loff_t *ppos)
871 {
872         int rc;
873         unsigned int flags;
874         char flags_string[12];
875         bool bv;
876
877         if ((count < 1) || (count > 11))
878                 return -EINVAL;
879
880         memset(flags_string, 0, 12);
881
882         if (copy_from_user(flags_string, buffer, count))
883                 return -EFAULT;
884
885         if (count < 3) {
886                 /* single char or single char followed by null */
887                 if (strtobool(flags_string, &bv) == 0) {
888                         global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF;
889                         return count;
890                 } else if (!isdigit(flags_string[0])) {
891                         cifs_dbg(VFS, "Invalid SecurityFlags: %s\n",
892                                         flags_string);
893                         return -EINVAL;
894                 }
895         }
896
897         /* else we have a number */
898         rc = kstrtouint(flags_string, 0, &flags);
899         if (rc) {
900                 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n",
901                                 flags_string);
902                 return rc;
903         }
904
905         cifs_dbg(FYI, "sec flags 0x%x\n", flags);
906
907         if (flags == 0)  {
908                 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", flags_string);
909                 return -EINVAL;
910         }
911
912         if (flags & ~CIFSSEC_MASK) {
913                 cifs_dbg(VFS, "Unsupported security flags: 0x%x\n",
914                          flags & ~CIFSSEC_MASK);
915                 return -EINVAL;
916         }
917
918         cifs_security_flags_handle_must_flags(&flags);
919
920         /* flags look ok - update the global security flags for cifs module */
921         global_secflags = flags;
922         if (global_secflags & CIFSSEC_MUST_SIGN) {
923                 /* requiring signing implies signing is allowed */
924                 global_secflags |= CIFSSEC_MAY_SIGN;
925                 cifs_dbg(FYI, "packet signing now required\n");
926         } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) {
927                 cifs_dbg(FYI, "packet signing disabled\n");
928         }
929         /* BB should we turn on MAY flags for other MUST options? */
930         return count;
931 }
932
933 static const struct file_operations cifs_security_flags_proc_fops = {
934         .open           = cifs_security_flags_proc_open,
935         .read           = seq_read,
936         .llseek         = seq_lseek,
937         .release        = single_release,
938         .write          = cifs_security_flags_proc_write,
939 };
940 #else
941 inline void cifs_proc_init(void)
942 {
943 }
944
945 inline void cifs_proc_clean(void)
946 {
947 }
948 #endif /* PROC_FS */