2015-07-17 17:38:13 +03:00
/*
* ( C ) 2001 Clemson University and The University of Chicago
*
* Changes by Acxiom Corporation to add proc file handler for pvfs2 client
* parameters , Copyright Acxiom Corporation , 2005.
*
* See COPYING in top - level directory .
*/
# include "protocol.h"
2015-12-04 20:56:14 +03:00
# include "orangefs-kernel.h"
# include "orangefs-debugfs.h"
# include "orangefs-sysfs.h"
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
/* ORANGEFS_VERSION is a ./configure define */
# ifndef ORANGEFS_VERSION
2016-01-13 19:34:59 +03:00
# define ORANGEFS_VERSION "upstream"
2015-07-17 17:38:13 +03:00
# endif
/*
* global variables declared here
*/
2016-08-15 22:33:42 +03:00
struct orangefs_stats orangefs_stats ;
2015-07-17 17:38:13 +03:00
/* the size of the hash tables for ops in progress */
int hash_table_size = 509 ;
static ulong module_parm_debug_mask ;
2016-08-15 18:38:36 +03:00
__u64 orangefs_gossip_debug_mask ;
2015-11-24 23:12:14 +03:00
int op_timeout_secs = ORANGEFS_DEFAULT_OP_TIMEOUT_SECS ;
int slot_timeout_secs = ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS ;
2016-08-16 18:38:14 +03:00
int orangefs_dcache_timeout_msecs = 50 ;
int orangefs_getattr_timeout_msecs = 50 ;
2015-07-17 17:38:13 +03:00
MODULE_LICENSE ( " GPL " ) ;
2015-11-24 23:12:14 +03:00
MODULE_AUTHOR ( " ORANGEFS Development Team " ) ;
MODULE_DESCRIPTION ( " The Linux Kernel VFS interface to ORANGEFS " ) ;
MODULE_PARM_DESC ( module_parm_debug_mask , " debugging level (see orangefs-debug.h for values) " ) ;
2015-07-17 17:38:13 +03:00
MODULE_PARM_DESC ( op_timeout_secs , " Operation timeout in seconds " ) ;
MODULE_PARM_DESC ( slot_timeout_secs , " Slot timeout in seconds " ) ;
MODULE_PARM_DESC ( hash_table_size ,
" size of hash table for operations in progress " ) ;
2015-11-24 23:12:14 +03:00
static struct file_system_type orangefs_fs_type = {
2015-07-17 17:38:13 +03:00
. name = " pvfs2 " ,
2015-11-24 23:12:14 +03:00
. mount = orangefs_mount ,
. kill_sb = orangefs_kill_sb ,
2015-07-17 17:38:13 +03:00
. owner = THIS_MODULE ,
} ;
module_param ( hash_table_size , int , 0 ) ;
2015-08-03 07:08:59 +03:00
module_param ( module_parm_debug_mask , ulong , 0644 ) ;
2015-07-17 17:38:13 +03:00
module_param ( op_timeout_secs , int , 0 ) ;
module_param ( slot_timeout_secs , int , 0 ) ;
/*
2015-10-05 20:44:24 +03:00
* Blocks non - priority requests from being queued for servicing . This
* could be used for protecting the request list data structure , but
* for now it ' s only being used to stall the op addition to the request
* list
*/
2016-08-16 18:38:14 +03:00
DEFINE_MUTEX ( orangefs_request_mutex ) ;
2015-07-17 17:38:13 +03:00
/* hash table for storing operations waiting for matching downcall */
2016-08-16 18:38:14 +03:00
struct list_head * orangefs_htable_ops_in_progress ;
DEFINE_SPINLOCK ( orangefs_htable_ops_in_progress_lock ) ;
2015-07-17 17:38:13 +03:00
/* list for queueing upcall operations */
2015-11-24 23:12:14 +03:00
LIST_HEAD ( orangefs_request_list ) ;
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
/* used to protect the above orangefs_request_list */
DEFINE_SPINLOCK ( orangefs_request_list_lock ) ;
2015-07-17 17:38:13 +03:00
/* used for incoming request notification */
2015-11-24 23:12:14 +03:00
DECLARE_WAIT_QUEUE_HEAD ( orangefs_request_list_waitq ) ;
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
static int __init orangefs_init ( void )
2015-07-17 17:38:13 +03:00
{
int ret = - 1 ;
__u32 i = 0 ;
2015-11-24 23:12:14 +03:00
ret = bdi_init ( & orangefs_backing_dev_info ) ;
2015-07-17 17:38:13 +03:00
if ( ret )
return ret ;
if ( op_timeout_secs < 0 )
op_timeout_secs = 0 ;
if ( slot_timeout_secs < 0 )
slot_timeout_secs = 0 ;
/* initialize global book keeping data structures */
ret = op_cache_initialize ( ) ;
if ( ret < 0 )
goto err ;
2015-11-24 23:12:14 +03:00
ret = orangefs_inode_cache_initialize ( ) ;
2015-07-17 17:38:13 +03:00
if ( ret < 0 )
2016-02-04 21:48:16 +03:00
goto cleanup_op ;
2015-07-17 17:38:13 +03:00
2016-08-16 18:38:14 +03:00
orangefs_htable_ops_in_progress =
2015-07-17 17:38:13 +03:00
kcalloc ( hash_table_size , sizeof ( struct list_head ) , GFP_KERNEL ) ;
2016-08-16 18:38:14 +03:00
if ( ! orangefs_htable_ops_in_progress ) {
2015-07-17 17:38:13 +03:00
gossip_err ( " Failed to initialize op hashtable " ) ;
ret = - ENOMEM ;
2016-03-17 20:20:35 +03:00
goto cleanup_inode ;
2015-07-17 17:38:13 +03:00
}
/* initialize a doubly linked at each hash table index */
for ( i = 0 ; i < hash_table_size ; i + + )
2016-08-16 18:38:14 +03:00
INIT_LIST_HEAD ( & orangefs_htable_ops_in_progress [ i ] ) ;
2015-07-17 17:38:13 +03:00
ret = fsid_key_table_initialize ( ) ;
if ( ret < 0 )
goto cleanup_progress_table ;
/*
* Build the contents of / sys / kernel / debug / orangefs / debug - help
* from the keywords in the kernel keyword / mask array .
*
* The keywords in the client keyword / mask array are
* unknown at boot time .
*
* orangefs_prepare_debugfs_help_string will be used again
2016-11-04 23:32:25 +03:00
* later to rebuild the debug - help - string after the client starts
2015-07-17 17:38:13 +03:00
* and passes along the needed info . The argument signifies
* which time orangefs_prepare_debugfs_help_string is being
* called .
*/
ret = orangefs_prepare_debugfs_help_string ( 1 ) ;
if ( ret )
2016-03-17 20:24:34 +03:00
goto cleanup_key_table ;
2016-03-14 22:30:39 +03:00
2016-08-15 18:38:36 +03:00
ret = orangefs_debugfs_init ( module_parm_debug_mask ) ;
2016-03-14 22:30:39 +03:00
if ( ret )
goto debugfs_init_failed ;
2015-07-17 17:38:13 +03:00
2016-03-14 22:30:39 +03:00
ret = orangefs_sysfs_init ( ) ;
if ( ret )
goto sysfs_init_failed ;
2015-07-17 17:38:13 +03:00
2016-03-17 20:20:35 +03:00
/* Initialize the orangefsdev subsystem. */
ret = orangefs_dev_init ( ) ;
if ( ret < 0 ) {
gossip_err ( " %s: could not initialize device subsystem %d! \n " ,
__func__ ,
ret ) ;
goto cleanup_device ;
}
2015-11-24 23:12:14 +03:00
ret = register_filesystem ( & orangefs_fs_type ) ;
2015-07-17 17:38:13 +03:00
if ( ret = = 0 ) {
2016-11-04 23:32:25 +03:00
pr_info ( " %s: module version %s loaded \n " ,
__func__ ,
ORANGEFS_VERSION ) ;
2016-03-14 22:30:39 +03:00
ret = 0 ;
goto out ;
2015-07-17 17:38:13 +03:00
}
orangefs_sysfs_exit ( ) ;
2016-03-17 20:20:35 +03:00
cleanup_device :
orangefs_dev_cleanup ( ) ;
2016-03-14 22:30:39 +03:00
sysfs_init_failed :
debugfs_init_failed :
orangefs_debugfs_cleanup ( ) ;
2016-03-17 20:24:34 +03:00
cleanup_key_table :
fsid_key_table_finalize ( ) ;
2016-03-14 22:30:39 +03:00
2015-07-17 17:38:13 +03:00
cleanup_progress_table :
2016-08-16 18:38:14 +03:00
kfree ( orangefs_htable_ops_in_progress ) ;
2015-07-17 17:38:13 +03:00
cleanup_inode :
2015-11-24 23:12:14 +03:00
orangefs_inode_cache_finalize ( ) ;
2015-07-17 17:38:13 +03:00
cleanup_op :
op_cache_finalize ( ) ;
err :
2015-11-24 23:12:14 +03:00
bdi_destroy ( & orangefs_backing_dev_info ) ;
2015-07-17 17:38:13 +03:00
out :
return ret ;
}
2015-11-24 23:12:14 +03:00
static void __exit orangefs_exit ( void )
2015-07-17 17:38:13 +03:00
{
int i = 0 ;
2015-11-24 23:12:14 +03:00
gossip_debug ( GOSSIP_INIT_DEBUG , " orangefs: orangefs_exit called \n " ) ;
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
unregister_filesystem ( & orangefs_fs_type ) ;
orangefs_debugfs_cleanup ( ) ;
2015-07-17 17:38:13 +03:00
orangefs_sysfs_exit ( ) ;
fsid_key_table_finalize ( ) ;
2015-11-24 23:12:14 +03:00
orangefs_dev_cleanup ( ) ;
2016-01-22 21:34:32 +03:00
BUG_ON ( ! list_empty ( & orangefs_request_list ) ) ;
2015-07-17 17:38:13 +03:00
for ( i = 0 ; i < hash_table_size ; i + + )
2016-08-16 18:38:14 +03:00
BUG_ON ( ! list_empty ( & orangefs_htable_ops_in_progress [ i ] ) ) ;
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
orangefs_inode_cache_finalize ( ) ;
2015-07-17 17:38:13 +03:00
op_cache_finalize ( ) ;
2016-08-16 18:38:14 +03:00
kfree ( orangefs_htable_ops_in_progress ) ;
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
bdi_destroy ( & orangefs_backing_dev_info ) ;
2015-07-17 17:38:13 +03:00
2015-11-24 23:12:14 +03:00
pr_info ( " orangefs: module version %s unloaded \n " , ORANGEFS_VERSION ) ;
2015-07-17 17:38:13 +03:00
}
/*
* What we do in this function is to walk the list of operations
* that are in progress in the hash table and mark them as purged as well .
*/
void purge_inprogress_ops ( void )
{
int i ;
for ( i = 0 ; i < hash_table_size ; i + + ) {
2015-11-24 23:12:14 +03:00
struct orangefs_kernel_op_s * op ;
struct orangefs_kernel_op_s * next ;
2015-07-17 17:38:13 +03:00
2016-08-16 18:38:14 +03:00
spin_lock ( & orangefs_htable_ops_in_progress_lock ) ;
2015-07-17 17:38:13 +03:00
list_for_each_entry_safe ( op ,
next ,
2016-08-16 18:38:14 +03:00
& orangefs_htable_ops_in_progress [ i ] ,
2015-07-17 17:38:13 +03:00
list ) {
set_op_state_purged ( op ) ;
2016-03-03 21:46:48 +03:00
gossip_debug ( GOSSIP_DEV_DEBUG ,
" %s: op:%s: op_state:%d: process:%s: \n " ,
__func__ ,
get_opname_string ( op ) ,
op - > op_state ,
current - > comm ) ;
2015-07-17 17:38:13 +03:00
}
2016-08-16 18:38:14 +03:00
spin_unlock ( & orangefs_htable_ops_in_progress_lock ) ;
2015-07-17 17:38:13 +03:00
}
}
2015-11-24 23:12:14 +03:00
module_init ( orangefs_init ) ;
module_exit ( orangefs_exit ) ;