cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cifs_debug.c (31667B)


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