2022-03-01 15:25:00 +00:00
// SPDX-License-Identifier: GPL-2.0-or-later
/* Miscellaneous bits for the netfs support library.
*
* Copyright ( C ) 2022 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*/
# include <linux/module.h>
# include <linux/export.h>
2023-11-21 15:43:52 +00:00
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
2022-03-01 15:25:00 +00:00
# include "internal.h"
2023-11-20 15:55:18 +00:00
# define CREATE_TRACE_POINTS
# include <trace/events/netfs.h>
2022-03-01 15:25:00 +00:00
MODULE_DESCRIPTION ( " Network fs support " ) ;
MODULE_AUTHOR ( " Red Hat, Inc. " ) ;
MODULE_LICENSE ( " GPL " ) ;
2022-04-25 16:30:11 +01:00
EXPORT_TRACEPOINT_SYMBOL ( netfs_sreq ) ;
2022-03-01 15:25:00 +00:00
unsigned netfs_debug ;
module_param_named ( debug , netfs_debug , uint , S_IWUSR | S_IRUGO ) ;
MODULE_PARM_DESC ( netfs_debug , " Netfs support debugging mask " ) ;
2023-11-20 15:29:09 +00:00
2022-03-04 10:34:27 +00:00
# ifdef CONFIG_PROC_FS
LIST_HEAD ( netfs_io_requests ) ;
DEFINE_SPINLOCK ( netfs_proc_lock ) ;
2022-02-09 19:52:13 +00:00
static const char * netfs_origins [ nr__netfs_io_origin ] = {
2022-02-21 11:38:17 +00:00
[ NETFS_READAHEAD ] = " RA " ,
[ NETFS_READPAGE ] = " RP " ,
[ NETFS_READ_FOR_WRITE ] = " RW " ,
[ NETFS_WRITEBACK ] = " WB " ,
2023-10-12 09:06:24 +01:00
[ NETFS_WRITETHROUGH ] = " WT " ,
2023-10-05 16:52:58 +01:00
[ NETFS_LAUNDER_WRITE ] = " LW " ,
2022-02-21 11:38:17 +00:00
[ NETFS_UNBUFFERED_WRITE ] = " UW " ,
[ NETFS_DIO_READ ] = " DR " ,
[ NETFS_DIO_WRITE ] = " DW " ,
2022-03-04 10:34:27 +00:00
} ;
/*
* Generate a list of I / O requests in / proc / fs / netfs / requests
*/
static int netfs_requests_seq_show ( struct seq_file * m , void * v )
{
struct netfs_io_request * rreq ;
if ( v = = & netfs_io_requests ) {
seq_puts ( m ,
" REQUEST OR REF FL ERR OPS COVERAGE \n "
" ======== == === == ==== === ========= \n "
) ;
return 0 ;
}
rreq = list_entry ( v , struct netfs_io_request , proc_link ) ;
seq_printf ( m ,
" %08x %s %3d %2lx %4d %3d @%04llx %zx/%zx " ,
rreq - > debug_id ,
netfs_origins [ rreq - > origin ] ,
refcount_read ( & rreq - > ref ) ,
rreq - > flags ,
rreq - > error ,
atomic_read ( & rreq - > nr_outstanding ) ,
rreq - > start , rreq - > submitted , rreq - > len ) ;
seq_putc ( m , ' \n ' ) ;
return 0 ;
}
static void * netfs_requests_seq_start ( struct seq_file * m , loff_t * _pos )
__acquires ( rcu )
{
rcu_read_lock ( ) ;
return seq_list_start_head ( & netfs_io_requests , * _pos ) ;
}
static void * netfs_requests_seq_next ( struct seq_file * m , void * v , loff_t * _pos )
{
return seq_list_next ( v , & netfs_io_requests , _pos ) ;
}
static void netfs_requests_seq_stop ( struct seq_file * m , void * v )
__releases ( rcu )
{
rcu_read_unlock ( ) ;
}
static const struct seq_operations netfs_requests_seq_ops = {
. start = netfs_requests_seq_start ,
. next = netfs_requests_seq_next ,
. stop = netfs_requests_seq_stop ,
. show = netfs_requests_seq_show ,
} ;
# endif /* CONFIG_PROC_FS */
2023-11-21 15:43:52 +00:00
static int __init netfs_init ( void )
{
int ret = - ENOMEM ;
if ( ! proc_mkdir ( " fs/netfs " , NULL ) )
goto error ;
2022-03-04 10:34:27 +00:00
if ( ! proc_create_seq ( " fs/netfs/requests " , S_IFREG | 0444 , NULL ,
& netfs_requests_seq_ops ) )
goto error_proc ;
2023-11-21 15:43:52 +00:00
# ifdef CONFIG_FSCACHE_STATS
if ( ! proc_create_single ( " fs/netfs/stats " , S_IFREG | 0444 , NULL ,
netfs_stats_show ) )
goto error_proc ;
# endif
ret = fscache_init ( ) ;
if ( ret < 0 )
goto error_proc ;
return 0 ;
error_proc :
remove_proc_entry ( " fs/netfs " , NULL ) ;
error :
return ret ;
}
fs_initcall ( netfs_init ) ;
static void __exit netfs_exit ( void )
{
fscache_exit ( ) ;
remove_proc_entry ( " fs/netfs " , NULL ) ;
}
module_exit ( netfs_exit ) ;