1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) International Business Machines Corp., 2000,2005
7 * Modified by Steve French (sfrench@us.ibm.com)
10 #include <linux/string.h>
11 #include <linux/ctype.h>
12 #include <linux/module.h>
13 #include <linux/proc_fs.h>
14 #include <linux/uaccess.h>
17 #include "cifsproto.h"
18 #include "cifs_debug.h"
20 #ifdef CONFIG_CIFS_DFS_UPCALL
21 #include "dfs_cache.h"
23 #ifdef CONFIG_CIFS_SMB_DIRECT
24 #include "smbdirect.h"
26 #ifdef CONFIG_CIFS_SWN_UPCALL
31 cifs_dump_mem(char *label
, void *data
, int length
)
33 pr_debug("%s: dump of %d bytes of data at 0x%p\n", label
, length
, data
);
34 print_hex_dump(KERN_DEBUG
, "", DUMP_PREFIX_OFFSET
, 16, 4,
38 void cifs_dump_detail(void *buf
, struct TCP_Server_Info
*server
)
40 #ifdef CONFIG_CIFS_DEBUG2
41 struct smb_hdr
*smb
= (struct smb_hdr
*)buf
;
43 cifs_dbg(VFS
, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n",
44 smb
->Command
, smb
->Status
.CifsError
,
45 smb
->Flags
, smb
->Flags2
, smb
->Mid
, smb
->Pid
);
46 cifs_dbg(VFS
, "smb buf %p len %u\n", smb
,
47 server
->ops
->calc_smb_size(smb
, server
));
48 #endif /* CONFIG_CIFS_DEBUG2 */
51 void cifs_dump_mids(struct TCP_Server_Info
*server
)
53 #ifdef CONFIG_CIFS_DEBUG2
54 struct list_head
*tmp
;
55 struct mid_q_entry
*mid_entry
;
60 cifs_dbg(VFS
, "Dump pending requests:\n");
61 spin_lock(&GlobalMid_Lock
);
62 list_for_each(tmp
, &server
->pending_mid_q
) {
63 mid_entry
= list_entry(tmp
, struct mid_q_entry
, qhead
);
64 cifs_dbg(VFS
, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
66 le16_to_cpu(mid_entry
->command
),
68 mid_entry
->callback_data
,
70 #ifdef CONFIG_CIFS_STATS2
71 cifs_dbg(VFS
, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n",
74 mid_entry
->when_received
,
77 cifs_dbg(VFS
, "IsMult: %d IsEnd: %d\n",
78 mid_entry
->multiRsp
, mid_entry
->multiEnd
);
79 if (mid_entry
->resp_buf
) {
80 cifs_dump_detail(mid_entry
->resp_buf
, server
);
81 cifs_dump_mem("existing buf: ",
82 mid_entry
->resp_buf
, 62);
85 spin_unlock(&GlobalMid_Lock
);
86 #endif /* CONFIG_CIFS_DEBUG2 */
90 static void cifs_debug_tcon(struct seq_file
*m
, struct cifs_tcon
*tcon
)
92 __u32 dev_type
= le32_to_cpu(tcon
->fsDevInfo
.DeviceType
);
94 seq_printf(m
, "%s Mounts: %d ", tcon
->treeName
, tcon
->tc_count
);
95 if (tcon
->nativeFileSystem
)
96 seq_printf(m
, "Type: %s ", tcon
->nativeFileSystem
);
97 seq_printf(m
, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d",
98 le32_to_cpu(tcon
->fsDevInfo
.DeviceCharacteristics
),
99 le32_to_cpu(tcon
->fsAttrInfo
.Attributes
),
100 le32_to_cpu(tcon
->fsAttrInfo
.MaxPathNameComponentLength
),
102 if (dev_type
== FILE_DEVICE_DISK
)
103 seq_puts(m
, " type: DISK ");
104 else if (dev_type
== FILE_DEVICE_CD_ROM
)
105 seq_puts(m
, " type: CDROM ");
107 seq_printf(m
, " type: %d ", dev_type
);
109 seq_printf(m
, "Serial Number: 0x%x", tcon
->vol_serial_number
);
112 (tcon
->ses
->session_flags
& SMB2_SESSION_FLAG_ENCRYPT_DATA
) ||
113 (tcon
->share_flags
& SHI1005_FLAGS_ENCRYPT_DATA
))
114 seq_printf(m
, " Encrypted");
116 seq_printf(m
, " nocase");
118 seq_printf(m
, " POSIX Extensions");
119 if (tcon
->ses
->server
->ops
->dump_share_caps
)
120 tcon
->ses
->server
->ops
->dump_share_caps(m
, tcon
);
121 #ifdef CONFIG_CIFS_SWN_UPCALL
122 if (tcon
->use_witness
)
123 seq_puts(m
, " Witness");
126 if (tcon
->need_reconnect
)
127 seq_puts(m
, "\tDISCONNECTED ");
132 cifs_dump_channel(struct seq_file
*m
, int i
, struct cifs_chan
*chan
)
134 struct TCP_Server_Info
*server
= chan
->server
;
136 seq_printf(m
, "\t\tChannel %d Number of credits: %d Dialect 0x%x "
137 "TCP status: %d Instance: %d Local Users To Server: %d "
138 "SecMode: 0x%x Req On Wire: %d In Send: %d "
139 "In MaxReq Wait: %d\n",
144 server
->reconnect_instance
,
148 atomic_read(&server
->in_send
),
149 atomic_read(&server
->num_waiters
));
153 cifs_dump_iface(struct seq_file
*m
, struct cifs_server_iface
*iface
)
155 struct sockaddr_in
*ipv4
= (struct sockaddr_in
*)&iface
->sockaddr
;
156 struct sockaddr_in6
*ipv6
= (struct sockaddr_in6
*)&iface
->sockaddr
;
158 seq_printf(m
, "\tSpeed: %zu bps\n", iface
->speed
);
159 seq_puts(m
, "\t\tCapabilities: ");
160 if (iface
->rdma_capable
)
161 seq_puts(m
, "rdma ");
162 if (iface
->rss_capable
)
165 if (iface
->sockaddr
.ss_family
== AF_INET
)
166 seq_printf(m
, "\t\tIPv4: %pI4\n", &ipv4
->sin_addr
);
167 else if (iface
->sockaddr
.ss_family
== AF_INET6
)
168 seq_printf(m
, "\t\tIPv6: %pI6\n", &ipv6
->sin6_addr
);
171 static int cifs_debug_files_proc_show(struct seq_file
*m
, void *v
)
173 struct list_head
*stmp
, *tmp
, *tmp1
, *tmp2
;
174 struct TCP_Server_Info
*server
;
175 struct cifs_ses
*ses
;
176 struct cifs_tcon
*tcon
;
177 struct cifsFileInfo
*cfile
;
179 seq_puts(m
, "# Version:1\n");
180 seq_puts(m
, "# Format:\n");
181 seq_puts(m
, "# <tree id> <persistent fid> <flags> <count> <pid> <uid>");
182 #ifdef CONFIG_CIFS_DEBUG2
183 seq_printf(m
, " <filename> <mid>\n");
185 seq_printf(m
, " <filename>\n");
186 #endif /* CIFS_DEBUG2 */
187 spin_lock(&cifs_tcp_ses_lock
);
188 list_for_each(stmp
, &cifs_tcp_ses_list
) {
189 server
= list_entry(stmp
, struct TCP_Server_Info
,
191 list_for_each(tmp
, &server
->smb_ses_list
) {
192 ses
= list_entry(tmp
, struct cifs_ses
, smb_ses_list
);
193 list_for_each(tmp1
, &ses
->tcon_list
) {
194 tcon
= list_entry(tmp1
, struct cifs_tcon
, tcon_list
);
195 spin_lock(&tcon
->open_file_lock
);
196 list_for_each(tmp2
, &tcon
->openFileList
) {
197 cfile
= list_entry(tmp2
, struct cifsFileInfo
,
200 "0x%x 0x%llx 0x%x %d %d %d %s",
202 cfile
->fid
.persistent_fid
,
206 from_kuid(&init_user_ns
, cfile
->uid
),
207 cfile
->dentry
->d_name
.name
);
208 #ifdef CONFIG_CIFS_DEBUG2
209 seq_printf(m
, " 0x%llx\n", cfile
->fid
.mid
);
212 #endif /* CIFS_DEBUG2 */
214 spin_unlock(&tcon
->open_file_lock
);
218 spin_unlock(&cifs_tcp_ses_lock
);
223 static int cifs_debug_data_proc_show(struct seq_file
*m
, void *v
)
225 struct list_head
*tmp1
, *tmp2
, *tmp3
;
226 struct mid_q_entry
*mid_entry
;
227 struct TCP_Server_Info
*server
;
228 struct cifs_ses
*ses
;
229 struct cifs_tcon
*tcon
;
233 "Display Internal CIFS Data Structures for Debugging\n"
234 "---------------------------------------------------\n");
235 seq_printf(m
, "CIFS Version %s\n", CIFS_VERSION
);
236 seq_printf(m
, "Features:");
237 #ifdef CONFIG_CIFS_DFS_UPCALL
238 seq_printf(m
, " DFS");
240 #ifdef CONFIG_CIFS_FSCACHE
241 seq_printf(m
, ",FSCACHE");
243 #ifdef CONFIG_CIFS_SMB_DIRECT
244 seq_printf(m
, ",SMB_DIRECT");
246 #ifdef CONFIG_CIFS_STATS2
247 seq_printf(m
, ",STATS2");
249 seq_printf(m
, ",STATS");
251 #ifdef CONFIG_CIFS_DEBUG2
252 seq_printf(m
, ",DEBUG2");
253 #elif defined(CONFIG_CIFS_DEBUG)
254 seq_printf(m
, ",DEBUG");
256 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
257 seq_printf(m
, ",ALLOW_INSECURE_LEGACY");
259 #ifdef CONFIG_CIFS_WEAK_PW_HASH
260 seq_printf(m
, ",WEAK_PW_HASH");
262 #ifdef CONFIG_CIFS_POSIX
263 seq_printf(m
, ",CIFS_POSIX");
265 #ifdef CONFIG_CIFS_UPCALL
266 seq_printf(m
, ",UPCALL(SPNEGO)");
268 #ifdef CONFIG_CIFS_XATTR
269 seq_printf(m
, ",XATTR");
271 seq_printf(m
, ",ACL");
272 #ifdef CONFIG_CIFS_SWN_UPCALL
273 seq_puts(m
, ",WITNESS");
276 seq_printf(m
, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize
);
277 seq_printf(m
, "Active VFS Requests: %d\n", GlobalTotalActiveXid
);
278 seq_printf(m
, "Servers:");
281 spin_lock(&cifs_tcp_ses_lock
);
282 list_for_each(tmp1
, &cifs_tcp_ses_list
) {
283 server
= list_entry(tmp1
, struct TCP_Server_Info
,
286 #ifdef CONFIG_CIFS_SMB_DIRECT
290 if (!server
->smbd_conn
) {
291 seq_printf(m
, "\nSMBDirect transport not available");
295 seq_printf(m
, "\nSMBDirect (in hex) protocol version: %x "
296 "transport status: %x",
297 server
->smbd_conn
->protocol
,
298 server
->smbd_conn
->transport_status
);
299 seq_printf(m
, "\nConn receive_credit_max: %x "
300 "send_credit_target: %x max_send_size: %x",
301 server
->smbd_conn
->receive_credit_max
,
302 server
->smbd_conn
->send_credit_target
,
303 server
->smbd_conn
->max_send_size
);
304 seq_printf(m
, "\nConn max_fragmented_recv_size: %x "
305 "max_fragmented_send_size: %x max_receive_size:%x",
306 server
->smbd_conn
->max_fragmented_recv_size
,
307 server
->smbd_conn
->max_fragmented_send_size
,
308 server
->smbd_conn
->max_receive_size
);
309 seq_printf(m
, "\nConn keep_alive_interval: %x "
310 "max_readwrite_size: %x rdma_readwrite_threshold: %x",
311 server
->smbd_conn
->keep_alive_interval
,
312 server
->smbd_conn
->max_readwrite_size
,
313 server
->smbd_conn
->rdma_readwrite_threshold
);
314 seq_printf(m
, "\nDebug count_get_receive_buffer: %x "
315 "count_put_receive_buffer: %x count_send_empty: %x",
316 server
->smbd_conn
->count_get_receive_buffer
,
317 server
->smbd_conn
->count_put_receive_buffer
,
318 server
->smbd_conn
->count_send_empty
);
319 seq_printf(m
, "\nRead Queue count_reassembly_queue: %x "
320 "count_enqueue_reassembly_queue: %x "
321 "count_dequeue_reassembly_queue: %x "
322 "fragment_reassembly_remaining: %x "
323 "reassembly_data_length: %x "
324 "reassembly_queue_length: %x",
325 server
->smbd_conn
->count_reassembly_queue
,
326 server
->smbd_conn
->count_enqueue_reassembly_queue
,
327 server
->smbd_conn
->count_dequeue_reassembly_queue
,
328 server
->smbd_conn
->fragment_reassembly_remaining
,
329 server
->smbd_conn
->reassembly_data_length
,
330 server
->smbd_conn
->reassembly_queue_length
);
331 seq_printf(m
, "\nCurrent Credits send_credits: %x "
332 "receive_credits: %x receive_credit_target: %x",
333 atomic_read(&server
->smbd_conn
->send_credits
),
334 atomic_read(&server
->smbd_conn
->receive_credits
),
335 server
->smbd_conn
->receive_credit_target
);
336 seq_printf(m
, "\nPending send_pending: %x ",
337 atomic_read(&server
->smbd_conn
->send_pending
));
338 seq_printf(m
, "\nReceive buffers count_receive_queue: %x "
339 "count_empty_packet_queue: %x",
340 server
->smbd_conn
->count_receive_queue
,
341 server
->smbd_conn
->count_empty_packet_queue
);
342 seq_printf(m
, "\nMR responder_resources: %x "
343 "max_frmr_depth: %x mr_type: %x",
344 server
->smbd_conn
->responder_resources
,
345 server
->smbd_conn
->max_frmr_depth
,
346 server
->smbd_conn
->mr_type
);
347 seq_printf(m
, "\nMR mr_ready_count: %x mr_used_count: %x",
348 atomic_read(&server
->smbd_conn
->mr_ready_count
),
349 atomic_read(&server
->smbd_conn
->mr_used_count
));
352 seq_printf(m
, "\nNumber of credits: %d Dialect 0x%x",
353 server
->credits
, server
->dialect
);
354 if (server
->compress_algorithm
== SMB3_COMPRESS_LZNT1
)
355 seq_printf(m
, " COMPRESS_LZNT1");
356 else if (server
->compress_algorithm
== SMB3_COMPRESS_LZ77
)
357 seq_printf(m
, " COMPRESS_LZ77");
358 else if (server
->compress_algorithm
== SMB3_COMPRESS_LZ77_HUFF
)
359 seq_printf(m
, " COMPRESS_LZ77_HUFF");
361 seq_printf(m
, " signed");
362 if (server
->posix_ext_supported
)
363 seq_printf(m
, " posix");
366 list_for_each(tmp2
, &server
->smb_ses_list
) {
367 ses
= list_entry(tmp2
, struct cifs_ses
,
369 if ((ses
->serverDomain
== NULL
) ||
370 (ses
->serverOS
== NULL
) ||
371 (ses
->serverNOS
== NULL
)) {
372 seq_printf(m
, "\n%d) Name: %s Uses: %d Capability: 0x%x\tSession Status: %d ",
373 i
, ses
->serverName
, ses
->ses_count
,
374 ses
->capabilities
, ses
->status
);
375 if (ses
->session_flags
& SMB2_SESSION_FLAG_IS_GUEST
)
376 seq_printf(m
, "Guest\t");
377 else if (ses
->session_flags
& SMB2_SESSION_FLAG_IS_NULL
)
378 seq_printf(m
, "Anonymous\t");
381 "\n%d) Name: %s Domain: %s Uses: %d OS:"
382 " %s\n\tNOS: %s\tCapability: 0x%x\n\tSMB"
383 " session status: %d ",
384 i
, ses
->serverName
, ses
->serverDomain
,
385 ses
->ses_count
, ses
->serverOS
, ses
->serverNOS
,
386 ses
->capabilities
, ses
->status
);
389 seq_printf(m
,"Security type: %s\n",
390 get_security_type_str(server
->ops
->select_sectype(server
, ses
->sectype
)));
393 seq_printf(m
, "RDMA\n\t");
394 seq_printf(m
, "TCP status: %d Instance: %d\n\tLocal Users To "
395 "Server: %d SecMode: 0x%x Req On Wire: %d",
397 server
->reconnect_instance
,
399 server
->sec_mode
, in_flight(server
));
401 seq_printf(m
, " In Send: %d In MaxReq Wait: %d",
402 atomic_read(&server
->in_send
),
403 atomic_read(&server
->num_waiters
));
405 /* dump session id helpful for use with network trace */
406 seq_printf(m
, " SessionId: 0x%llx", ses
->Suid
);
407 if (ses
->session_flags
& SMB2_SESSION_FLAG_ENCRYPT_DATA
)
408 seq_puts(m
, " encrypted");
410 seq_puts(m
, " signed");
412 seq_printf(m
, "\n\tUser: %d Cred User: %d",
413 from_kuid(&init_user_ns
, ses
->linux_uid
),
414 from_kuid(&init_user_ns
, ses
->cred_uid
));
416 if (ses
->chan_count
> 1) {
417 seq_printf(m
, "\n\n\tExtra Channels: %zu\n",
419 for (j
= 1; j
< ses
->chan_count
; j
++)
420 cifs_dump_channel(m
, j
, &ses
->chans
[j
]);
423 seq_puts(m
, "\n\n\tShares:");
426 seq_printf(m
, "\n\t%d) IPC: ", j
);
428 cifs_debug_tcon(m
, ses
->tcon_ipc
);
430 seq_puts(m
, "none\n");
432 list_for_each(tmp3
, &ses
->tcon_list
) {
433 tcon
= list_entry(tmp3
, struct cifs_tcon
,
436 seq_printf(m
, "\n\t%d) ", j
);
437 cifs_debug_tcon(m
, tcon
);
440 seq_puts(m
, "\n\tMIDs:\n");
442 spin_lock(&GlobalMid_Lock
);
443 list_for_each(tmp3
, &server
->pending_mid_q
) {
444 mid_entry
= list_entry(tmp3
, struct mid_q_entry
,
446 seq_printf(m
, "\tState: %d com: %d pid:"
447 " %d cbdata: %p mid %llu\n",
448 mid_entry
->mid_state
,
449 le16_to_cpu(mid_entry
->command
),
451 mid_entry
->callback_data
,
454 spin_unlock(&GlobalMid_Lock
);
456 spin_lock(&ses
->iface_lock
);
457 if (ses
->iface_count
)
458 seq_printf(m
, "\n\tServer interfaces: %zu\n",
460 for (j
= 0; j
< ses
->iface_count
; j
++) {
461 struct cifs_server_iface
*iface
;
463 iface
= &ses
->iface_list
[j
];
464 seq_printf(m
, "\t%d)", j
);
465 cifs_dump_iface(m
, iface
);
466 if (is_ses_using_iface(ses
, iface
))
467 seq_puts(m
, "\t\t[CONNECTED]\n");
469 spin_unlock(&ses
->iface_lock
);
472 spin_unlock(&cifs_tcp_ses_lock
);
475 #ifdef CONFIG_CIFS_SWN_UPCALL
478 /* BB add code to dump additional info such as TCP session info now */
482 static ssize_t
cifs_stats_proc_write(struct file
*file
,
483 const char __user
*buffer
, size_t count
, loff_t
*ppos
)
487 struct list_head
*tmp1
, *tmp2
, *tmp3
;
488 struct TCP_Server_Info
*server
;
489 struct cifs_ses
*ses
;
490 struct cifs_tcon
*tcon
;
492 rc
= kstrtobool_from_user(buffer
, count
, &bv
);
494 #ifdef CONFIG_CIFS_STATS2
497 atomic_set(&totBufAllocCount
, 0);
498 atomic_set(&totSmBufAllocCount
, 0);
499 #endif /* CONFIG_CIFS_STATS2 */
500 atomic_set(&tcpSesReconnectCount
, 0);
501 atomic_set(&tconInfoReconnectCount
, 0);
503 spin_lock(&GlobalMid_Lock
);
504 GlobalMaxActiveXid
= 0;
505 GlobalCurrentXid
= 0;
506 spin_unlock(&GlobalMid_Lock
);
507 spin_lock(&cifs_tcp_ses_lock
);
508 list_for_each(tmp1
, &cifs_tcp_ses_list
) {
509 server
= list_entry(tmp1
, struct TCP_Server_Info
,
511 server
->max_in_flight
= 0;
512 #ifdef CONFIG_CIFS_STATS2
513 for (i
= 0; i
< NUMBER_OF_SMB2_COMMANDS
; i
++) {
514 atomic_set(&server
->num_cmds
[i
], 0);
515 atomic_set(&server
->smb2slowcmd
[i
], 0);
516 server
->time_per_cmd
[i
] = 0;
517 server
->slowest_cmd
[i
] = 0;
518 server
->fastest_cmd
[0] = 0;
520 #endif /* CONFIG_CIFS_STATS2 */
521 list_for_each(tmp2
, &server
->smb_ses_list
) {
522 ses
= list_entry(tmp2
, struct cifs_ses
,
524 list_for_each(tmp3
, &ses
->tcon_list
) {
525 tcon
= list_entry(tmp3
,
528 atomic_set(&tcon
->num_smbs_sent
, 0);
529 spin_lock(&tcon
->stat_lock
);
530 tcon
->bytes_read
= 0;
531 tcon
->bytes_written
= 0;
532 spin_unlock(&tcon
->stat_lock
);
533 if (server
->ops
->clear_stats
)
534 server
->ops
->clear_stats(tcon
);
538 spin_unlock(&cifs_tcp_ses_lock
);
546 static int cifs_stats_proc_show(struct seq_file
*m
, void *v
)
549 #ifdef CONFIG_CIFS_STATS2
552 struct list_head
*tmp1
, *tmp2
, *tmp3
;
553 struct TCP_Server_Info
*server
;
554 struct cifs_ses
*ses
;
555 struct cifs_tcon
*tcon
;
557 seq_printf(m
, "Resources in use\nCIFS Session: %d\n",
558 sesInfoAllocCount
.counter
);
559 seq_printf(m
, "Share (unique mount targets): %d\n",
560 tconInfoAllocCount
.counter
);
561 seq_printf(m
, "SMB Request/Response Buffer: %d Pool size: %d\n",
562 bufAllocCount
.counter
,
563 cifs_min_rcv
+ tcpSesAllocCount
.counter
);
564 seq_printf(m
, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
565 smBufAllocCount
.counter
, cifs_min_small
);
566 #ifdef CONFIG_CIFS_STATS2
567 seq_printf(m
, "Total Large %d Small %d Allocations\n",
568 atomic_read(&totBufAllocCount
),
569 atomic_read(&totSmBufAllocCount
));
570 #endif /* CONFIG_CIFS_STATS2 */
572 seq_printf(m
, "Operations (MIDs): %d\n", atomic_read(&midCount
));
574 "\n%d session %d share reconnects\n",
575 tcpSesReconnectCount
.counter
, tconInfoReconnectCount
.counter
);
578 "Total vfs operations: %d maximum at one time: %d\n",
579 GlobalCurrentXid
, GlobalMaxActiveXid
);
582 spin_lock(&cifs_tcp_ses_lock
);
583 list_for_each(tmp1
, &cifs_tcp_ses_list
) {
584 server
= list_entry(tmp1
, struct TCP_Server_Info
,
586 seq_printf(m
, "\nMax requests in flight: %d", server
->max_in_flight
);
587 #ifdef CONFIG_CIFS_STATS2
588 seq_puts(m
, "\nTotal time spent processing by command. Time ");
589 seq_printf(m
, "units are jiffies (%d per second)\n", HZ
);
590 seq_puts(m
, " SMB3 CMD\tNumber\tTotal Time\tFastest\tSlowest\n");
591 seq_puts(m
, " --------\t------\t----------\t-------\t-------\n");
592 for (j
= 0; j
< NUMBER_OF_SMB2_COMMANDS
; j
++)
593 seq_printf(m
, " %d\t\t%d\t%llu\t\t%u\t%u\n", j
,
594 atomic_read(&server
->num_cmds
[j
]),
595 server
->time_per_cmd
[j
],
596 server
->fastest_cmd
[j
],
597 server
->slowest_cmd
[j
]);
598 for (j
= 0; j
< NUMBER_OF_SMB2_COMMANDS
; j
++)
599 if (atomic_read(&server
->smb2slowcmd
[j
]))
600 seq_printf(m
, " %d slow responses from %s for command %d\n",
601 atomic_read(&server
->smb2slowcmd
[j
]),
602 server
->hostname
, j
);
604 list_for_each(tmp2
, &server
->smb_ses_list
) {
605 ses
= list_entry(tmp2
, struct cifs_ses
,
607 list_for_each(tmp3
, &ses
->tcon_list
) {
608 tcon
= list_entry(tmp3
,
612 seq_printf(m
, "\n%d) %s", i
, tcon
->treeName
);
613 if (tcon
->need_reconnect
)
614 seq_puts(m
, "\tDISCONNECTED ");
615 seq_printf(m
, "\nSMBs: %d",
616 atomic_read(&tcon
->num_smbs_sent
));
617 if (server
->ops
->print_stats
)
618 server
->ops
->print_stats(m
, tcon
);
622 spin_unlock(&cifs_tcp_ses_lock
);
628 static int cifs_stats_proc_open(struct inode
*inode
, struct file
*file
)
630 return single_open(file
, cifs_stats_proc_show
, NULL
);
633 static const struct proc_ops cifs_stats_proc_ops
= {
634 .proc_open
= cifs_stats_proc_open
,
635 .proc_read
= seq_read
,
636 .proc_lseek
= seq_lseek
,
637 .proc_release
= single_release
,
638 .proc_write
= cifs_stats_proc_write
,
641 #ifdef CONFIG_CIFS_SMB_DIRECT
642 #define PROC_FILE_DEFINE(name) \
643 static ssize_t name##_write(struct file *file, const char __user *buffer, \
644 size_t count, loff_t *ppos) \
647 rc = kstrtoint_from_user(buffer, count, 10, & name); \
652 static int name##_proc_show(struct seq_file *m, void *v) \
654 seq_printf(m, "%d\n", name ); \
657 static int name##_open(struct inode *inode, struct file *file) \
659 return single_open(file, name##_proc_show, NULL); \
662 static const struct proc_ops cifs_##name##_proc_fops = { \
663 .proc_open = name##_open, \
664 .proc_read = seq_read, \
665 .proc_lseek = seq_lseek, \
666 .proc_release = single_release, \
667 .proc_write = name##_write, \
670 PROC_FILE_DEFINE(rdma_readwrite_threshold
);
671 PROC_FILE_DEFINE(smbd_max_frmr_depth
);
672 PROC_FILE_DEFINE(smbd_keep_alive_interval
);
673 PROC_FILE_DEFINE(smbd_max_receive_size
);
674 PROC_FILE_DEFINE(smbd_max_fragmented_recv_size
);
675 PROC_FILE_DEFINE(smbd_max_send_size
);
676 PROC_FILE_DEFINE(smbd_send_credit_target
);
677 PROC_FILE_DEFINE(smbd_receive_credit_max
);
680 static struct proc_dir_entry
*proc_fs_cifs
;
681 static const struct proc_ops cifsFYI_proc_ops
;
682 static const struct proc_ops cifs_lookup_cache_proc_ops
;
683 static const struct proc_ops traceSMB_proc_ops
;
684 static const struct proc_ops cifs_security_flags_proc_ops
;
685 static const struct proc_ops cifs_linux_ext_proc_ops
;
690 proc_fs_cifs
= proc_mkdir("fs/cifs", NULL
);
691 if (proc_fs_cifs
== NULL
)
694 proc_create_single("DebugData", 0, proc_fs_cifs
,
695 cifs_debug_data_proc_show
);
697 proc_create_single("open_files", 0400, proc_fs_cifs
,
698 cifs_debug_files_proc_show
);
700 proc_create("Stats", 0644, proc_fs_cifs
, &cifs_stats_proc_ops
);
701 proc_create("cifsFYI", 0644, proc_fs_cifs
, &cifsFYI_proc_ops
);
702 proc_create("traceSMB", 0644, proc_fs_cifs
, &traceSMB_proc_ops
);
703 proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs
,
704 &cifs_linux_ext_proc_ops
);
705 proc_create("SecurityFlags", 0644, proc_fs_cifs
,
706 &cifs_security_flags_proc_ops
);
707 proc_create("LookupCacheEnabled", 0644, proc_fs_cifs
,
708 &cifs_lookup_cache_proc_ops
);
710 #ifdef CONFIG_CIFS_DFS_UPCALL
711 proc_create("dfscache", 0644, proc_fs_cifs
, &dfscache_proc_ops
);
714 #ifdef CONFIG_CIFS_SMB_DIRECT
715 proc_create("rdma_readwrite_threshold", 0644, proc_fs_cifs
,
716 &cifs_rdma_readwrite_threshold_proc_fops
);
717 proc_create("smbd_max_frmr_depth", 0644, proc_fs_cifs
,
718 &cifs_smbd_max_frmr_depth_proc_fops
);
719 proc_create("smbd_keep_alive_interval", 0644, proc_fs_cifs
,
720 &cifs_smbd_keep_alive_interval_proc_fops
);
721 proc_create("smbd_max_receive_size", 0644, proc_fs_cifs
,
722 &cifs_smbd_max_receive_size_proc_fops
);
723 proc_create("smbd_max_fragmented_recv_size", 0644, proc_fs_cifs
,
724 &cifs_smbd_max_fragmented_recv_size_proc_fops
);
725 proc_create("smbd_max_send_size", 0644, proc_fs_cifs
,
726 &cifs_smbd_max_send_size_proc_fops
);
727 proc_create("smbd_send_credit_target", 0644, proc_fs_cifs
,
728 &cifs_smbd_send_credit_target_proc_fops
);
729 proc_create("smbd_receive_credit_max", 0644, proc_fs_cifs
,
730 &cifs_smbd_receive_credit_max_proc_fops
);
735 cifs_proc_clean(void)
737 if (proc_fs_cifs
== NULL
)
740 remove_proc_entry("DebugData", proc_fs_cifs
);
741 remove_proc_entry("open_files", proc_fs_cifs
);
742 remove_proc_entry("cifsFYI", proc_fs_cifs
);
743 remove_proc_entry("traceSMB", proc_fs_cifs
);
744 remove_proc_entry("Stats", proc_fs_cifs
);
745 remove_proc_entry("SecurityFlags", proc_fs_cifs
);
746 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs
);
747 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs
);
749 #ifdef CONFIG_CIFS_DFS_UPCALL
750 remove_proc_entry("dfscache", proc_fs_cifs
);
752 #ifdef CONFIG_CIFS_SMB_DIRECT
753 remove_proc_entry("rdma_readwrite_threshold", proc_fs_cifs
);
754 remove_proc_entry("smbd_max_frmr_depth", proc_fs_cifs
);
755 remove_proc_entry("smbd_keep_alive_interval", proc_fs_cifs
);
756 remove_proc_entry("smbd_max_receive_size", proc_fs_cifs
);
757 remove_proc_entry("smbd_max_fragmented_recv_size", proc_fs_cifs
);
758 remove_proc_entry("smbd_max_send_size", proc_fs_cifs
);
759 remove_proc_entry("smbd_send_credit_target", proc_fs_cifs
);
760 remove_proc_entry("smbd_receive_credit_max", proc_fs_cifs
);
762 remove_proc_entry("fs/cifs", NULL
);
765 static int cifsFYI_proc_show(struct seq_file
*m
, void *v
)
767 seq_printf(m
, "%d\n", cifsFYI
);
771 static int cifsFYI_proc_open(struct inode
*inode
, struct file
*file
)
773 return single_open(file
, cifsFYI_proc_show
, NULL
);
776 static ssize_t
cifsFYI_proc_write(struct file
*file
, const char __user
*buffer
,
777 size_t count
, loff_t
*ppos
)
779 char c
[2] = { '\0' };
783 rc
= get_user(c
[0], buffer
);
786 if (strtobool(c
, &bv
) == 0)
788 else if ((c
[0] > '1') && (c
[0] <= '9'))
789 cifsFYI
= (int) (c
[0] - '0'); /* see cifs_debug.h for meanings */
796 static const struct proc_ops cifsFYI_proc_ops
= {
797 .proc_open
= cifsFYI_proc_open
,
798 .proc_read
= seq_read
,
799 .proc_lseek
= seq_lseek
,
800 .proc_release
= single_release
,
801 .proc_write
= cifsFYI_proc_write
,
804 static int cifs_linux_ext_proc_show(struct seq_file
*m
, void *v
)
806 seq_printf(m
, "%d\n", linuxExtEnabled
);
810 static int cifs_linux_ext_proc_open(struct inode
*inode
, struct file
*file
)
812 return single_open(file
, cifs_linux_ext_proc_show
, NULL
);
815 static ssize_t
cifs_linux_ext_proc_write(struct file
*file
,
816 const char __user
*buffer
, size_t count
, loff_t
*ppos
)
820 rc
= kstrtobool_from_user(buffer
, count
, &linuxExtEnabled
);
827 static const struct proc_ops cifs_linux_ext_proc_ops
= {
828 .proc_open
= cifs_linux_ext_proc_open
,
829 .proc_read
= seq_read
,
830 .proc_lseek
= seq_lseek
,
831 .proc_release
= single_release
,
832 .proc_write
= cifs_linux_ext_proc_write
,
835 static int cifs_lookup_cache_proc_show(struct seq_file
*m
, void *v
)
837 seq_printf(m
, "%d\n", lookupCacheEnabled
);
841 static int cifs_lookup_cache_proc_open(struct inode
*inode
, struct file
*file
)
843 return single_open(file
, cifs_lookup_cache_proc_show
, NULL
);
846 static ssize_t
cifs_lookup_cache_proc_write(struct file
*file
,
847 const char __user
*buffer
, size_t count
, loff_t
*ppos
)
851 rc
= kstrtobool_from_user(buffer
, count
, &lookupCacheEnabled
);
858 static const struct proc_ops cifs_lookup_cache_proc_ops
= {
859 .proc_open
= cifs_lookup_cache_proc_open
,
860 .proc_read
= seq_read
,
861 .proc_lseek
= seq_lseek
,
862 .proc_release
= single_release
,
863 .proc_write
= cifs_lookup_cache_proc_write
,
866 static int traceSMB_proc_show(struct seq_file
*m
, void *v
)
868 seq_printf(m
, "%d\n", traceSMB
);
872 static int traceSMB_proc_open(struct inode
*inode
, struct file
*file
)
874 return single_open(file
, traceSMB_proc_show
, NULL
);
877 static ssize_t
traceSMB_proc_write(struct file
*file
, const char __user
*buffer
,
878 size_t count
, loff_t
*ppos
)
882 rc
= kstrtobool_from_user(buffer
, count
, &traceSMB
);
889 static const struct proc_ops traceSMB_proc_ops
= {
890 .proc_open
= traceSMB_proc_open
,
891 .proc_read
= seq_read
,
892 .proc_lseek
= seq_lseek
,
893 .proc_release
= single_release
,
894 .proc_write
= traceSMB_proc_write
,
897 static int cifs_security_flags_proc_show(struct seq_file
*m
, void *v
)
899 seq_printf(m
, "0x%x\n", global_secflags
);
903 static int cifs_security_flags_proc_open(struct inode
*inode
, struct file
*file
)
905 return single_open(file
, cifs_security_flags_proc_show
, NULL
);
909 * Ensure that if someone sets a MUST flag, that we disable all other MAY
910 * flags except for the ones corresponding to the given MUST flag. If there are
911 * multiple MUST flags, then try to prefer more secure ones.
914 cifs_security_flags_handle_must_flags(unsigned int *flags
)
916 unsigned int signflags
= *flags
& CIFSSEC_MUST_SIGN
;
918 if ((*flags
& CIFSSEC_MUST_KRB5
) == CIFSSEC_MUST_KRB5
)
919 *flags
= CIFSSEC_MUST_KRB5
;
920 else if ((*flags
& CIFSSEC_MUST_NTLMSSP
) == CIFSSEC_MUST_NTLMSSP
)
921 *flags
= CIFSSEC_MUST_NTLMSSP
;
922 else if ((*flags
& CIFSSEC_MUST_NTLMV2
) == CIFSSEC_MUST_NTLMV2
)
923 *flags
= CIFSSEC_MUST_NTLMV2
;
924 else if ((*flags
& CIFSSEC_MUST_NTLM
) == CIFSSEC_MUST_NTLM
)
925 *flags
= CIFSSEC_MUST_NTLM
;
926 else if (CIFSSEC_MUST_LANMAN
&&
927 (*flags
& CIFSSEC_MUST_LANMAN
) == CIFSSEC_MUST_LANMAN
)
928 *flags
= CIFSSEC_MUST_LANMAN
;
929 else if (CIFSSEC_MUST_PLNTXT
&&
930 (*flags
& CIFSSEC_MUST_PLNTXT
) == CIFSSEC_MUST_PLNTXT
)
931 *flags
= CIFSSEC_MUST_PLNTXT
;
936 static ssize_t
cifs_security_flags_proc_write(struct file
*file
,
937 const char __user
*buffer
, size_t count
, loff_t
*ppos
)
941 char flags_string
[12];
944 if ((count
< 1) || (count
> 11))
947 memset(flags_string
, 0, 12);
949 if (copy_from_user(flags_string
, buffer
, count
))
953 /* single char or single char followed by null */
954 if (strtobool(flags_string
, &bv
) == 0) {
955 global_secflags
= bv
? CIFSSEC_MAX
: CIFSSEC_DEF
;
957 } else if (!isdigit(flags_string
[0])) {
958 cifs_dbg(VFS
, "Invalid SecurityFlags: %s\n",
964 /* else we have a number */
965 rc
= kstrtouint(flags_string
, 0, &flags
);
967 cifs_dbg(VFS
, "Invalid SecurityFlags: %s\n",
972 cifs_dbg(FYI
, "sec flags 0x%x\n", flags
);
975 cifs_dbg(VFS
, "Invalid SecurityFlags: %s\n", flags_string
);
979 if (flags
& ~CIFSSEC_MASK
) {
980 cifs_dbg(VFS
, "Unsupported security flags: 0x%x\n",
981 flags
& ~CIFSSEC_MASK
);
985 cifs_security_flags_handle_must_flags(&flags
);
987 /* flags look ok - update the global security flags for cifs module */
988 global_secflags
= flags
;
989 if (global_secflags
& CIFSSEC_MUST_SIGN
) {
990 /* requiring signing implies signing is allowed */
991 global_secflags
|= CIFSSEC_MAY_SIGN
;
992 cifs_dbg(FYI
, "packet signing now required\n");
993 } else if ((global_secflags
& CIFSSEC_MAY_SIGN
) == 0) {
994 cifs_dbg(FYI
, "packet signing disabled\n");
996 /* BB should we turn on MAY flags for other MUST options? */
1000 static const struct proc_ops cifs_security_flags_proc_ops
= {
1001 .proc_open
= cifs_security_flags_proc_open
,
1002 .proc_read
= seq_read
,
1003 .proc_lseek
= seq_lseek
,
1004 .proc_release
= single_release
,
1005 .proc_write
= cifs_security_flags_proc_write
,
1008 inline void cifs_proc_init(void)
1012 inline void cifs_proc_clean(void)
1015 #endif /* PROC_FS */