2019-05-31 01:09:56 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2006-01-16 16:50:04 +00:00
/*
* Copyright ( C ) Sistina Software , Inc . 1997 - 2003 All rights reserved .
2006-05-18 15:09:15 -04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2006-01-16 16:50:04 +00:00
*/
2014-03-06 12:10:45 -08:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2006-01-16 16:50:04 +00:00
# include <linux/slab.h>
# include <linux/spinlock.h>
# include <linux/completion.h>
# include <linux/buffer_head.h>
# include <linux/module.h>
# include <linux/init.h>
2006-02-27 17:23:27 -05:00
# include <linux/gfs2_ondisk.h>
2011-01-19 09:30:01 +00:00
# include <linux/rcupdate.h>
# include <linux/rculist_bl.h>
2011-07-26 16:09:06 -07:00
# include <linux/atomic.h>
2012-03-08 12:10:23 +00:00
# include <linux/mempool.h>
2006-01-16 16:50:04 +00:00
# include "gfs2.h"
2006-02-27 17:23:27 -05:00
# include "incore.h"
2008-10-14 16:05:55 +01:00
# include "super.h"
2006-01-16 16:50:04 +00:00
# include "sys.h"
2006-02-27 17:23:27 -05:00
# include "util.h"
2006-09-07 14:40:21 -04:00
# include "glock.h"
2009-01-07 16:03:37 -06:00
# include "quota.h"
2010-07-20 22:09:02 +02:00
# include "recovery.h"
2010-09-17 12:30:23 +01:00
# include "dir.h"
2014-11-13 20:42:04 -06:00
# include "glops.h"
2009-01-07 16:03:37 -06:00
2012-01-09 17:18:05 -05:00
struct workqueue_struct * gfs2_control_wq ;
2008-07-25 19:45:34 -07:00
static void gfs2_init_inode_once ( void * foo )
2006-05-18 16:25:27 -04:00
{
struct gfs2_inode * ip = foo ;
2007-05-16 22:10:57 -07:00
inode_init_once ( & ip - > i_inode ) ;
2018-08-30 16:01:50 +01:00
atomic_set ( & ip - > i_sizehint , 0 ) ;
2007-05-16 22:10:57 -07:00
init_rwsem ( & ip - > i_rw_mutex ) ;
2008-11-18 13:38:48 +00:00
INIT_LIST_HEAD ( & ip - > i_trunc_list ) ;
2020-06-17 07:47:34 -05:00
INIT_LIST_HEAD ( & ip - > i_ordered ) ;
2015-10-26 10:40:28 -05:00
ip - > i_qadata = NULL ;
2018-08-30 16:01:50 +01:00
gfs2_holder_mark_uninitialized ( & ip - > i_rgd_gh ) ;
2015-07-16 08:28:04 -05:00
memset ( & ip - > i_res , 0 , sizeof ( ip - > i_res ) ) ;
RB_CLEAR_NODE ( & ip - > i_res . rs_node ) ;
2011-06-15 10:29:37 +01:00
ip - > i_hash_cache = NULL ;
2016-06-17 07:31:27 -05:00
gfs2_holder_mark_uninitialized ( & ip - > i_iopen_gh ) ;
2006-05-18 16:25:27 -04:00
}
2008-07-25 19:45:34 -07:00
static void gfs2_init_glock_once ( void * foo )
2006-08-30 10:36:52 -04:00
{
struct gfs2_glock * gl = foo ;
2007-05-16 22:10:57 -07:00
2015-10-29 10:58:09 -05:00
spin_lock_init ( & gl - > gl_lockref . lock ) ;
2007-05-16 22:10:57 -07:00
INIT_LIST_HEAD ( & gl - > gl_holders ) ;
2008-11-20 13:39:47 +00:00
INIT_LIST_HEAD ( & gl - > gl_lru ) ;
2007-05-16 22:10:57 -07:00
INIT_LIST_HEAD ( & gl - > gl_ail_list ) ;
atomic_set ( & gl - > gl_ail_count , 0 ) ;
2019-06-06 07:33:38 -05:00
atomic_set ( & gl - > gl_revokes , 0 ) ;
2006-08-30 10:36:52 -04:00
}
2009-12-08 12:12:13 +00:00
static void gfs2_init_gl_aspace_once ( void * foo )
{
2022-05-08 03:06:30 -07:00
struct gfs2_glock_aspace * gla = foo ;
2009-12-08 12:12:13 +00:00
2022-05-08 03:06:30 -07:00
gfs2_init_glock_once ( & gla - > glock ) ;
address_space_init_once ( & gla - > mapping ) ;
2009-12-08 12:12:13 +00:00
}
2006-01-16 16:50:04 +00:00
/**
* init_gfs2_fs - Register GFS2 as a filesystem
*
* Returns : 0 on success , error code on failure
*/
static int __init init_gfs2_fs ( void )
{
int error ;
2010-09-17 12:30:23 +01:00
gfs2_str2qstr ( & gfs2_qdot , " . " ) ;
gfs2_str2qstr ( & gfs2_qdotdot , " .. " ) ;
2013-12-12 10:47:59 +00:00
gfs2_quota_hash_init ( ) ;
2010-09-17 12:30:23 +01:00
2006-01-16 16:50:04 +00:00
error = gfs2_sys_init ( ) ;
if ( error )
return error ;
2013-11-04 10:15:08 +00:00
error = list_lru_init ( & gfs2_qd_lru ) ;
if ( error )
goto fail_lru ;
2006-09-07 14:40:21 -04:00
error = gfs2_glock_init ( ) ;
if ( error )
2017-11-27 08:56:34 -06:00
goto fail_glock ;
2006-01-16 16:50:04 +00:00
2006-09-07 14:40:21 -04:00
error = - ENOMEM ;
2006-01-16 16:50:04 +00:00
gfs2_glock_cachep = kmem_cache_create ( " gfs2_glock " ,
sizeof ( struct gfs2_glock ) ,
2021-01-05 07:48:00 -05:00
0 , SLAB_RECLAIM_ACCOUNT ,
2007-07-20 10:11:58 +09:00
gfs2_init_glock_once ) ;
2006-01-16 16:50:04 +00:00
if ( ! gfs2_glock_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep1 ;
2006-01-16 16:50:04 +00:00
2010-03-12 17:05:31 +00:00
gfs2_glock_aspace_cachep = kmem_cache_create ( " gfs2_glock(aspace) " ,
2022-05-08 03:06:30 -07:00
sizeof ( struct gfs2_glock_aspace ) ,
2009-12-08 12:12:13 +00:00
0 , 0 , gfs2_init_gl_aspace_once ) ;
if ( ! gfs2_glock_aspace_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep2 ;
2009-12-08 12:12:13 +00:00
2006-01-16 16:50:04 +00:00
gfs2_inode_cachep = kmem_cache_create ( " gfs2_inode " ,
sizeof ( struct gfs2_inode ) ,
2006-10-28 03:03:48 +04:00
0 , SLAB_RECLAIM_ACCOUNT |
2016-01-14 15:18:21 -08:00
SLAB_MEM_SPREAD |
SLAB_ACCOUNT ,
2007-07-20 10:11:58 +09:00
gfs2_init_inode_once ) ;
2006-01-16 16:50:04 +00:00
if ( ! gfs2_inode_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep3 ;
2006-01-16 16:50:04 +00:00
gfs2_bufdata_cachep = kmem_cache_create ( " gfs2_bufdata " ,
sizeof ( struct gfs2_bufdata ) ,
2007-07-20 10:11:58 +09:00
0 , 0 , NULL ) ;
2006-01-16 16:50:04 +00:00
if ( ! gfs2_bufdata_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep4 ;
2006-01-16 16:50:04 +00:00
2008-01-28 17:20:26 -06:00
gfs2_rgrpd_cachep = kmem_cache_create ( " gfs2_rgrpd " ,
sizeof ( struct gfs2_rgrpd ) ,
0 , 0 , NULL ) ;
if ( ! gfs2_rgrpd_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep5 ;
2008-01-28 17:20:26 -06:00
2008-11-17 14:25:37 +00:00
gfs2_quotad_cachep = kmem_cache_create ( " gfs2_quotad " ,
sizeof ( struct gfs2_quota_data ) ,
2021-01-05 07:48:00 -05:00
0 , SLAB_RECLAIM_ACCOUNT , NULL ) ;
2008-11-17 14:25:37 +00:00
if ( ! gfs2_quotad_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep6 ;
2008-11-17 14:25:37 +00:00
2015-10-26 10:40:28 -05:00
gfs2_qadata_cachep = kmem_cache_create ( " gfs2_qadata " ,
sizeof ( struct gfs2_qadata ) ,
0 , 0 , NULL ) ;
if ( ! gfs2_qadata_cachep )
2017-11-27 08:56:34 -06:00
goto fail_cachep7 ;
2015-10-26 10:40:28 -05:00
2019-04-17 12:04:27 -06:00
gfs2_trans_cachep = kmem_cache_create ( " gfs2_trans " ,
sizeof ( struct gfs2_trans ) ,
0 , 0 , NULL ) ;
if ( ! gfs2_trans_cachep )
goto fail_cachep8 ;
2016-09-21 12:09:40 -05:00
error = register_shrinker ( & gfs2_qd_shrinker ) ;
if ( error )
2017-11-27 08:56:34 -06:00
goto fail_shrinker ;
2009-01-07 16:03:37 -06:00
2006-01-16 16:50:04 +00:00
error = register_filesystem ( & gfs2_fs_type ) ;
if ( error )
2017-11-27 08:56:34 -06:00
goto fail_fs1 ;
2006-01-16 16:50:04 +00:00
2006-03-02 16:33:41 -05:00
error = register_filesystem ( & gfs2meta_fs_type ) ;
if ( error )
2017-11-27 08:56:34 -06:00
goto fail_fs2 ;
2006-03-02 16:33:41 -05:00
2010-07-20 22:09:02 +02:00
error = - ENOMEM ;
gfs_recovery_wq = alloc_workqueue ( " gfs_recovery " ,
2011-02-16 09:25:31 +01:00
WQ_MEM_RECLAIM | WQ_FREEZABLE , 0 ) ;
2010-07-20 22:09:02 +02:00
if ( ! gfs_recovery_wq )
2017-11-27 08:56:34 -06:00
goto fail_wq1 ;
2009-05-19 10:01:18 +01:00
2012-01-09 17:18:05 -05:00
gfs2_control_wq = alloc_workqueue ( " gfs2_control " ,
2013-07-30 08:40:25 -04:00
WQ_UNBOUND | WQ_FREEZABLE , 0 ) ;
2012-01-09 17:18:05 -05:00
if ( ! gfs2_control_wq )
2017-11-27 08:56:34 -06:00
goto fail_wq2 ;
2012-03-08 12:10:23 +00:00
2014-11-13 20:42:04 -06:00
gfs2_freeze_wq = alloc_workqueue ( " freeze_workqueue " , 0 , 0 ) ;
if ( ! gfs2_freeze_wq )
2017-11-27 08:56:34 -06:00
goto fail_wq3 ;
2014-11-13 20:42:04 -06:00
2012-04-16 09:28:31 +01:00
gfs2_page_pool = mempool_create_page_pool ( 64 , 0 ) ;
if ( ! gfs2_page_pool )
2017-11-27 08:56:34 -06:00
goto fail_mempool ;
2012-01-09 17:18:05 -05:00
2019-01-22 16:21:51 +01:00
gfs2_register_debugfs ( ) ;
2007-03-16 10:26:37 +00:00
2014-03-05 22:06:42 +08:00
pr_info ( " GFS2 installed \n " ) ;
2006-01-16 16:50:04 +00:00
return 0 ;
2017-11-27 08:56:34 -06:00
fail_mempool :
2014-11-13 20:42:04 -06:00
destroy_workqueue ( gfs2_freeze_wq ) ;
2017-11-27 08:56:34 -06:00
fail_wq3 :
2012-03-08 12:10:23 +00:00
destroy_workqueue ( gfs2_control_wq ) ;
2017-11-27 08:56:34 -06:00
fail_wq2 :
2012-01-09 17:18:05 -05:00
destroy_workqueue ( gfs_recovery_wq ) ;
2017-11-27 08:56:34 -06:00
fail_wq1 :
2009-05-19 10:01:18 +01:00
unregister_filesystem ( & gfs2meta_fs_type ) ;
2017-11-27 08:56:34 -06:00
fail_fs2 :
2006-03-02 16:33:41 -05:00
unregister_filesystem ( & gfs2_fs_type ) ;
2017-11-27 08:56:34 -06:00
fail_fs1 :
2013-11-04 10:15:08 +00:00
unregister_shrinker ( & gfs2_qd_shrinker ) ;
2017-11-27 08:56:34 -06:00
fail_shrinker :
2019-04-17 12:04:27 -06:00
kmem_cache_destroy ( gfs2_trans_cachep ) ;
fail_cachep8 :
2017-11-27 08:56:34 -06:00
kmem_cache_destroy ( gfs2_qadata_cachep ) ;
fail_cachep7 :
kmem_cache_destroy ( gfs2_quotad_cachep ) ;
fail_cachep6 :
kmem_cache_destroy ( gfs2_rgrpd_cachep ) ;
fail_cachep5 :
kmem_cache_destroy ( gfs2_bufdata_cachep ) ;
fail_cachep4 :
kmem_cache_destroy ( gfs2_inode_cachep ) ;
fail_cachep3 :
kmem_cache_destroy ( gfs2_glock_aspace_cachep ) ;
fail_cachep2 :
kmem_cache_destroy ( gfs2_glock_cachep ) ;
fail_cachep1 :
2007-08-01 13:57:10 +01:00
gfs2_glock_exit ( ) ;
2017-11-27 08:56:34 -06:00
fail_glock :
list_lru_destroy ( & gfs2_qd_lru ) ;
fail_lru :
2006-01-16 16:50:04 +00:00
gfs2_sys_uninit ( ) ;
return error ;
}
/**
* exit_gfs2_fs - Unregister the file system
*
*/
static void __exit exit_gfs2_fs ( void )
{
2013-11-04 10:15:08 +00:00
unregister_shrinker ( & gfs2_qd_shrinker ) ;
2007-08-01 13:57:10 +01:00
gfs2_glock_exit ( ) ;
2007-03-16 10:26:37 +00:00
gfs2_unregister_debugfs ( ) ;
2006-01-16 16:50:04 +00:00
unregister_filesystem ( & gfs2_fs_type ) ;
2006-03-02 16:33:41 -05:00
unregister_filesystem ( & gfs2meta_fs_type ) ;
2010-07-20 22:09:02 +02:00
destroy_workqueue ( gfs_recovery_wq ) ;
2012-01-09 17:18:05 -05:00
destroy_workqueue ( gfs2_control_wq ) ;
2014-11-13 20:42:04 -06:00
destroy_workqueue ( gfs2_freeze_wq ) ;
2013-11-04 10:15:08 +00:00
list_lru_destroy ( & gfs2_qd_lru ) ;
2006-01-16 16:50:04 +00:00
2011-01-19 09:30:01 +00:00
rcu_barrier ( ) ;
2012-04-16 09:28:31 +01:00
mempool_destroy ( gfs2_page_pool ) ;
2019-04-17 12:04:27 -06:00
kmem_cache_destroy ( gfs2_trans_cachep ) ;
2015-10-26 10:40:28 -05:00
kmem_cache_destroy ( gfs2_qadata_cachep ) ;
2008-11-17 14:25:37 +00:00
kmem_cache_destroy ( gfs2_quotad_cachep ) ;
2008-01-28 17:20:26 -06:00
kmem_cache_destroy ( gfs2_rgrpd_cachep ) ;
2006-01-16 16:50:04 +00:00
kmem_cache_destroy ( gfs2_bufdata_cachep ) ;
kmem_cache_destroy ( gfs2_inode_cachep ) ;
2009-12-08 12:12:13 +00:00
kmem_cache_destroy ( gfs2_glock_aspace_cachep ) ;
2006-01-16 16:50:04 +00:00
kmem_cache_destroy ( gfs2_glock_cachep ) ;
gfs2_sys_uninit ( ) ;
}
MODULE_DESCRIPTION ( " Global File System " ) ;
MODULE_AUTHOR ( " Red Hat, Inc. " ) ;
MODULE_LICENSE ( " GPL " ) ;
module_init ( init_gfs2_fs ) ;
module_exit ( exit_gfs2_fs ) ;