2005-04-17 02:20:36 +04:00
/*
* fs / cifs_debug . c
*
2005-04-29 09:41:07 +04:00
* Copyright ( C ) International Business Machines Corp . , 2000 , 2005
2005-04-17 02:20:36 +04:00
*
* Modified by Steve French ( sfrench @ us . ibm . com )
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2007-06-06 00:35:06 +04:00
* the Free Software Foundation ; either version 2 of the License , or
2005-04-17 02:20:36 +04:00
* ( at your option ) any later version .
2007-06-06 00:35:06 +04:00
*
2005-04-17 02:20:36 +04:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See
* the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2007-06-06 00:35:06 +04:00
* along with this program ; if not , write to the Free Software
2005-04-17 02:20:36 +04:00
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <linux/fs.h>
# include <linux/string.h>
# include <linux/ctype.h>
# include <linux/module.h>
# include <linux/proc_fs.h>
2016-12-24 22:46:01 +03:00
# include <linux/uaccess.h>
2005-04-17 02:20:36 +04:00
# include "cifspdu.h"
# include "cifsglob.h"
# include "cifsproto.h"
# include "cifs_debug.h"
2005-04-29 09:41:06 +04:00
# include "cifsfs.h"
2018-11-14 21:01:21 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
# include "dfs_cache.h"
# endif
2017-11-07 11:54:58 +03:00
# ifdef CONFIG_CIFS_SMB_DIRECT
# include "smbdirect.h"
# endif
2005-04-17 02:20:36 +04:00
void
cifs_dump_mem ( char * label , void * data , int length )
{
2014-08-27 17:49:44 +04:00
pr_debug ( " %s: dump of %d bytes of data at 0x%p \n " , label , length , data ) ;
2014-08-27 17:49:43 +04:00
print_hex_dump ( KERN_DEBUG , " " , DUMP_PREFIX_OFFSET , 16 , 4 ,
data , length , true ) ;
2005-04-17 02:20:36 +04:00
}
2018-04-22 23:45:53 +03:00
void cifs_dump_detail ( void * buf , struct TCP_Server_Info * server )
2006-06-01 02:40:51 +04:00
{
2012-05-17 13:25:35 +04:00
# ifdef CONFIG_CIFS_DEBUG2
2012-03-23 22:28:02 +04:00
struct smb_hdr * smb = ( struct smb_hdr * ) buf ;
2013-05-05 07:12:25 +04:00
cifs_dbg ( VFS , " Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d \n " ,
smb - > Command , smb - > Status . CifsError ,
smb - > Flags , smb - > Flags2 , smb - > Mid , smb - > Pid ) ;
2018-04-22 23:45:53 +03:00
cifs_dbg ( VFS , " smb buf %p len %u \n " , smb ,
2018-05-06 23:58:51 +03:00
server - > ops - > calc_smb_size ( smb , server ) ) ;
2012-05-17 13:25:35 +04:00
# endif /* CONFIG_CIFS_DEBUG2 */
2006-06-01 02:40:51 +04:00
}
2007-06-25 01:15:44 +04:00
void cifs_dump_mids ( struct TCP_Server_Info * server )
2006-06-01 02:40:51 +04:00
{
2012-05-17 13:25:35 +04:00
# ifdef CONFIG_CIFS_DEBUG2
2006-06-01 02:40:51 +04:00
struct list_head * tmp ;
2007-06-25 01:15:44 +04:00
struct mid_q_entry * mid_entry ;
2006-06-01 02:40:51 +04:00
2007-06-06 00:35:06 +04:00
if ( server = = NULL )
2006-06-01 02:40:51 +04:00
return ;
2013-05-05 07:12:25 +04:00
cifs_dbg ( VFS , " Dump pending requests: \n " ) ;
2006-06-01 02:40:51 +04:00
spin_lock ( & GlobalMid_Lock ) ;
list_for_each ( tmp , & server - > pending_mid_q ) {
mid_entry = list_entry ( tmp , struct mid_q_entry , qhead ) ;
2013-05-05 07:12:25 +04:00
cifs_dbg ( VFS , " State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu \n " ,
mid_entry - > mid_state ,
le16_to_cpu ( mid_entry - > command ) ,
mid_entry - > pid ,
mid_entry - > callback_data ,
mid_entry - > mid ) ;
2006-06-01 02:40:51 +04:00
# ifdef CONFIG_CIFS_STATS2
2013-05-05 07:12:25 +04:00
cifs_dbg ( VFS , " IsLarge: %d buf: %p time rcv: %ld now: %ld \n " ,
mid_entry - > large_buf ,
mid_entry - > resp_buf ,
mid_entry - > when_received ,
jiffies ) ;
2006-06-01 02:40:51 +04:00
# endif /* STATS2 */
2013-05-05 07:12:25 +04:00
cifs_dbg ( VFS , " IsMult: %d IsEnd: %d \n " ,
mid_entry - > multiRsp , mid_entry - > multiEnd ) ;
2008-08-09 01:10:16 +04:00
if ( mid_entry - > resp_buf ) {
2018-05-06 23:58:51 +03:00
cifs_dump_detail ( mid_entry - > resp_buf , server ) ;
2008-08-09 01:10:16 +04:00
cifs_dump_mem ( " existing buf: " ,
mid_entry - > resp_buf , 62 ) ;
2006-06-01 02:40:51 +04:00
}
}
spin_unlock ( & GlobalMid_Lock ) ;
# endif /* CONFIG_CIFS_DEBUG2 */
2012-05-17 13:25:35 +04:00
}
2006-06-01 02:40:51 +04:00
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_PROC_FS
2018-01-24 15:46:12 +03:00
static void cifs_debug_tcon ( struct seq_file * m , struct cifs_tcon * tcon )
{
__u32 dev_type = le32_to_cpu ( tcon - > fsDevInfo . DeviceType ) ;
seq_printf ( m , " %s Mounts: %d " , tcon - > treeName , tcon - > tc_count ) ;
if ( tcon - > nativeFileSystem )
seq_printf ( m , " Type: %s " , tcon - > nativeFileSystem ) ;
seq_printf ( m , " DevInfo: 0x%x Attributes: 0x%x \n \t PathComponentMax: %d Status: %d " ,
le32_to_cpu ( tcon - > fsDevInfo . DeviceCharacteristics ) ,
le32_to_cpu ( tcon - > fsAttrInfo . Attributes ) ,
le32_to_cpu ( tcon - > fsAttrInfo . MaxPathNameComponentLength ) ,
tcon - > tidStatus ) ;
if ( dev_type = = FILE_DEVICE_DISK )
seq_puts ( m , " type: DISK " ) ;
else if ( dev_type = = FILE_DEVICE_CD_ROM )
seq_puts ( m , " type: CDROM " ) ;
else
seq_printf ( m , " type: %d " , dev_type ) ;
2019-03-12 09:29:03 +03:00
seq_printf ( m , " Serial Number: 0x%x " , tcon - > vol_serial_number ) ;
2019-03-10 03:12:18 +03:00
if ( ( tcon - > seal ) | |
( tcon - > ses - > session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA ) | |
( tcon - > share_flags & SHI1005_FLAGS_ENCRYPT_DATA ) )
2018-01-31 23:34:37 +03:00
seq_printf ( m , " Encrypted " ) ;
2018-05-31 01:11:55 +03:00
if ( tcon - > nocase )
seq_printf ( m , " nocase " ) ;
2018-01-31 23:34:37 +03:00
if ( tcon - > unix_ext )
seq_printf ( m , " POSIX Extensions " ) ;
2018-01-24 15:46:12 +03:00
if ( tcon - > ses - > server - > ops - > dump_share_caps )
tcon - > ses - > server - > ops - > dump_share_caps ( m , tcon ) ;
if ( tcon - > need_reconnect )
seq_puts ( m , " \t DISCONNECTED " ) ;
seq_putc ( m , ' \n ' ) ;
}
2018-06-14 16:43:20 +03:00
static void
cifs_dump_iface ( struct seq_file * m , struct cifs_server_iface * iface )
{
struct sockaddr_in * ipv4 = ( struct sockaddr_in * ) & iface - > sockaddr ;
struct sockaddr_in6 * ipv6 = ( struct sockaddr_in6 * ) & iface - > sockaddr ;
2018-10-20 05:21:37 +03:00
seq_printf ( m , " \t Speed: %zu bps \n " , iface - > speed ) ;
2018-06-14 16:43:20 +03:00
seq_puts ( m , " \t \t Capabilities: " ) ;
if ( iface - > rdma_capable )
seq_puts ( m , " rdma " ) ;
if ( iface - > rss_capable )
seq_puts ( m , " rss " ) ;
seq_putc ( m , ' \n ' ) ;
if ( iface - > sockaddr . ss_family = = AF_INET )
seq_printf ( m , " \t \t IPv4: %pI4 \n " , & ipv4 - > sin_addr ) ;
else if ( iface - > sockaddr . ss_family = = AF_INET6 )
seq_printf ( m , " \t \t IPv6: %pI6 \n " , & ipv6 - > sin6_addr ) ;
}
2018-10-31 03:50:31 +03:00
static int cifs_debug_files_proc_show ( struct seq_file * m , void * v )
{
struct list_head * stmp , * tmp , * tmp1 , * tmp2 ;
struct TCP_Server_Info * server ;
struct cifs_ses * ses ;
struct cifs_tcon * tcon ;
struct cifsFileInfo * cfile ;
seq_puts ( m , " # Version:1 \n " ) ;
seq_puts ( m , " # Format: \n " ) ;
seq_puts ( m , " # <tree id> <persistent fid> <flags> <count> <pid> <uid> " ) ;
# ifdef CONFIG_CIFS_DEBUG2
seq_printf ( m , " <filename> <mid> \n " ) ;
# else
seq_printf ( m , " <filename> \n " ) ;
# endif /* CIFS_DEBUG2 */
spin_lock ( & cifs_tcp_ses_lock ) ;
list_for_each ( stmp , & cifs_tcp_ses_list ) {
server = list_entry ( stmp , struct TCP_Server_Info ,
tcp_ses_list ) ;
list_for_each ( tmp , & server - > smb_ses_list ) {
ses = list_entry ( tmp , struct cifs_ses , smb_ses_list ) ;
list_for_each ( tmp1 , & ses - > tcon_list ) {
tcon = list_entry ( tmp1 , struct cifs_tcon , tcon_list ) ;
spin_lock ( & tcon - > open_file_lock ) ;
list_for_each ( tmp2 , & tcon - > openFileList ) {
cfile = list_entry ( tmp2 , struct cifsFileInfo ,
tlist ) ;
seq_printf ( m ,
" 0x%x 0x%llx 0x%x %d %d %d %s " ,
tcon - > tid ,
cfile - > fid . persistent_fid ,
cfile - > f_flags ,
cfile - > count ,
cfile - > pid ,
from_kuid ( & init_user_ns , cfile - > uid ) ,
cfile - > dentry - > d_name . name ) ;
# ifdef CONFIG_CIFS_DEBUG2
seq_printf ( m , " 0x%llx \n " , cfile - > fid . mid ) ;
# else
seq_printf ( m , " \n " ) ;
# endif /* CIFS_DEBUG2 */
}
spin_unlock ( & tcon - > open_file_lock ) ;
}
}
}
spin_unlock ( & cifs_tcp_ses_lock ) ;
seq_putc ( m , ' \n ' ) ;
return 0 ;
}
2008-07-24 06:34:24 +04:00
static int cifs_debug_data_proc_show ( struct seq_file * m , void * v )
2005-04-17 02:20:36 +04:00
{
2008-11-15 19:12:47 +03:00
struct list_head * tmp1 , * tmp2 , * tmp3 ;
2007-06-25 01:15:44 +04:00
struct mid_q_entry * mid_entry ;
2008-11-14 21:53:46 +03:00
struct TCP_Server_Info * server ;
2011-05-27 08:34:02 +04:00
struct cifs_ses * ses ;
struct cifs_tcon * tcon ;
2008-11-15 19:12:47 +03:00
int i , j ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
seq_puts ( m ,
2005-04-17 02:20:36 +04:00
" Display Internal CIFS Data Structures for Debugging \n "
" --------------------------------------------------- \n " ) ;
2008-07-24 06:34:24 +04:00
seq_printf ( m , " CIFS Version %s \n " , CIFS_VERSION ) ;
2011-01-07 19:30:29 +03:00
seq_printf ( m , " Features: " ) ;
2010-07-30 16:55:56 +04:00
# ifdef CONFIG_CIFS_DFS_UPCALL
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " DFS " ) ;
2010-07-30 16:55:56 +04:00
# endif
# ifdef CONFIG_CIFS_FSCACHE
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,FSCACHE " ) ;
# endif
# ifdef CONFIG_CIFS_SMB_DIRECT
seq_printf ( m , " ,SMB_DIRECT " ) ;
# endif
# ifdef CONFIG_CIFS_STATS2
seq_printf ( m , " ,STATS2 " ) ;
2018-08-02 06:34:04 +03:00
# else
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,STATS " ) ;
# endif
# ifdef CONFIG_CIFS_DEBUG2
seq_printf ( m , " ,DEBUG2 " ) ;
# elif defined(CONFIG_CIFS_DEBUG)
seq_printf ( m , " ,DEBUG " ) ;
# endif
# ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
seq_printf ( m , " ,ALLOW_INSECURE_LEGACY " ) ;
2010-07-30 16:55:56 +04:00
# endif
# ifdef CONFIG_CIFS_WEAK_PW_HASH
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,WEAK_PW_HASH " ) ;
2010-07-30 16:55:56 +04:00
# endif
# ifdef CONFIG_CIFS_POSIX
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,CIFS_POSIX " ) ;
2010-07-30 16:55:56 +04:00
# endif
# ifdef CONFIG_CIFS_UPCALL
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,UPCALL(SPNEGO) " ) ;
2010-07-30 16:55:56 +04:00
# endif
# ifdef CONFIG_CIFS_XATTR
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,XATTR " ) ;
2011-01-07 19:30:29 +03:00
# endif
# ifdef CONFIG_CIFS_ACL
cifs: add missing debug entries for kconfig options
/proc/fs/cifs/DebugData displays the features (Kconfig options)
used to build cifs.ko but it was missing some, and needed comma
separator. These can be useful in debugging certain problems
so we know which optional features were enabled in the user's build.
Also clarify them, by making them more closely match the
corresponding CONFIG_CIFS_* parm.
Old format:
Features: dfs fscache posix spnego xattr acl
New format:
Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
CC: Stable <stable@vger.kernel.org>
2018-06-29 02:46:40 +03:00
seq_printf ( m , " ,ACL " ) ;
2010-07-30 16:55:56 +04:00
# endif
seq_putc ( m , ' \n ' ) ;
2019-01-24 09:19:31 +03:00
seq_printf ( m , " CIFSMaxBufSize: %d \n " , CIFSMaxBufSize ) ;
2008-07-24 06:34:24 +04:00
seq_printf ( m , " Active VFS Requests: %d \n " , GlobalTotalActiveXid ) ;
seq_printf ( m , " Servers: " ) ;
2005-04-17 02:20:36 +04:00
i = 0 ;
2010-10-18 21:59:37 +04:00
spin_lock ( & cifs_tcp_ses_lock ) ;
2008-11-15 19:12:47 +03:00
list_for_each ( tmp1 , & cifs_tcp_ses_list ) {
server = list_entry ( tmp1 , struct TCP_Server_Info ,
2008-11-14 21:53:46 +03:00
tcp_ses_list ) ;
2017-11-23 03:38:48 +03:00
# ifdef CONFIG_CIFS_SMB_DIRECT
if ( ! server - > rdma )
goto skip_rdma ;
seq_printf ( m , " \n SMBDirect (in hex) protocol version: %x "
" transport status: %x " ,
server - > smbd_conn - > protocol ,
server - > smbd_conn - > transport_status ) ;
seq_printf ( m , " \n Conn receive_credit_max: %x "
" send_credit_target: %x max_send_size: %x " ,
server - > smbd_conn - > receive_credit_max ,
server - > smbd_conn - > send_credit_target ,
server - > smbd_conn - > max_send_size ) ;
seq_printf ( m , " \n Conn max_fragmented_recv_size: %x "
" max_fragmented_send_size: %x max_receive_size:%x " ,
server - > smbd_conn - > max_fragmented_recv_size ,
server - > smbd_conn - > max_fragmented_send_size ,
server - > smbd_conn - > max_receive_size ) ;
seq_printf ( m , " \n Conn keep_alive_interval: %x "
" max_readwrite_size: %x rdma_readwrite_threshold: %x " ,
server - > smbd_conn - > keep_alive_interval ,
server - > smbd_conn - > max_readwrite_size ,
server - > smbd_conn - > rdma_readwrite_threshold ) ;
seq_printf ( m , " \n Debug count_get_receive_buffer: %x "
" count_put_receive_buffer: %x count_send_empty: %x " ,
server - > smbd_conn - > count_get_receive_buffer ,
server - > smbd_conn - > count_put_receive_buffer ,
server - > smbd_conn - > count_send_empty ) ;
seq_printf ( m , " \n Read Queue count_reassembly_queue: %x "
" count_enqueue_reassembly_queue: %x "
" count_dequeue_reassembly_queue: %x "
" fragment_reassembly_remaining: %x "
" reassembly_data_length: %x "
" reassembly_queue_length: %x " ,
server - > smbd_conn - > count_reassembly_queue ,
server - > smbd_conn - > count_enqueue_reassembly_queue ,
server - > smbd_conn - > count_dequeue_reassembly_queue ,
server - > smbd_conn - > fragment_reassembly_remaining ,
server - > smbd_conn - > reassembly_data_length ,
server - > smbd_conn - > reassembly_queue_length ) ;
seq_printf ( m , " \n Current Credits send_credits: %x "
" receive_credits: %x receive_credit_target: %x " ,
atomic_read ( & server - > smbd_conn - > send_credits ) ,
atomic_read ( & server - > smbd_conn - > receive_credits ) ,
server - > smbd_conn - > receive_credit_target ) ;
seq_printf ( m , " \n Pending send_pending: %x send_payload_pending: "
" %x smbd_send_pending: %x smbd_recv_pending: %x " ,
atomic_read ( & server - > smbd_conn - > send_pending ) ,
atomic_read ( & server - > smbd_conn - > send_payload_pending ) ,
server - > smbd_conn - > smbd_send_pending ,
server - > smbd_conn - > smbd_recv_pending ) ;
seq_printf ( m , " \n Receive buffers count_receive_queue: %x "
" count_empty_packet_queue: %x " ,
server - > smbd_conn - > count_receive_queue ,
server - > smbd_conn - > count_empty_packet_queue ) ;
seq_printf ( m , " \n MR responder_resources: %x "
" max_frmr_depth: %x mr_type: %x " ,
server - > smbd_conn - > responder_resources ,
server - > smbd_conn - > max_frmr_depth ,
server - > smbd_conn - > mr_type ) ;
seq_printf ( m , " \n MR mr_ready_count: %x mr_used_count: %x " ,
atomic_read ( & server - > smbd_conn - > mr_ready_count ) ,
atomic_read ( & server - > smbd_conn - > mr_used_count ) ) ;
skip_rdma :
# endif
2018-01-31 23:34:37 +03:00
seq_printf ( m , " \n Number of credits: %d Dialect 0x%x " ,
server - > credits , server - > dialect ) ;
if ( server - > sign )
seq_printf ( m , " signed " ) ;
2018-05-20 04:45:27 +03:00
if ( server - > posix_ext_supported )
seq_printf ( m , " posix " ) ;
2018-06-29 03:30:23 +03:00
2005-04-17 02:20:36 +04:00
i + + ;
2008-11-14 21:53:46 +03:00
list_for_each ( tmp2 , & server - > smb_ses_list ) {
2011-05-27 08:34:02 +04:00
ses = list_entry ( tmp2 , struct cifs_ses ,
2008-11-14 21:53:46 +03:00
smb_ses_list ) ;
if ( ( ses - > serverDomain = = NULL ) | |
( ses - > serverOS = = NULL ) | |
( ses - > serverNOS = = NULL ) ) {
2018-09-19 10:38:17 +03:00
seq_printf ( m , " \n %d) Name: %s Uses: %d Capability: 0x%x \t Session Status: %d " ,
2017-09-21 00:46:49 +03:00
i , ses - > serverName , ses - > ses_count ,
ses - > capabilities , ses - > status ) ;
if ( ses - > session_flags & SMB2_SESSION_FLAG_IS_GUEST )
seq_printf ( m , " Guest \t " ) ;
else if ( ses - > session_flags & SMB2_SESSION_FLAG_IS_NULL )
seq_printf ( m , " Anonymous \t " ) ;
2008-11-14 21:53:46 +03:00
} else {
seq_printf ( m ,
2008-11-15 19:12:47 +03:00
" \n %d) Name: %s Domain: %s Uses: %d OS: "
" %s \n \t NOS: %s \t Capability: 0x%x \n \t SMB "
2018-09-19 10:38:17 +03:00
" session status: %d " ,
2005-04-29 09:41:07 +04:00
i , ses - > serverName , ses - > serverDomain ,
2008-11-14 21:53:46 +03:00
ses - > ses_count , ses - > serverOS , ses - > serverNOS ,
2007-06-06 00:35:06 +04:00
ses - > capabilities , ses - > status ) ;
2008-11-14 21:53:46 +03:00
}
2017-11-07 11:54:55 +03:00
if ( server - > rdma )
seq_printf ( m , " RDMA \n \t " ) ;
2018-09-19 10:38:17 +03:00
seq_printf ( m , " TCP status: %d Instance: %d \n \t Local Users To "
2008-11-14 21:53:46 +03:00
" Server: %d SecMode: 0x%x Req On Wire: %d " ,
2018-09-19 10:38:17 +03:00
server - > tcpStatus ,
server - > reconnect_instance ,
server - > srv_count ,
2012-02-17 18:09:12 +04:00
server - > sec_mode , in_flight ( server ) ) ;
2005-10-07 20:51:05 +04:00
# ifdef CONFIG_CIFS_STATS2
2008-07-24 06:34:24 +04:00
seq_printf ( m , " In Send: %d In MaxReq Wait: %d " ,
2011-08-09 22:44:44 +04:00
atomic_read ( & server - > in_send ) ,
2008-11-14 21:53:46 +03:00
atomic_read ( & server - > num_waiters ) ) ;
2005-10-07 20:51:05 +04:00
# endif
2019-03-10 03:12:18 +03:00
if ( ses - > session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA )
seq_puts ( m , " encrypted " ) ;
if ( ses - > sign )
seq_puts ( m , " signed " ) ;
2005-10-07 20:51:05 +04:00
2008-11-15 19:12:47 +03:00
seq_puts ( m , " \n \t Shares: " ) ;
j = 0 ;
2018-01-24 15:46:12 +03:00
seq_printf ( m , " \n \t %d) IPC: " , j ) ;
if ( ses - > tcon_ipc )
cifs_debug_tcon ( m , ses - > tcon_ipc ) ;
else
seq_puts ( m , " none \n " ) ;
2008-11-15 19:12:47 +03:00
list_for_each ( tmp3 , & ses - > tcon_list ) {
2011-05-27 08:34:02 +04:00
tcon = list_entry ( tmp3 , struct cifs_tcon ,
2008-11-15 19:12:47 +03:00
tcon_list ) ;
+ + j ;
2018-01-24 15:46:12 +03:00
seq_printf ( m , " \n \t %d) " , j ) ;
cifs_debug_tcon ( m , tcon ) ;
2008-11-15 19:12:47 +03:00
}
seq_puts ( m , " \n \t MIDs: \n " ) ;
2005-04-17 02:20:36 +04:00
spin_lock ( & GlobalMid_Lock ) ;
2008-11-14 21:53:46 +03:00
list_for_each ( tmp3 , & server - > pending_mid_q ) {
2008-11-15 19:12:47 +03:00
mid_entry = list_entry ( tmp3 , struct mid_q_entry ,
2005-04-17 02:20:36 +04:00
qhead ) ;
2008-11-15 19:12:47 +03:00
seq_printf ( m , " \t State: %d com: %d pid: "
2012-03-23 22:28:03 +04:00
" %d cbdata: %p mid %llu \n " ,
mid_entry - > mid_state ,
le16_to_cpu ( mid_entry - > command ) ,
mid_entry - > pid ,
mid_entry - > callback_data ,
mid_entry - > mid ) ;
2005-04-17 02:20:36 +04:00
}
2007-06-06 00:35:06 +04:00
spin_unlock ( & GlobalMid_Lock ) ;
2018-06-14 16:43:20 +03:00
spin_lock ( & ses - > iface_lock ) ;
2018-06-15 05:59:31 +03:00
if ( ses - > iface_count )
seq_printf ( m , " \n \t Server interfaces: %zu \n " ,
ses - > iface_count ) ;
2018-06-14 16:43:20 +03:00
for ( j = 0 ; j < ses - > iface_count ; j + + ) {
2018-10-20 05:21:37 +03:00
seq_printf ( m , " \t %d) " , j ) ;
2018-06-14 16:43:20 +03:00
cifs_dump_iface ( m , & ses - > iface_list [ j ] ) ;
}
spin_unlock ( & ses - > iface_lock ) ;
2005-04-17 02:20:36 +04:00
}
}
2010-10-18 21:59:37 +04:00
spin_unlock ( & cifs_tcp_ses_lock ) ;
2008-07-24 06:34:24 +04:00
seq_putc ( m , ' \n ' ) ;
2005-04-17 02:20:36 +04:00
/* BB add code to dump additional info such as TCP session info now */
2008-07-24 06:34:24 +04:00
return 0 ;
}
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static ssize_t cifs_stats_proc_write ( struct file * file ,
const char __user * buffer , size_t count , loff_t * ppos )
2005-10-12 06:58:06 +04:00
{
2014-08-27 17:49:42 +04:00
bool bv ;
2007-06-06 00:35:06 +04:00
int rc ;
2008-11-15 19:12:47 +03:00
struct list_head * tmp1 , * tmp2 , * tmp3 ;
struct TCP_Server_Info * server ;
2011-05-27 08:34:02 +04:00
struct cifs_ses * ses ;
struct cifs_tcon * tcon ;
2005-10-12 06:58:06 +04:00
2016-03-18 00:22:54 +03:00
rc = kstrtobool_from_user ( buffer , count , & bv ) ;
if ( rc = = 0 ) {
2005-12-04 00:58:57 +03:00
# ifdef CONFIG_CIFS_STATS2
2018-08-04 13:24:34 +03:00
int i ;
2005-12-04 00:58:57 +03:00
atomic_set ( & totBufAllocCount , 0 ) ;
atomic_set ( & totSmBufAllocCount , 0 ) ;
# endif /* CONFIG_CIFS_STATS2 */
2018-09-16 07:04:41 +03:00
atomic_set ( & tcpSesReconnectCount , 0 ) ;
atomic_set ( & tconInfoReconnectCount , 0 ) ;
2018-08-01 08:56:12 +03:00
spin_lock ( & GlobalMid_Lock ) ;
GlobalMaxActiveXid = 0 ;
GlobalCurrentXid = 0 ;
spin_unlock ( & GlobalMid_Lock ) ;
2010-10-18 21:59:37 +04:00
spin_lock ( & cifs_tcp_ses_lock ) ;
2008-11-15 19:12:47 +03:00
list_for_each ( tmp1 , & cifs_tcp_ses_list ) {
server = list_entry ( tmp1 , struct TCP_Server_Info ,
tcp_ses_list ) ;
2018-08-04 13:24:34 +03:00
# ifdef CONFIG_CIFS_STATS2
2019-03-26 21:53:21 +03:00
for ( i = 0 ; i < NUMBER_OF_SMB2_COMMANDS ; i + + ) {
atomic_set ( & server - > num_cmds [ i ] , 0 ) ;
2018-08-04 13:24:34 +03:00
atomic_set ( & server - > smb2slowcmd [ i ] , 0 ) ;
2019-03-26 21:53:21 +03:00
server - > time_per_cmd [ i ] = 0 ;
server - > slowest_cmd [ i ] = 0 ;
server - > fastest_cmd [ 0 ] = 0 ;
}
2018-08-04 13:24:34 +03:00
# endif /* CONFIG_CIFS_STATS2 */
2008-11-17 06:57:13 +03:00
list_for_each ( tmp2 , & server - > smb_ses_list ) {
2011-05-27 08:34:02 +04:00
ses = list_entry ( tmp2 , struct cifs_ses ,
2008-11-17 06:57:13 +03:00
smb_ses_list ) ;
2008-11-15 19:12:47 +03:00
list_for_each ( tmp3 , & ses - > tcon_list ) {
tcon = list_entry ( tmp3 ,
2011-05-27 08:34:02 +04:00
struct cifs_tcon ,
2008-11-15 19:12:47 +03:00
tcon_list ) ;
atomic_set ( & tcon - > num_smbs_sent , 0 ) ;
2018-08-01 08:56:12 +03:00
spin_lock ( & tcon - > stat_lock ) ;
tcon - > bytes_read = 0 ;
tcon - > bytes_written = 0 ;
spin_unlock ( & tcon - > stat_lock ) ;
2012-05-28 14:16:31 +04:00
if ( server - > ops - > clear_stats )
server - > ops - > clear_stats ( tcon ) ;
2008-11-15 19:12:47 +03:00
}
}
2005-10-12 06:58:06 +04:00
}
2010-10-18 21:59:37 +04:00
spin_unlock ( & cifs_tcp_ses_lock ) ;
2016-03-18 00:22:54 +03:00
} else {
return rc ;
2005-10-12 06:58:06 +04:00
}
2007-06-06 00:35:06 +04:00
return count ;
2005-10-12 06:58:06 +04:00
}
2008-07-24 06:34:24 +04:00
static int cifs_stats_proc_show ( struct seq_file * m , void * v )
2005-04-17 02:20:36 +04:00
{
2008-07-24 06:34:24 +04:00
int i ;
2018-08-04 13:24:34 +03:00
# ifdef CONFIG_CIFS_STATS2
int j ;
# endif /* STATS2 */
2008-11-15 19:12:47 +03:00
struct list_head * tmp1 , * tmp2 , * tmp3 ;
struct TCP_Server_Info * server ;
2011-05-27 08:34:02 +04:00
struct cifs_ses * ses ;
struct cifs_tcon * tcon ;
2005-04-17 02:20:36 +04:00
2018-08-04 13:24:34 +03:00
seq_printf ( m , " Resources in use \n CIFS Session: %d \n " ,
2005-04-17 02:20:36 +04:00
sesInfoAllocCount . counter ) ;
2008-07-24 06:34:24 +04:00
seq_printf ( m , " Share (unique mount targets): %d \n " ,
2005-04-17 02:20:36 +04:00
tconInfoAllocCount . counter ) ;
2008-07-24 06:34:24 +04:00
seq_printf ( m , " SMB Request/Response Buffer: %d Pool size: %d \n " ,
2005-04-29 09:41:07 +04:00
bufAllocCount . counter ,
cifs_min_rcv + tcpSesAllocCount . counter ) ;
2008-07-24 06:34:24 +04:00
seq_printf ( m , " SMB Small Req/Resp Buffer: %d Pool size: %d \n " ,
2007-06-06 00:35:06 +04:00
smBufAllocCount . counter , cifs_min_small ) ;
2005-12-04 01:11:37 +03:00
# ifdef CONFIG_CIFS_STATS2
2008-07-24 06:34:24 +04:00
seq_printf ( m , " Total Large %d Small %d Allocations \n " ,
2005-12-04 01:11:37 +03:00
atomic_read ( & totBufAllocCount ) ,
2007-06-06 00:35:06 +04:00
atomic_read ( & totSmBufAllocCount ) ) ;
2005-12-04 01:11:37 +03:00
# endif /* CONFIG_CIFS_STATS2 */
2011-01-11 15:24:02 +03:00
seq_printf ( m , " Operations (MIDs): %d \n " , atomic_read ( & midCount ) ) ;
2008-07-24 06:34:24 +04:00
seq_printf ( m ,
2005-04-17 02:20:36 +04:00
" \n %d session %d share reconnects \n " ,
2007-06-06 00:35:06 +04:00
tcpSesReconnectCount . counter , tconInfoReconnectCount . counter ) ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
seq_printf ( m ,
2005-04-17 02:20:36 +04:00
" Total vfs operations: %d maximum at one time: %d \n " ,
2007-06-06 00:35:06 +04:00
GlobalCurrentXid , GlobalMaxActiveXid ) ;
2005-04-17 02:20:36 +04:00
i = 0 ;
2010-10-18 21:59:37 +04:00
spin_lock ( & cifs_tcp_ses_lock ) ;
2008-11-15 19:12:47 +03:00
list_for_each ( tmp1 , & cifs_tcp_ses_list ) {
server = list_entry ( tmp1 , struct TCP_Server_Info ,
tcp_ses_list ) ;
2018-08-04 13:24:34 +03:00
# ifdef CONFIG_CIFS_STATS2
2019-03-26 21:53:21 +03:00
seq_puts ( m , " \n Total time spent processing by command. Time " ) ;
seq_printf ( m , " units are jiffies (%d per second) \n " , HZ ) ;
seq_puts ( m , " SMB3 CMD \t Number \t Total Time \t Fastest \t Slowest \n " ) ;
seq_puts ( m , " -------- \t ------ \t ---------- \t ------- \t ------- \n " ) ;
for ( j = 0 ; j < NUMBER_OF_SMB2_COMMANDS ; j + + )
seq_printf ( m , " %d \t \t %d \t %llu \t \t %u \t %u \n " , j ,
atomic_read ( & server - > num_cmds [ j ] ) ,
server - > time_per_cmd [ j ] ,
server - > fastest_cmd [ j ] ,
server - > slowest_cmd [ j ] ) ;
2018-08-04 13:24:34 +03:00
for ( j = 0 ; j < NUMBER_OF_SMB2_COMMANDS ; j + + )
if ( atomic_read ( & server - > smb2slowcmd [ j ] ) )
2019-03-26 21:53:21 +03:00
seq_printf ( m , " %d slow responses from %s for command %d \n " ,
2018-08-04 13:24:34 +03:00
atomic_read ( & server - > smb2slowcmd [ j ] ) ,
server - > hostname , j ) ;
# endif /* STATS2 */
2008-11-15 19:12:47 +03:00
list_for_each ( tmp2 , & server - > smb_ses_list ) {
2011-05-27 08:34:02 +04:00
ses = list_entry ( tmp2 , struct cifs_ses ,
2008-11-15 19:12:47 +03:00
smb_ses_list ) ;
list_for_each ( tmp3 , & ses - > tcon_list ) {
tcon = list_entry ( tmp3 ,
2011-05-27 08:34:02 +04:00
struct cifs_tcon ,
2008-11-15 19:12:47 +03:00
tcon_list ) ;
i + + ;
seq_printf ( m , " \n %d) %s " , i , tcon - > treeName ) ;
if ( tcon - > need_reconnect )
seq_puts ( m , " \t DISCONNECTED " ) ;
2012-05-28 14:16:31 +04:00
seq_printf ( m , " \n SMBs: %d " ,
atomic_read ( & tcon - > num_smbs_sent ) ) ;
if ( server - > ops - > print_stats )
server - > ops - > print_stats ( m , tcon ) ;
2008-11-15 19:12:47 +03:00
}
}
2005-04-17 02:20:36 +04:00
}
2010-10-18 21:59:37 +04:00
spin_unlock ( & cifs_tcp_ses_lock ) ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
seq_putc ( m , ' \n ' ) ;
return 0 ;
}
2007-06-06 00:35:06 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_stats_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , cifs_stats_proc_show , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static const struct file_operations cifs_stats_proc_fops = {
. open = cifs_stats_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = cifs_stats_proc_write ,
} ;
2005-04-17 02:20:36 +04:00
2017-11-07 11:54:58 +03:00
# ifdef CONFIG_CIFS_SMB_DIRECT
# define PROC_FILE_DEFINE(name) \
static ssize_t name # # _write ( struct file * file , const char __user * buffer , \
size_t count , loff_t * ppos ) \
{ \
int rc ; \
rc = kstrtoint_from_user ( buffer , count , 10 , & name ) ; \
if ( rc ) \
return rc ; \
return count ; \
} \
static int name # # _proc_show ( struct seq_file * m , void * v ) \
{ \
seq_printf ( m , " %d \n " , name ) ; \
return 0 ; \
} \
static int name # # _open ( struct inode * inode , struct file * file ) \
{ \
return single_open ( file , name # # _proc_show , NULL ) ; \
} \
\
static const struct file_operations cifs_ # # name # # _proc_fops = { \
. open = name # # _open , \
. read = seq_read , \
. llseek = seq_lseek , \
. release = single_release , \
. write = name # # _write , \
}
PROC_FILE_DEFINE ( rdma_readwrite_threshold ) ;
PROC_FILE_DEFINE ( smbd_max_frmr_depth ) ;
PROC_FILE_DEFINE ( smbd_keep_alive_interval ) ;
PROC_FILE_DEFINE ( smbd_max_receive_size ) ;
PROC_FILE_DEFINE ( smbd_max_fragmented_recv_size ) ;
PROC_FILE_DEFINE ( smbd_max_send_size ) ;
PROC_FILE_DEFINE ( smbd_send_credit_target ) ;
PROC_FILE_DEFINE ( smbd_receive_credit_max ) ;
# endif
2005-04-17 02:20:36 +04:00
static struct proc_dir_entry * proc_fs_cifs ;
2008-07-24 06:34:24 +04:00
static const struct file_operations cifsFYI_proc_fops ;
static const struct file_operations cifs_lookup_cache_proc_fops ;
static const struct file_operations traceSMB_proc_fops ;
static const struct file_operations cifs_security_flags_proc_fops ;
static const struct file_operations cifs_linux_ext_proc_fops ;
2005-04-17 02:20:36 +04:00
void
cifs_proc_init ( void )
{
2008-04-29 12:01:42 +04:00
proc_fs_cifs = proc_mkdir ( " fs/cifs " , NULL ) ;
2005-04-17 02:20:36 +04:00
if ( proc_fs_cifs = = NULL )
return ;
2018-05-15 16:57:23 +03:00
proc_create_single ( " DebugData " , 0 , proc_fs_cifs ,
cifs_debug_data_proc_show ) ;
2005-04-17 02:20:36 +04:00
2018-10-31 03:50:31 +03:00
proc_create_single ( " open_files " , 0400 , proc_fs_cifs ,
cifs_debug_files_proc_show ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " Stats " , 0644 , proc_fs_cifs , & cifs_stats_proc_fops ) ;
proc_create ( " cifsFYI " , 0644 , proc_fs_cifs , & cifsFYI_proc_fops ) ;
proc_create ( " traceSMB " , 0644 , proc_fs_cifs , & traceSMB_proc_fops ) ;
proc_create ( " LinuxExtensionsEnabled " , 0644 , proc_fs_cifs ,
2008-07-24 06:37:45 +04:00
& cifs_linux_ext_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " SecurityFlags " , 0644 , proc_fs_cifs ,
2008-07-24 06:37:45 +04:00
& cifs_security_flags_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " LookupCacheEnabled " , 0644 , proc_fs_cifs ,
2008-07-24 06:37:45 +04:00
& cifs_lookup_cache_proc_fops ) ;
2018-11-14 21:01:21 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
proc_create ( " dfscache " , 0644 , proc_fs_cifs , & dfscache_proc_fops ) ;
# endif
2017-11-07 11:54:58 +03:00
# ifdef CONFIG_CIFS_SMB_DIRECT
2018-05-24 07:18:05 +03:00
proc_create ( " rdma_readwrite_threshold " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_rdma_readwrite_threshold_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_max_frmr_depth " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_max_frmr_depth_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_keep_alive_interval " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_keep_alive_interval_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_max_receive_size " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_max_receive_size_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_max_fragmented_recv_size " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_max_fragmented_recv_size_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_max_send_size " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_max_send_size_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_send_credit_target " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_send_credit_target_proc_fops ) ;
2018-05-24 07:18:05 +03:00
proc_create ( " smbd_receive_credit_max " , 0644 , proc_fs_cifs ,
2017-11-07 11:54:58 +03:00
& cifs_smbd_receive_credit_max_proc_fops ) ;
# endif
2005-04-17 02:20:36 +04:00
}
void
cifs_proc_clean ( void )
{
if ( proc_fs_cifs = = NULL )
return ;
remove_proc_entry ( " DebugData " , proc_fs_cifs ) ;
2018-10-31 03:50:31 +03:00
remove_proc_entry ( " open_files " , proc_fs_cifs ) ;
2005-04-17 02:20:36 +04:00
remove_proc_entry ( " cifsFYI " , proc_fs_cifs ) ;
remove_proc_entry ( " traceSMB " , proc_fs_cifs ) ;
remove_proc_entry ( " Stats " , proc_fs_cifs ) ;
2007-06-06 00:35:06 +04:00
remove_proc_entry ( " SecurityFlags " , proc_fs_cifs ) ;
remove_proc_entry ( " LinuxExtensionsEnabled " , proc_fs_cifs ) ;
remove_proc_entry ( " LookupCacheEnabled " , proc_fs_cifs ) ;
2018-11-14 21:01:21 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
remove_proc_entry ( " dfscache " , proc_fs_cifs ) ;
# endif
2017-11-07 11:54:58 +03:00
# ifdef CONFIG_CIFS_SMB_DIRECT
remove_proc_entry ( " rdma_readwrite_threshold " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_max_frmr_depth " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_keep_alive_interval " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_max_receive_size " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_max_fragmented_recv_size " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_max_send_size " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_send_credit_target " , proc_fs_cifs ) ;
remove_proc_entry ( " smbd_receive_credit_max " , proc_fs_cifs ) ;
# endif
2008-04-29 12:01:42 +04:00
remove_proc_entry ( " fs/cifs " , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static int cifsFYI_proc_show ( struct seq_file * m , void * v )
2005-04-17 02:20:36 +04:00
{
2008-07-24 06:34:24 +04:00
seq_printf ( m , " %d \n " , cifsFYI ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifsFYI_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , cifsFYI_proc_show , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static ssize_t cifsFYI_proc_write ( struct file * file , const char __user * buffer ,
size_t count , loff_t * ppos )
2005-04-17 02:20:36 +04:00
{
2016-03-18 00:22:54 +03:00
char c [ 2 ] = { ' \0 ' } ;
2014-08-27 17:49:42 +04:00
bool bv ;
2005-04-17 02:20:36 +04:00
int rc ;
2016-03-18 00:22:54 +03:00
rc = get_user ( c [ 0 ] , buffer ) ;
2005-04-17 02:20:36 +04:00
if ( rc )
return rc ;
2016-03-18 00:22:54 +03:00
if ( strtobool ( c , & bv ) = = 0 )
2014-08-27 17:49:42 +04:00
cifsFYI = bv ;
2016-03-18 00:22:54 +03:00
else if ( ( c [ 0 ] > ' 1 ' ) & & ( c [ 0 ] < = ' 9 ' ) )
cifsFYI = ( int ) ( c [ 0 ] - ' 0 ' ) ; /* see cifs_debug.h for meanings */
2018-05-24 02:53:39 +03:00
else
return - EINVAL ;
2005-04-17 02:20:36 +04:00
return count ;
}
2008-07-24 06:34:24 +04:00
static const struct file_operations cifsFYI_proc_fops = {
. open = cifsFYI_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = cifsFYI_proc_write ,
} ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_linux_ext_proc_show ( struct seq_file * m , void * v )
{
seq_printf ( m , " %d \n " , linuxExtEnabled ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_linux_ext_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , cifs_linux_ext_proc_show , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static ssize_t cifs_linux_ext_proc_write ( struct file * file ,
const char __user * buffer , size_t count , loff_t * ppos )
2005-04-17 02:20:36 +04:00
{
2007-06-06 00:35:06 +04:00
int rc ;
2016-03-18 00:22:54 +03:00
rc = kstrtobool_from_user ( buffer , count , & linuxExtEnabled ) ;
2007-06-06 00:35:06 +04:00
if ( rc )
return rc ;
2014-08-27 17:49:42 +04:00
2007-06-06 00:35:06 +04:00
return count ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static const struct file_operations cifs_linux_ext_proc_fops = {
. open = cifs_linux_ext_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = cifs_linux_ext_proc_write ,
} ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_lookup_cache_proc_show ( struct seq_file * m , void * v )
2005-04-17 02:20:36 +04:00
{
2008-07-24 06:34:24 +04:00
seq_printf ( m , " %d \n " , lookupCacheEnabled ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_lookup_cache_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , cifs_lookup_cache_proc_show , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static ssize_t cifs_lookup_cache_proc_write ( struct file * file ,
const char __user * buffer , size_t count , loff_t * ppos )
2005-04-17 02:20:36 +04:00
{
int rc ;
2016-03-18 00:22:54 +03:00
rc = kstrtobool_from_user ( buffer , count , & lookupCacheEnabled ) ;
2005-04-17 02:20:36 +04:00
if ( rc )
return rc ;
2014-08-27 17:49:42 +04:00
2005-04-17 02:20:36 +04:00
return count ;
}
2008-07-24 06:34:24 +04:00
static const struct file_operations cifs_lookup_cache_proc_fops = {
. open = cifs_lookup_cache_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = cifs_lookup_cache_proc_write ,
} ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int traceSMB_proc_show ( struct seq_file * m , void * v )
{
seq_printf ( m , " %d \n " , traceSMB ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int traceSMB_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , traceSMB_proc_show , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
static ssize_t traceSMB_proc_write ( struct file * file , const char __user * buffer ,
size_t count , loff_t * ppos )
2005-04-17 02:20:36 +04:00
{
int rc ;
2016-03-18 00:22:54 +03:00
rc = kstrtobool_from_user ( buffer , count , & traceSMB ) ;
2005-04-17 02:20:36 +04:00
if ( rc )
return rc ;
2014-08-27 17:49:42 +04:00
2005-04-17 02:20:36 +04:00
return count ;
}
2008-07-24 06:34:24 +04:00
static const struct file_operations traceSMB_proc_fops = {
. open = traceSMB_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = traceSMB_proc_write ,
} ;
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_security_flags_proc_show ( struct seq_file * m , void * v )
{
2010-04-24 15:57:45 +04:00
seq_printf ( m , " 0x%x \n " , global_secflags ) ;
2008-07-24 06:34:24 +04:00
return 0 ;
}
2005-04-17 02:20:36 +04:00
2008-07-24 06:34:24 +04:00
static int cifs_security_flags_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , cifs_security_flags_proc_show , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-24 06:34:24 +04:00
2013-05-26 15:01:02 +04:00
/*
* Ensure that if someone sets a MUST flag , that we disable all other MAY
* flags except for the ones corresponding to the given MUST flag . If there are
* multiple MUST flags , then try to prefer more secure ones .
*/
static void
cifs_security_flags_handle_must_flags ( unsigned int * flags )
{
unsigned int signflags = * flags & CIFSSEC_MUST_SIGN ;
if ( ( * flags & CIFSSEC_MUST_KRB5 ) = = CIFSSEC_MUST_KRB5 )
* flags = CIFSSEC_MUST_KRB5 ;
else if ( ( * flags & CIFSSEC_MUST_NTLMSSP ) = = CIFSSEC_MUST_NTLMSSP )
* flags = CIFSSEC_MUST_NTLMSSP ;
else if ( ( * flags & CIFSSEC_MUST_NTLMV2 ) = = CIFSSEC_MUST_NTLMV2 )
* flags = CIFSSEC_MUST_NTLMV2 ;
else if ( ( * flags & CIFSSEC_MUST_NTLM ) = = CIFSSEC_MUST_NTLM )
* flags = CIFSSEC_MUST_NTLM ;
2015-01-22 16:16:34 +03:00
else if ( CIFSSEC_MUST_LANMAN & &
( * flags & CIFSSEC_MUST_LANMAN ) = = CIFSSEC_MUST_LANMAN )
2013-05-26 15:01:02 +04:00
* flags = CIFSSEC_MUST_LANMAN ;
2015-01-22 16:16:34 +03:00
else if ( CIFSSEC_MUST_PLNTXT & &
( * flags & CIFSSEC_MUST_PLNTXT ) = = CIFSSEC_MUST_PLNTXT )
2013-05-26 15:01:02 +04:00
* flags = CIFSSEC_MUST_PLNTXT ;
* flags | = signflags ;
}
2008-07-24 06:34:24 +04:00
static ssize_t cifs_security_flags_proc_write ( struct file * file ,
const char __user * buffer , size_t count , loff_t * ppos )
2005-04-17 02:20:36 +04:00
{
2013-05-26 15:01:01 +04:00
int rc ;
2006-06-03 02:57:13 +04:00
unsigned int flags ;
char flags_string [ 12 ] ;
2014-08-27 17:49:42 +04:00
bool bv ;
2006-06-03 02:57:13 +04:00
2007-06-06 00:35:06 +04:00
if ( ( count < 1 ) | | ( count > 11 ) )
2006-06-01 02:40:51 +04:00
return - EINVAL ;
2005-04-17 02:20:36 +04:00
2006-06-03 02:57:13 +04:00
memset ( flags_string , 0 , 12 ) ;
2006-06-01 02:40:51 +04:00
2007-06-06 00:35:06 +04:00
if ( copy_from_user ( flags_string , buffer , count ) )
2006-06-03 02:57:13 +04:00
return - EFAULT ;
2006-06-01 02:40:51 +04:00
2007-06-06 00:35:06 +04:00
if ( count < 3 ) {
2006-06-03 02:57:13 +04:00
/* single char or single char followed by null */
2016-03-18 00:22:54 +03:00
if ( strtobool ( flags_string , & bv ) = = 0 ) {
2014-08-27 17:49:42 +04:00
global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF ;
2007-10-05 00:05:09 +04:00
return count ;
2016-03-18 00:22:54 +03:00
} else if ( ! isdigit ( flags_string [ 0 ] ) ) {
2013-05-26 15:01:01 +04:00
cifs_dbg ( VFS , " Invalid SecurityFlags: %s \n " ,
flags_string ) ;
2007-10-05 00:05:09 +04:00
return - EINVAL ;
}
2006-06-03 02:57:13 +04:00
}
2013-05-26 15:01:01 +04:00
/* else we have a number */
rc = kstrtouint ( flags_string , 0 , & flags ) ;
if ( rc ) {
cifs_dbg ( VFS , " Invalid SecurityFlags: %s \n " ,
flags_string ) ;
return rc ;
}
2006-06-03 02:57:13 +04:00
2013-05-05 07:12:25 +04:00
cifs_dbg ( FYI , " sec flags 0x%x \n " , flags ) ;
2006-06-03 02:57:13 +04:00
2013-05-26 15:01:01 +04:00
if ( flags = = 0 ) {
cifs_dbg ( VFS , " Invalid SecurityFlags: %s \n " , flags_string ) ;
2006-06-03 02:57:13 +04:00
return - EINVAL ;
}
2005-04-17 02:20:36 +04:00
2007-06-06 00:35:06 +04:00
if ( flags & ~ CIFSSEC_MASK ) {
2013-05-26 15:01:01 +04:00
cifs_dbg ( VFS , " Unsupported security flags: 0x%x \n " ,
2013-05-05 07:12:25 +04:00
flags & ~ CIFSSEC_MASK ) ;
2006-06-03 02:57:13 +04:00
return - EINVAL ;
}
2013-05-26 15:01:01 +04:00
2013-05-26 15:01:02 +04:00
cifs_security_flags_handle_must_flags ( & flags ) ;
2006-06-03 02:57:13 +04:00
/* flags look ok - update the global security flags for cifs module */
2010-04-24 15:57:45 +04:00
global_secflags = flags ;
if ( global_secflags & CIFSSEC_MUST_SIGN ) {
2007-06-28 22:41:42 +04:00
/* requiring signing implies signing is allowed */
2010-04-24 15:57:45 +04:00
global_secflags | = CIFSSEC_MAY_SIGN ;
2013-05-05 07:12:25 +04:00
cifs_dbg ( FYI , " packet signing now required \n " ) ;
2010-04-24 15:57:45 +04:00
} else if ( ( global_secflags & CIFSSEC_MAY_SIGN ) = = 0 ) {
2013-05-05 07:12:25 +04:00
cifs_dbg ( FYI , " packet signing disabled \n " ) ;
2007-06-28 22:41:42 +04:00
}
/* BB should we turn on MAY flags for other MUST options? */
2005-04-17 02:20:36 +04:00
return count ;
}
2008-07-24 06:34:24 +04:00
static const struct file_operations cifs_security_flags_proc_fops = {
. open = cifs_security_flags_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = cifs_security_flags_proc_write ,
} ;
2008-02-12 23:32:36 +03:00
# else
2008-02-18 07:03:58 +03:00
inline void cifs_proc_init ( void )
2008-02-12 23:32:36 +03:00
{
}
2008-02-18 07:03:58 +03:00
inline void cifs_proc_clean ( void )
2008-02-12 23:32:36 +03:00
{
}
# endif /* PROC_FS */