xref: /openbmc/linux/fs/smb/client/cifs_debug.c (revision 726ccdba)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *
4  *   Copyright (C) International Business Machines  Corp., 2000,2005
5  *
6  *   Modified by Steve French (sfrench@us.ibm.com)
7  */
8 #include <linux/fs.h>
9 #include <linux/string.h>
10 #include <linux/ctype.h>
11 #include <linux/kstrtox.h>
12 #include <linux/module.h>
13 #include <linux/proc_fs.h>
14 #include <linux/uaccess.h>
15 #include "cifspdu.h"
16 #include "cifsglob.h"
17 #include "cifsproto.h"
18 #include "cifs_debug.h"
19 #include "cifsfs.h"
20 #include "fs_context.h"
21 #ifdef CONFIG_CIFS_DFS_UPCALL
22 #include "dfs_cache.h"
23 #endif
24 #ifdef CONFIG_CIFS_SMB_DIRECT
25 #include "smbdirect.h"
26 #endif
27 #include "cifs_swn.h"
28 
29 void
30 cifs_dump_mem(char *label, void *data, int length)
31 {
32 	pr_debug("%s: dump of %d bytes of data at 0x%p\n", label, length, data);
33 	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
34 		       data, length, true);
35 }
36 
37 void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
38 {
39 #ifdef CONFIG_CIFS_DEBUG2
40 	struct smb_hdr *smb = buf;
41 
42 	cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n",
43 		 smb->Command, smb->Status.CifsError,
44 		 smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
45 	cifs_dbg(VFS, "smb buf %p len %u\n", smb,
46 		 server->ops->calc_smb_size(smb));
47 #endif /* CONFIG_CIFS_DEBUG2 */
48 }
49 
50 void cifs_dump_mids(struct TCP_Server_Info *server)
51 {
52 #ifdef CONFIG_CIFS_DEBUG2
53 	struct mid_q_entry *mid_entry;
54 
55 	if (server == NULL)
56 		return;
57 
58 	cifs_dbg(VFS, "Dump pending requests:\n");
59 	spin_lock(&server->mid_lock);
60 	list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
61 		cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
62 			 mid_entry->mid_state,
63 			 le16_to_cpu(mid_entry->command),
64 			 mid_entry->pid,
65 			 mid_entry->callback_data,
66 			 mid_entry->mid);
67 #ifdef CONFIG_CIFS_STATS2
68 		cifs_dbg(VFS, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n",
69 			 mid_entry->large_buf,
70 			 mid_entry->resp_buf,
71 			 mid_entry->when_received,
72 			 jiffies);
73 #endif /* STATS2 */
74 		cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n",
75 			 mid_entry->multiRsp, mid_entry->multiEnd);
76 		if (mid_entry->resp_buf) {
77 			cifs_dump_detail(mid_entry->resp_buf, server);
78 			cifs_dump_mem("existing buf: ",
79 				mid_entry->resp_buf, 62);
80 		}
81 	}
82 	spin_unlock(&server->mid_lock);
83 #endif /* CONFIG_CIFS_DEBUG2 */
84 }
85 
86 #ifdef CONFIG_PROC_FS
87 static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
88 {
89 	__u32 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
90 
91 	seq_printf(m, "%s Mounts: %d ", tcon->tree_name, tcon->tc_count);
92 	if (tcon->nativeFileSystem)
93 		seq_printf(m, "Type: %s ", tcon->nativeFileSystem);
94 	seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d",
95 		   le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
96 		   le32_to_cpu(tcon->fsAttrInfo.Attributes),
97 		   le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
98 		   tcon->status);
99 	if (dev_type == FILE_DEVICE_DISK)
100 		seq_puts(m, " type: DISK ");
101 	else if (dev_type == FILE_DEVICE_CD_ROM)
102 		seq_puts(m, " type: CDROM ");
103 	else
104 		seq_printf(m, " type: %d ", dev_type);
105 
106 	seq_printf(m, "Serial Number: 0x%x", tcon->vol_serial_number);
107 
108 	if ((tcon->seal) ||
109 	    (tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
110 	    (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
111 		seq_puts(m, " encrypted");
112 	if (tcon->nocase)
113 		seq_printf(m, " nocase");
114 	if (tcon->unix_ext)
115 		seq_printf(m, " POSIX Extensions");
116 	if (tcon->ses->server->ops->dump_share_caps)
117 		tcon->ses->server->ops->dump_share_caps(m, tcon);
118 	if (tcon->use_witness)
119 		seq_puts(m, " Witness");
120 	if (tcon->broken_sparse_sup)
121 		seq_puts(m, " nosparse");
122 	if (tcon->need_reconnect)
123 		seq_puts(m, "\tDISCONNECTED ");
124 	seq_putc(m, '\n');
125 }
126 
127 static void
128 cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
129 {
130 	struct TCP_Server_Info *server = chan->server;
131 
132 	seq_printf(m, "\n\n\t\tChannel: %d ConnectionId: 0x%llx"
133 		   "\n\t\tNumber of credits: %d Dialect 0x%x"
134 		   "\n\t\tTCP status: %d Instance: %d"
135 		   "\n\t\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d"
136 		   "\n\t\tIn Send: %d In MaxReq Wait: %d",
137 		   i+1, server->conn_id,
138 		   server->credits,
139 		   server->dialect,
140 		   server->tcpStatus,
141 		   server->reconnect_instance,
142 		   server->srv_count,
143 		   server->sec_mode,
144 		   in_flight(server),
145 		   atomic_read(&server->in_send),
146 		   atomic_read(&server->num_waiters));
147 }
148 
149 static void
150 cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface)
151 {
152 	struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
153 	struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
154 
155 	seq_printf(m, "\tSpeed: %zu bps\n", iface->speed);
156 	seq_puts(m, "\t\tCapabilities: ");
157 	if (iface->rdma_capable)
158 		seq_puts(m, "rdma ");
159 	if (iface->rss_capable)
160 		seq_puts(m, "rss ");
161 	seq_putc(m, '\n');
162 	if (iface->sockaddr.ss_family == AF_INET)
163 		seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr);
164 	else if (iface->sockaddr.ss_family == AF_INET6)
165 		seq_printf(m, "\t\tIPv6: %pI6\n", &ipv6->sin6_addr);
166 	if (!iface->is_active)
167 		seq_puts(m, "\t\t[for-cleanup]\n");
168 }
169 
170 static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
171 {
172 	struct TCP_Server_Info *server;
173 	struct cifs_ses *ses;
174 	struct cifs_tcon *tcon;
175 	struct cifsFileInfo *cfile;
176 
177 	seq_puts(m, "# Version:1\n");
178 	seq_puts(m, "# Format:\n");
179 	seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>");
180 #ifdef CONFIG_CIFS_DEBUG2
181 	seq_printf(m, " <filename> <mid>\n");
182 #else
183 	seq_printf(m, " <filename>\n");
184 #endif /* CIFS_DEBUG2 */
185 	spin_lock(&cifs_tcp_ses_lock);
186 	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
187 		list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
188 			list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
189 				spin_lock(&tcon->open_file_lock);
190 				list_for_each_entry(cfile, &tcon->openFileList, tlist) {
191 					seq_printf(m,
192 						"0x%x 0x%llx 0x%llx 0x%x %d %d %d %pd",
193 						tcon->tid,
194 						ses->Suid,
195 						cfile->fid.persistent_fid,
196 						cfile->f_flags,
197 						cfile->count,
198 						cfile->pid,
199 						from_kuid(&init_user_ns, cfile->uid),
200 						cfile->dentry);
201 #ifdef CONFIG_CIFS_DEBUG2
202 					seq_printf(m, " %llu\n", cfile->fid.mid);
203 #else
204 					seq_printf(m, "\n");
205 #endif /* CIFS_DEBUG2 */
206 				}
207 				spin_unlock(&tcon->open_file_lock);
208 			}
209 		}
210 	}
211 	spin_unlock(&cifs_tcp_ses_lock);
212 	seq_putc(m, '\n');
213 	return 0;
214 }
215 
216 static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
217 {
218 	struct mid_q_entry *mid_entry;
219 	struct TCP_Server_Info *server;
220 	struct TCP_Server_Info *chan_server;
221 	struct cifs_ses *ses;
222 	struct cifs_tcon *tcon;
223 	struct cifs_server_iface *iface;
224 	int c, i, j;
225 
226 	seq_puts(m,
227 		    "Display Internal CIFS Data Structures for Debugging\n"
228 		    "---------------------------------------------------\n");
229 	seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
230 	seq_printf(m, "Features:");
231 #ifdef CONFIG_CIFS_DFS_UPCALL
232 	seq_printf(m, " DFS");
233 #endif
234 #ifdef CONFIG_CIFS_FSCACHE
235 	seq_printf(m, ",FSCACHE");
236 #endif
237 #ifdef CONFIG_CIFS_SMB_DIRECT
238 	seq_printf(m, ",SMB_DIRECT");
239 #endif
240 #ifdef CONFIG_CIFS_STATS2
241 	seq_printf(m, ",STATS2");
242 #else
243 	seq_printf(m, ",STATS");
244 #endif
245 #ifdef CONFIG_CIFS_DEBUG2
246 	seq_printf(m, ",DEBUG2");
247 #elif defined(CONFIG_CIFS_DEBUG)
248 	seq_printf(m, ",DEBUG");
249 #endif
250 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
251 	seq_printf(m, ",ALLOW_INSECURE_LEGACY");
252 #endif
253 #ifdef CONFIG_CIFS_POSIX
254 	seq_printf(m, ",CIFS_POSIX");
255 #endif
256 #ifdef CONFIG_CIFS_UPCALL
257 	seq_printf(m, ",UPCALL(SPNEGO)");
258 #endif
259 #ifdef CONFIG_CIFS_XATTR
260 	seq_printf(m, ",XATTR");
261 #endif
262 	seq_printf(m, ",ACL");
263 #ifdef CONFIG_CIFS_SWN_UPCALL
264 	seq_puts(m, ",WITNESS");
265 #endif
266 	seq_putc(m, '\n');
267 	seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize);
268 	seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
269 
270 	seq_printf(m, "\nServers: ");
271 
272 	c = 0;
273 	spin_lock(&cifs_tcp_ses_lock);
274 	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
275 		/* channel info will be printed as a part of sessions below */
276 		if (CIFS_SERVER_IS_CHAN(server))
277 			continue;
278 
279 		c++;
280 		seq_printf(m, "\n%d) ConnectionId: 0x%llx ",
281 			c, server->conn_id);
282 
283 		spin_lock(&server->srv_lock);
284 		if (server->hostname)
285 			seq_printf(m, "Hostname: %s ", server->hostname);
286 		spin_unlock(&server->srv_lock);
287 #ifdef CONFIG_CIFS_SMB_DIRECT
288 		if (!server->rdma)
289 			goto skip_rdma;
290 
291 		if (!server->smbd_conn) {
292 			seq_printf(m, "\nSMBDirect transport not available");
293 			goto skip_rdma;
294 		}
295 
296 		seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
297 			"transport status: %x",
298 			server->smbd_conn->protocol,
299 			server->smbd_conn->transport_status);
300 		seq_printf(m, "\nConn receive_credit_max: %x "
301 			"send_credit_target: %x max_send_size: %x",
302 			server->smbd_conn->receive_credit_max,
303 			server->smbd_conn->send_credit_target,
304 			server->smbd_conn->max_send_size);
305 		seq_printf(m, "\nConn max_fragmented_recv_size: %x "
306 			"max_fragmented_send_size: %x max_receive_size:%x",
307 			server->smbd_conn->max_fragmented_recv_size,
308 			server->smbd_conn->max_fragmented_send_size,
309 			server->smbd_conn->max_receive_size);
310 		seq_printf(m, "\nConn keep_alive_interval: %x "
311 			"max_readwrite_size: %x rdma_readwrite_threshold: %x",
312 			server->smbd_conn->keep_alive_interval,
313 			server->smbd_conn->max_readwrite_size,
314 			server->smbd_conn->rdma_readwrite_threshold);
315 		seq_printf(m, "\nDebug count_get_receive_buffer: %x "
316 			"count_put_receive_buffer: %x count_send_empty: %x",
317 			server->smbd_conn->count_get_receive_buffer,
318 			server->smbd_conn->count_put_receive_buffer,
319 			server->smbd_conn->count_send_empty);
320 		seq_printf(m, "\nRead Queue count_reassembly_queue: %x "
321 			"count_enqueue_reassembly_queue: %x "
322 			"count_dequeue_reassembly_queue: %x "
323 			"fragment_reassembly_remaining: %x "
324 			"reassembly_data_length: %x "
325 			"reassembly_queue_length: %x",
326 			server->smbd_conn->count_reassembly_queue,
327 			server->smbd_conn->count_enqueue_reassembly_queue,
328 			server->smbd_conn->count_dequeue_reassembly_queue,
329 			server->smbd_conn->fragment_reassembly_remaining,
330 			server->smbd_conn->reassembly_data_length,
331 			server->smbd_conn->reassembly_queue_length);
332 		seq_printf(m, "\nCurrent Credits send_credits: %x "
333 			"receive_credits: %x receive_credit_target: %x",
334 			atomic_read(&server->smbd_conn->send_credits),
335 			atomic_read(&server->smbd_conn->receive_credits),
336 			server->smbd_conn->receive_credit_target);
337 		seq_printf(m, "\nPending send_pending: %x ",
338 			atomic_read(&server->smbd_conn->send_pending));
339 		seq_printf(m, "\nReceive buffers count_receive_queue: %x "
340 			"count_empty_packet_queue: %x",
341 			server->smbd_conn->count_receive_queue,
342 			server->smbd_conn->count_empty_packet_queue);
343 		seq_printf(m, "\nMR responder_resources: %x "
344 			"max_frmr_depth: %x mr_type: %x",
345 			server->smbd_conn->responder_resources,
346 			server->smbd_conn->max_frmr_depth,
347 			server->smbd_conn->mr_type);
348 		seq_printf(m, "\nMR mr_ready_count: %x mr_used_count: %x",
349 			atomic_read(&server->smbd_conn->mr_ready_count),
350 			atomic_read(&server->smbd_conn->mr_used_count));
351 skip_rdma:
352 #endif
353 		seq_printf(m, "\nNumber of credits: %d Dialect 0x%x",
354 			server->credits,  server->dialect);
355 		if (server->compress_algorithm == SMB3_COMPRESS_LZNT1)
356 			seq_printf(m, " COMPRESS_LZNT1");
357 		else if (server->compress_algorithm == SMB3_COMPRESS_LZ77)
358 			seq_printf(m, " COMPRESS_LZ77");
359 		else if (server->compress_algorithm == SMB3_COMPRESS_LZ77_HUFF)
360 			seq_printf(m, " COMPRESS_LZ77_HUFF");
361 		if (server->sign)
362 			seq_printf(m, " signed");
363 		if (server->posix_ext_supported)
364 			seq_printf(m, " posix");
365 		if (server->nosharesock)
366 			seq_printf(m, " nosharesock");
367 
368 		if (server->rdma)
369 			seq_printf(m, "\nRDMA ");
370 		seq_printf(m, "\nTCP status: %d Instance: %d"
371 				"\nLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d",
372 				server->tcpStatus,
373 				server->reconnect_instance,
374 				server->srv_count,
375 				server->sec_mode, in_flight(server));
376 
377 		seq_printf(m, "\nIn Send: %d In MaxReq Wait: %d",
378 				atomic_read(&server->in_send),
379 				atomic_read(&server->num_waiters));
380 		if (IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)) {
381 			if (server->origin_fullpath)
382 				seq_printf(m, "\nDFS origin full path: %s",
383 					   server->origin_fullpath);
384 			if (server->leaf_fullpath)
385 				seq_printf(m, "\nDFS leaf full path:   %s",
386 					   server->leaf_fullpath);
387 		}
388 
389 		seq_printf(m, "\n\n\tSessions: ");
390 		i = 0;
391 		list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
392 			i++;
393 			if ((ses->serverDomain == NULL) ||
394 				(ses->serverOS == NULL) ||
395 				(ses->serverNOS == NULL)) {
396 				seq_printf(m, "\n\t%d) Address: %s Uses: %d Capability: 0x%x\tSession Status: %d ",
397 					i, ses->ip_addr, ses->ses_count,
398 					ses->capabilities, ses->ses_status);
399 				if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
400 					seq_printf(m, "Guest ");
401 				else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
402 					seq_printf(m, "Anonymous ");
403 			} else {
404 				seq_printf(m,
405 				    "\n\t%d) Name: %s  Domain: %s Uses: %d OS: %s "
406 				    "\n\tNOS: %s\tCapability: 0x%x"
407 					"\n\tSMB session status: %d ",
408 				i, ses->ip_addr, ses->serverDomain,
409 				ses->ses_count, ses->serverOS, ses->serverNOS,
410 				ses->capabilities, ses->ses_status);
411 			}
412 
413 			seq_printf(m, "\n\tSecurity type: %s ",
414 				get_security_type_str(server->ops->select_sectype(server, ses->sectype)));
415 
416 			/* dump session id helpful for use with network trace */
417 			seq_printf(m, " SessionId: 0x%llx", ses->Suid);
418 			if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
419 				seq_puts(m, " encrypted");
420 				/* can help in debugging to show encryption type */
421 				if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
422 					seq_puts(m, "(gcm256)");
423 			}
424 			if (ses->sign)
425 				seq_puts(m, " signed");
426 
427 			seq_printf(m, "\n\tUser: %d Cred User: %d",
428 				   from_kuid(&init_user_ns, ses->linux_uid),
429 				   from_kuid(&init_user_ns, ses->cred_uid));
430 
431 			if (ses->dfs_root_ses) {
432 				seq_printf(m, "\n\tDFS root session id: 0x%llx",
433 					   ses->dfs_root_ses->Suid);
434 			}
435 
436 			spin_lock(&ses->chan_lock);
437 			if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0))
438 				seq_puts(m, "\tPrimary channel: DISCONNECTED ");
439 			if (CIFS_CHAN_IN_RECONNECT(ses, 0))
440 				seq_puts(m, "\t[RECONNECTING] ");
441 
442 			if (ses->chan_count > 1) {
443 				seq_printf(m, "\n\n\tExtra Channels: %zu ",
444 					   ses->chan_count-1);
445 				for (j = 1; j < ses->chan_count; j++) {
446 					cifs_dump_channel(m, j, &ses->chans[j]);
447 					if (CIFS_CHAN_NEEDS_RECONNECT(ses, j))
448 						seq_puts(m, "\tDISCONNECTED ");
449 					if (CIFS_CHAN_IN_RECONNECT(ses, j))
450 						seq_puts(m, "\t[RECONNECTING] ");
451 				}
452 			}
453 			spin_unlock(&ses->chan_lock);
454 
455 			seq_puts(m, "\n\n\tShares: ");
456 			j = 0;
457 
458 			seq_printf(m, "\n\t%d) IPC: ", j);
459 			if (ses->tcon_ipc)
460 				cifs_debug_tcon(m, ses->tcon_ipc);
461 			else
462 				seq_puts(m, "none\n");
463 
464 			list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
465 				++j;
466 				seq_printf(m, "\n\t%d) ", j);
467 				cifs_debug_tcon(m, tcon);
468 			}
469 
470 			spin_lock(&ses->iface_lock);
471 			if (ses->iface_count)
472 				seq_printf(m, "\n\n\tServer interfaces: %zu"
473 					   "\tLast updated: %lu seconds ago",
474 					   ses->iface_count,
475 					   (jiffies - ses->iface_last_update) / HZ);
476 			j = 0;
477 			list_for_each_entry(iface, &ses->iface_list,
478 						 iface_head) {
479 				seq_printf(m, "\n\t%d)", ++j);
480 				cifs_dump_iface(m, iface);
481 				if (is_ses_using_iface(ses, iface))
482 					seq_puts(m, "\t\t[CONNECTED]\n");
483 			}
484 			spin_unlock(&ses->iface_lock);
485 
486 			seq_puts(m, "\n\n\tMIDs: ");
487 			spin_lock(&ses->chan_lock);
488 			for (j = 0; j < ses->chan_count; j++) {
489 				chan_server = ses->chans[j].server;
490 				if (!chan_server)
491 					continue;
492 
493 				if (list_empty(&chan_server->pending_mid_q))
494 					continue;
495 
496 				seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
497 					   chan_server->conn_id);
498 				spin_lock(&chan_server->mid_lock);
499 				list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
500 					seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
501 						   mid_entry->mid_state,
502 						   le16_to_cpu(mid_entry->command),
503 						   mid_entry->pid,
504 						   mid_entry->callback_data,
505 						   mid_entry->mid);
506 				}
507 				spin_unlock(&chan_server->mid_lock);
508 			}
509 			spin_unlock(&ses->chan_lock);
510 			seq_puts(m, "\n--\n");
511 		}
512 		if (i == 0)
513 			seq_printf(m, "\n\t\t[NONE]");
514 	}
515 	if (c == 0)
516 		seq_printf(m, "\n\t[NONE]");
517 
518 	spin_unlock(&cifs_tcp_ses_lock);
519 	seq_putc(m, '\n');
520 	cifs_swn_dump(m);
521 
522 	/* BB add code to dump additional info such as TCP session info now */
523 	return 0;
524 }
525 
526 static ssize_t cifs_stats_proc_write(struct file *file,
527 		const char __user *buffer, size_t count, loff_t *ppos)
528 {
529 	bool bv;
530 	int rc;
531 	struct TCP_Server_Info *server;
532 	struct cifs_ses *ses;
533 	struct cifs_tcon *tcon;
534 
535 	rc = kstrtobool_from_user(buffer, count, &bv);
536 	if (rc == 0) {
537 #ifdef CONFIG_CIFS_STATS2
538 		int i;
539 
540 		atomic_set(&total_buf_alloc_count, 0);
541 		atomic_set(&total_small_buf_alloc_count, 0);
542 #endif /* CONFIG_CIFS_STATS2 */
543 		atomic_set(&tcpSesReconnectCount, 0);
544 		atomic_set(&tconInfoReconnectCount, 0);
545 
546 		spin_lock(&GlobalMid_Lock);
547 		GlobalMaxActiveXid = 0;
548 		GlobalCurrentXid = 0;
549 		spin_unlock(&GlobalMid_Lock);
550 		spin_lock(&cifs_tcp_ses_lock);
551 		list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
552 			server->max_in_flight = 0;
553 #ifdef CONFIG_CIFS_STATS2
554 			for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
555 				atomic_set(&server->num_cmds[i], 0);
556 				atomic_set(&server->smb2slowcmd[i], 0);
557 				server->time_per_cmd[i] = 0;
558 				server->slowest_cmd[i] = 0;
559 				server->fastest_cmd[0] = 0;
560 			}
561 #endif /* CONFIG_CIFS_STATS2 */
562 			list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
563 				list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
564 					atomic_set(&tcon->num_smbs_sent, 0);
565 					spin_lock(&tcon->stat_lock);
566 					tcon->bytes_read = 0;
567 					tcon->bytes_written = 0;
568 					spin_unlock(&tcon->stat_lock);
569 					if (server->ops->clear_stats)
570 						server->ops->clear_stats(tcon);
571 				}
572 			}
573 		}
574 		spin_unlock(&cifs_tcp_ses_lock);
575 	} else {
576 		return rc;
577 	}
578 
579 	return count;
580 }
581 
582 static int cifs_stats_proc_show(struct seq_file *m, void *v)
583 {
584 	int i;
585 #ifdef CONFIG_CIFS_STATS2
586 	int j;
587 #endif /* STATS2 */
588 	struct TCP_Server_Info *server;
589 	struct cifs_ses *ses;
590 	struct cifs_tcon *tcon;
591 
592 	seq_printf(m, "Resources in use\nCIFS Session: %d\n",
593 			sesInfoAllocCount.counter);
594 	seq_printf(m, "Share (unique mount targets): %d\n",
595 			tconInfoAllocCount.counter);
596 	seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",
597 			buf_alloc_count.counter,
598 			cifs_min_rcv + tcpSesAllocCount.counter);
599 	seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
600 			small_buf_alloc_count.counter, cifs_min_small);
601 #ifdef CONFIG_CIFS_STATS2
602 	seq_printf(m, "Total Large %d Small %d Allocations\n",
603 				atomic_read(&total_buf_alloc_count),
604 				atomic_read(&total_small_buf_alloc_count));
605 #endif /* CONFIG_CIFS_STATS2 */
606 
607 	seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&mid_count));
608 	seq_printf(m,
609 		"\n%d session %d share reconnects\n",
610 		tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
611 
612 	seq_printf(m,
613 		"Total vfs operations: %d maximum at one time: %d\n",
614 		GlobalCurrentXid, GlobalMaxActiveXid);
615 
616 	i = 0;
617 	spin_lock(&cifs_tcp_ses_lock);
618 	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
619 		seq_printf(m, "\nMax requests in flight: %d", server->max_in_flight);
620 #ifdef CONFIG_CIFS_STATS2
621 		seq_puts(m, "\nTotal time spent processing by command. Time ");
622 		seq_printf(m, "units are jiffies (%d per second)\n", HZ);
623 		seq_puts(m, "  SMB3 CMD\tNumber\tTotal Time\tFastest\tSlowest\n");
624 		seq_puts(m, "  --------\t------\t----------\t-------\t-------\n");
625 		for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
626 			seq_printf(m, "  %d\t\t%d\t%llu\t\t%u\t%u\n", j,
627 				atomic_read(&server->num_cmds[j]),
628 				server->time_per_cmd[j],
629 				server->fastest_cmd[j],
630 				server->slowest_cmd[j]);
631 		for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
632 			if (atomic_read(&server->smb2slowcmd[j])) {
633 				spin_lock(&server->srv_lock);
634 				seq_printf(m, "  %d slow responses from %s for command %d\n",
635 					atomic_read(&server->smb2slowcmd[j]),
636 					server->hostname, j);
637 				spin_unlock(&server->srv_lock);
638 			}
639 #endif /* STATS2 */
640 		list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
641 			list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
642 				i++;
643 				seq_printf(m, "\n%d) %s", i, tcon->tree_name);
644 				if (tcon->need_reconnect)
645 					seq_puts(m, "\tDISCONNECTED ");
646 				seq_printf(m, "\nSMBs: %d",
647 					   atomic_read(&tcon->num_smbs_sent));
648 				if (server->ops->print_stats)
649 					server->ops->print_stats(m, tcon);
650 			}
651 		}
652 	}
653 	spin_unlock(&cifs_tcp_ses_lock);
654 
655 	seq_putc(m, '\n');
656 	return 0;
657 }
658 
659 static int cifs_stats_proc_open(struct inode *inode, struct file *file)
660 {
661 	return single_open(file, cifs_stats_proc_show, NULL);
662 }
663 
664 static const struct proc_ops cifs_stats_proc_ops = {
665 	.proc_open	= cifs_stats_proc_open,
666 	.proc_read	= seq_read,
667 	.proc_lseek	= seq_lseek,
668 	.proc_release	= single_release,
669 	.proc_write	= cifs_stats_proc_write,
670 };
671 
672 #ifdef CONFIG_CIFS_SMB_DIRECT
673 #define PROC_FILE_DEFINE(name) \
674 static ssize_t name##_write(struct file *file, const char __user *buffer, \
675 	size_t count, loff_t *ppos) \
676 { \
677 	int rc; \
678 	rc = kstrtoint_from_user(buffer, count, 10, & name); \
679 	if (rc) \
680 		return rc; \
681 	return count; \
682 } \
683 static int name##_proc_show(struct seq_file *m, void *v) \
684 { \
685 	seq_printf(m, "%d\n", name ); \
686 	return 0; \
687 } \
688 static int name##_open(struct inode *inode, struct file *file) \
689 { \
690 	return single_open(file, name##_proc_show, NULL); \
691 } \
692 \
693 static const struct proc_ops cifs_##name##_proc_fops = { \
694 	.proc_open	= name##_open, \
695 	.proc_read	= seq_read, \
696 	.proc_lseek	= seq_lseek, \
697 	.proc_release	= single_release, \
698 	.proc_write	= name##_write, \
699 }
700 
701 PROC_FILE_DEFINE(rdma_readwrite_threshold);
702 PROC_FILE_DEFINE(smbd_max_frmr_depth);
703 PROC_FILE_DEFINE(smbd_keep_alive_interval);
704 PROC_FILE_DEFINE(smbd_max_receive_size);
705 PROC_FILE_DEFINE(smbd_max_fragmented_recv_size);
706 PROC_FILE_DEFINE(smbd_max_send_size);
707 PROC_FILE_DEFINE(smbd_send_credit_target);
708 PROC_FILE_DEFINE(smbd_receive_credit_max);
709 #endif
710 
711 static struct proc_dir_entry *proc_fs_cifs;
712 static const struct proc_ops cifsFYI_proc_ops;
713 static const struct proc_ops cifs_lookup_cache_proc_ops;
714 static const struct proc_ops traceSMB_proc_ops;
715 static const struct proc_ops cifs_security_flags_proc_ops;
716 static const struct proc_ops cifs_linux_ext_proc_ops;
717 static const struct proc_ops cifs_mount_params_proc_ops;
718 
719 void
720 cifs_proc_init(void)
721 {
722 	proc_fs_cifs = proc_mkdir("fs/cifs", NULL);
723 	if (proc_fs_cifs == NULL)
724 		return;
725 
726 	proc_create_single("DebugData", 0, proc_fs_cifs,
727 			cifs_debug_data_proc_show);
728 
729 	proc_create_single("open_files", 0400, proc_fs_cifs,
730 			cifs_debug_files_proc_show);
731 
732 	proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_ops);
733 	proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_ops);
734 	proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_ops);
735 	proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
736 		    &cifs_linux_ext_proc_ops);
737 	proc_create("SecurityFlags", 0644, proc_fs_cifs,
738 		    &cifs_security_flags_proc_ops);
739 	proc_create("LookupCacheEnabled", 0644, proc_fs_cifs,
740 		    &cifs_lookup_cache_proc_ops);
741 
742 	proc_create("mount_params", 0444, proc_fs_cifs, &cifs_mount_params_proc_ops);
743 
744 #ifdef CONFIG_CIFS_DFS_UPCALL
745 	proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_ops);
746 #endif
747 
748 #ifdef CONFIG_CIFS_SMB_DIRECT
749 	proc_create("rdma_readwrite_threshold", 0644, proc_fs_cifs,
750 		&cifs_rdma_readwrite_threshold_proc_fops);
751 	proc_create("smbd_max_frmr_depth", 0644, proc_fs_cifs,
752 		&cifs_smbd_max_frmr_depth_proc_fops);
753 	proc_create("smbd_keep_alive_interval", 0644, proc_fs_cifs,
754 		&cifs_smbd_keep_alive_interval_proc_fops);
755 	proc_create("smbd_max_receive_size", 0644, proc_fs_cifs,
756 		&cifs_smbd_max_receive_size_proc_fops);
757 	proc_create("smbd_max_fragmented_recv_size", 0644, proc_fs_cifs,
758 		&cifs_smbd_max_fragmented_recv_size_proc_fops);
759 	proc_create("smbd_max_send_size", 0644, proc_fs_cifs,
760 		&cifs_smbd_max_send_size_proc_fops);
761 	proc_create("smbd_send_credit_target", 0644, proc_fs_cifs,
762 		&cifs_smbd_send_credit_target_proc_fops);
763 	proc_create("smbd_receive_credit_max", 0644, proc_fs_cifs,
764 		&cifs_smbd_receive_credit_max_proc_fops);
765 #endif
766 }
767 
768 void
769 cifs_proc_clean(void)
770 {
771 	if (proc_fs_cifs == NULL)
772 		return;
773 
774 	remove_proc_entry("DebugData", proc_fs_cifs);
775 	remove_proc_entry("open_files", proc_fs_cifs);
776 	remove_proc_entry("cifsFYI", proc_fs_cifs);
777 	remove_proc_entry("traceSMB", proc_fs_cifs);
778 	remove_proc_entry("Stats", proc_fs_cifs);
779 	remove_proc_entry("SecurityFlags", proc_fs_cifs);
780 	remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
781 	remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
782 	remove_proc_entry("mount_params", proc_fs_cifs);
783 
784 #ifdef CONFIG_CIFS_DFS_UPCALL
785 	remove_proc_entry("dfscache", proc_fs_cifs);
786 #endif
787 #ifdef CONFIG_CIFS_SMB_DIRECT
788 	remove_proc_entry("rdma_readwrite_threshold", proc_fs_cifs);
789 	remove_proc_entry("smbd_max_frmr_depth", proc_fs_cifs);
790 	remove_proc_entry("smbd_keep_alive_interval", proc_fs_cifs);
791 	remove_proc_entry("smbd_max_receive_size", proc_fs_cifs);
792 	remove_proc_entry("smbd_max_fragmented_recv_size", proc_fs_cifs);
793 	remove_proc_entry("smbd_max_send_size", proc_fs_cifs);
794 	remove_proc_entry("smbd_send_credit_target", proc_fs_cifs);
795 	remove_proc_entry("smbd_receive_credit_max", proc_fs_cifs);
796 #endif
797 	remove_proc_entry("fs/cifs", NULL);
798 }
799 
800 static int cifsFYI_proc_show(struct seq_file *m, void *v)
801 {
802 	seq_printf(m, "%d\n", cifsFYI);
803 	return 0;
804 }
805 
806 static int cifsFYI_proc_open(struct inode *inode, struct file *file)
807 {
808 	return single_open(file, cifsFYI_proc_show, NULL);
809 }
810 
811 static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
812 		size_t count, loff_t *ppos)
813 {
814 	char c[2] = { '\0' };
815 	bool bv;
816 	int rc;
817 
818 	rc = get_user(c[0], buffer);
819 	if (rc)
820 		return rc;
821 	if (kstrtobool(c, &bv) == 0)
822 		cifsFYI = bv;
823 	else if ((c[0] > '1') && (c[0] <= '9'))
824 		cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings */
825 	else
826 		return -EINVAL;
827 
828 	return count;
829 }
830 
831 static const struct proc_ops cifsFYI_proc_ops = {
832 	.proc_open	= cifsFYI_proc_open,
833 	.proc_read	= seq_read,
834 	.proc_lseek	= seq_lseek,
835 	.proc_release	= single_release,
836 	.proc_write	= cifsFYI_proc_write,
837 };
838 
839 static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
840 {
841 	seq_printf(m, "%d\n", linuxExtEnabled);
842 	return 0;
843 }
844 
845 static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file)
846 {
847 	return single_open(file, cifs_linux_ext_proc_show, NULL);
848 }
849 
850 static ssize_t cifs_linux_ext_proc_write(struct file *file,
851 		const char __user *buffer, size_t count, loff_t *ppos)
852 {
853 	int rc;
854 
855 	rc = kstrtobool_from_user(buffer, count, &linuxExtEnabled);
856 	if (rc)
857 		return rc;
858 
859 	return count;
860 }
861 
862 static const struct proc_ops cifs_linux_ext_proc_ops = {
863 	.proc_open	= cifs_linux_ext_proc_open,
864 	.proc_read	= seq_read,
865 	.proc_lseek	= seq_lseek,
866 	.proc_release	= single_release,
867 	.proc_write	= cifs_linux_ext_proc_write,
868 };
869 
870 static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v)
871 {
872 	seq_printf(m, "%d\n", lookupCacheEnabled);
873 	return 0;
874 }
875 
876 static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file)
877 {
878 	return single_open(file, cifs_lookup_cache_proc_show, NULL);
879 }
880 
881 static ssize_t cifs_lookup_cache_proc_write(struct file *file,
882 		const char __user *buffer, size_t count, loff_t *ppos)
883 {
884 	int rc;
885 
886 	rc = kstrtobool_from_user(buffer, count, &lookupCacheEnabled);
887 	if (rc)
888 		return rc;
889 
890 	return count;
891 }
892 
893 static const struct proc_ops cifs_lookup_cache_proc_ops = {
894 	.proc_open	= cifs_lookup_cache_proc_open,
895 	.proc_read	= seq_read,
896 	.proc_lseek	= seq_lseek,
897 	.proc_release	= single_release,
898 	.proc_write	= cifs_lookup_cache_proc_write,
899 };
900 
901 static int traceSMB_proc_show(struct seq_file *m, void *v)
902 {
903 	seq_printf(m, "%d\n", traceSMB);
904 	return 0;
905 }
906 
907 static int traceSMB_proc_open(struct inode *inode, struct file *file)
908 {
909 	return single_open(file, traceSMB_proc_show, NULL);
910 }
911 
912 static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer,
913 		size_t count, loff_t *ppos)
914 {
915 	int rc;
916 
917 	rc = kstrtobool_from_user(buffer, count, &traceSMB);
918 	if (rc)
919 		return rc;
920 
921 	return count;
922 }
923 
924 static const struct proc_ops traceSMB_proc_ops = {
925 	.proc_open	= traceSMB_proc_open,
926 	.proc_read	= seq_read,
927 	.proc_lseek	= seq_lseek,
928 	.proc_release	= single_release,
929 	.proc_write	= traceSMB_proc_write,
930 };
931 
932 static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
933 {
934 	seq_printf(m, "0x%x\n", global_secflags);
935 	return 0;
936 }
937 
938 static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
939 {
940 	return single_open(file, cifs_security_flags_proc_show, NULL);
941 }
942 
943 /*
944  * Ensure that if someone sets a MUST flag, that we disable all other MAY
945  * flags except for the ones corresponding to the given MUST flag. If there are
946  * multiple MUST flags, then try to prefer more secure ones.
947  */
948 static void
949 cifs_security_flags_handle_must_flags(unsigned int *flags)
950 {
951 	unsigned int signflags = *flags & CIFSSEC_MUST_SIGN;
952 
953 	if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
954 		*flags = CIFSSEC_MUST_KRB5;
955 	else if ((*flags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
956 		*flags = CIFSSEC_MUST_NTLMSSP;
957 	else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
958 		*flags = CIFSSEC_MUST_NTLMV2;
959 
960 	*flags |= signflags;
961 }
962 
963 static ssize_t cifs_security_flags_proc_write(struct file *file,
964 		const char __user *buffer, size_t count, loff_t *ppos)
965 {
966 	int rc;
967 	unsigned int flags;
968 	char flags_string[12];
969 	bool bv;
970 
971 	if ((count < 1) || (count > 11))
972 		return -EINVAL;
973 
974 	memset(flags_string, 0, 12);
975 
976 	if (copy_from_user(flags_string, buffer, count))
977 		return -EFAULT;
978 
979 	if (count < 3) {
980 		/* single char or single char followed by null */
981 		if (kstrtobool(flags_string, &bv) == 0) {
982 			global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF;
983 			return count;
984 		} else if (!isdigit(flags_string[0])) {
985 			cifs_dbg(VFS, "Invalid SecurityFlags: %s\n",
986 					flags_string);
987 			return -EINVAL;
988 		}
989 	}
990 
991 	/* else we have a number */
992 	rc = kstrtouint(flags_string, 0, &flags);
993 	if (rc) {
994 		cifs_dbg(VFS, "Invalid SecurityFlags: %s\n",
995 				flags_string);
996 		return rc;
997 	}
998 
999 	cifs_dbg(FYI, "sec flags 0x%x\n", flags);
1000 
1001 	if (flags == 0)  {
1002 		cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", flags_string);
1003 		return -EINVAL;
1004 	}
1005 
1006 	if (flags & ~CIFSSEC_MASK) {
1007 		cifs_dbg(VFS, "Unsupported security flags: 0x%x\n",
1008 			 flags & ~CIFSSEC_MASK);
1009 		return -EINVAL;
1010 	}
1011 
1012 	cifs_security_flags_handle_must_flags(&flags);
1013 
1014 	/* flags look ok - update the global security flags for cifs module */
1015 	global_secflags = flags;
1016 	if (global_secflags & CIFSSEC_MUST_SIGN) {
1017 		/* requiring signing implies signing is allowed */
1018 		global_secflags |= CIFSSEC_MAY_SIGN;
1019 		cifs_dbg(FYI, "packet signing now required\n");
1020 	} else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) {
1021 		cifs_dbg(FYI, "packet signing disabled\n");
1022 	}
1023 	/* BB should we turn on MAY flags for other MUST options? */
1024 	return count;
1025 }
1026 
1027 static const struct proc_ops cifs_security_flags_proc_ops = {
1028 	.proc_open	= cifs_security_flags_proc_open,
1029 	.proc_read	= seq_read,
1030 	.proc_lseek	= seq_lseek,
1031 	.proc_release	= single_release,
1032 	.proc_write	= cifs_security_flags_proc_write,
1033 };
1034 
1035 /* To make it easier to debug, can help to show mount params */
1036 static int cifs_mount_params_proc_show(struct seq_file *m, void *v)
1037 {
1038 	const struct fs_parameter_spec *p;
1039 	const char *type;
1040 
1041 	for (p = smb3_fs_parameters; p->name; p++) {
1042 		/* cannot use switch with pointers... */
1043 		if (!p->type) {
1044 			if (p->flags == fs_param_neg_with_no)
1045 				type = "noflag";
1046 			else
1047 				type = "flag";
1048 		} else if (p->type == fs_param_is_bool)
1049 			type = "bool";
1050 		else if (p->type == fs_param_is_u32)
1051 			type = "u32";
1052 		else if (p->type == fs_param_is_u64)
1053 			type = "u64";
1054 		else if (p->type == fs_param_is_string)
1055 			type = "string";
1056 		else
1057 			type = "unknown";
1058 
1059 		seq_printf(m, "%s:%s\n", p->name, type);
1060 	}
1061 
1062 	return 0;
1063 }
1064 
1065 static int cifs_mount_params_proc_open(struct inode *inode, struct file *file)
1066 {
1067 	return single_open(file, cifs_mount_params_proc_show, NULL);
1068 }
1069 
1070 static const struct proc_ops cifs_mount_params_proc_ops = {
1071 	.proc_open	= cifs_mount_params_proc_open,
1072 	.proc_read	= seq_read,
1073 	.proc_lseek	= seq_lseek,
1074 	.proc_release	= single_release,
1075 	/* No need for write for now */
1076 	/* .proc_write	= cifs_mount_params_proc_write, */
1077 };
1078 
1079 #else
1080 inline void cifs_proc_init(void)
1081 {
1082 }
1083 
1084 inline void cifs_proc_clean(void)
1085 {
1086 }
1087 #endif /* PROC_FS */
1088