17336d0e6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2b3b94faaSDavid Teigland /* 3b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 43a8a9a10SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 5b3b94faaSDavid Teigland */ 6b3b94faaSDavid Teigland 7d77d1b58SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8d77d1b58SJoe Perches 9b3b94faaSDavid Teigland #include <linux/slab.h> 10b3b94faaSDavid Teigland #include <linux/spinlock.h> 11b3b94faaSDavid Teigland #include <linux/completion.h> 12b3b94faaSDavid Teigland #include <linux/buffer_head.h> 13b3b94faaSDavid Teigland #include <linux/module.h> 14b3b94faaSDavid Teigland #include <linux/init.h> 155c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h> 16bc015cb8SSteven Whitehouse #include <linux/rcupdate.h> 17bc015cb8SSteven Whitehouse #include <linux/rculist_bl.h> 1860063497SArun Sharma #include <linux/atomic.h> 1975ca61c1SSteven Whitehouse #include <linux/mempool.h> 20b3b94faaSDavid Teigland 21b3b94faaSDavid Teigland #include "gfs2.h" 225c676f6dSSteven Whitehouse #include "incore.h" 23b2760583SSteven Whitehouse #include "super.h" 24b3b94faaSDavid Teigland #include "sys.h" 255c676f6dSSteven Whitehouse #include "util.h" 2685d1da67SSteven Whitehouse #include "glock.h" 270a7ab79cSAbhijith Das #include "quota.h" 286ecd7c2dSTejun Heo #include "recovery.h" 298d123585SSteven Whitehouse #include "dir.h" 302e60d768SBenjamin Marzinski #include "glops.h" 310a7ab79cSAbhijith Das 32e0c2a9aaSDavid Teigland struct workqueue_struct *gfs2_control_wq; 33e0c2a9aaSDavid Teigland 3451cc5068SAlexey Dobriyan static void gfs2_init_inode_once(void *foo) 35320dd101SSteven Whitehouse { 36320dd101SSteven Whitehouse struct gfs2_inode *ip = foo; 37a35afb83SChristoph Lameter 38320dd101SSteven Whitehouse inode_init_once(&ip->i_inode); 3921f09c43SAndreas Gruenbacher atomic_set(&ip->i_sizehint, 0); 40320dd101SSteven Whitehouse init_rwsem(&ip->i_rw_mutex); 41813e0c46SSteven Whitehouse INIT_LIST_HEAD(&ip->i_trunc_list); 427542486bSBob Peterson INIT_LIST_HEAD(&ip->i_ordered); 43b54e9a0bSBob Peterson ip->i_qadata = NULL; 4421f09c43SAndreas Gruenbacher gfs2_holder_mark_uninitialized(&ip->i_rgd_gh); 45a097dc7eSBob Peterson memset(&ip->i_res, 0, sizeof(ip->i_res)); 46a097dc7eSBob Peterson RB_CLEAR_NODE(&ip->i_res.rs_node); 4717d539f0SSteven Whitehouse ip->i_hash_cache = NULL; 486df9f9a2SAndreas Gruenbacher gfs2_holder_mark_uninitialized(&ip->i_iopen_gh); 49320dd101SSteven Whitehouse } 50320dd101SSteven Whitehouse 5151cc5068SAlexey Dobriyan static void gfs2_init_glock_once(void *foo) 52ec45d9f5SSteven Whitehouse { 53ec45d9f5SSteven Whitehouse struct gfs2_glock *gl = foo; 54a35afb83SChristoph Lameter 55f3dd1649SAndreas Gruenbacher spin_lock_init(&gl->gl_lockref.lock); 56ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_holders); 5797cc1025SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_lru); 58ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_ail_list); 59ec45d9f5SSteven Whitehouse atomic_set(&gl->gl_ail_count, 0); 60638803d4SBob Peterson atomic_set(&gl->gl_revokes, 0); 61ec45d9f5SSteven Whitehouse } 62ec45d9f5SSteven Whitehouse 63009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo) 64009d8518SSteven Whitehouse { 65*11d8b79eSKees Cook struct gfs2_glock_aspace *gla = foo; 66009d8518SSteven Whitehouse 67*11d8b79eSKees Cook gfs2_init_glock_once(&gla->glock); 68*11d8b79eSKees Cook address_space_init_once(&gla->mapping); 69009d8518SSteven Whitehouse } 70009d8518SSteven Whitehouse 71b3b94faaSDavid Teigland /** 72b3b94faaSDavid Teigland * init_gfs2_fs - Register GFS2 as a filesystem 73b3b94faaSDavid Teigland * 74b3b94faaSDavid Teigland * Returns: 0 on success, error code on failure 75b3b94faaSDavid Teigland */ 76b3b94faaSDavid Teigland 77b3b94faaSDavid Teigland static int __init init_gfs2_fs(void) 78b3b94faaSDavid Teigland { 79b3b94faaSDavid Teigland int error; 80b3b94faaSDavid Teigland 818d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdot, "."); 828d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdotdot, ".."); 83c754fbbbSSteven Whitehouse gfs2_quota_hash_init(); 848d123585SSteven Whitehouse 85b3b94faaSDavid Teigland error = gfs2_sys_init(); 86b3b94faaSDavid Teigland if (error) 87b3b94faaSDavid Teigland return error; 88b3b94faaSDavid Teigland 892147dbfdSSteven Whitehouse error = list_lru_init(&gfs2_qd_lru); 902147dbfdSSteven Whitehouse if (error) 912147dbfdSSteven Whitehouse goto fail_lru; 922147dbfdSSteven Whitehouse 9385d1da67SSteven Whitehouse error = gfs2_glock_init(); 9485d1da67SSteven Whitehouse if (error) 958b0d7f56STetsuo Handa goto fail_glock; 96b3b94faaSDavid Teigland 9785d1da67SSteven Whitehouse error = -ENOMEM; 98b3b94faaSDavid Teigland gfs2_glock_cachep = kmem_cache_create("gfs2_glock", 99b3b94faaSDavid Teigland sizeof(struct gfs2_glock), 10000e8e9bcSZhaoyang Huang 0, SLAB_RECLAIM_ACCOUNT, 10120c2df83SPaul Mundt gfs2_init_glock_once); 102b3b94faaSDavid Teigland if (!gfs2_glock_cachep) 1038b0d7f56STetsuo Handa goto fail_cachep1; 104b3b94faaSDavid Teigland 105009d8518SSteven Whitehouse gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)", 106*11d8b79eSKees Cook sizeof(struct gfs2_glock_aspace), 107009d8518SSteven Whitehouse 0, 0, gfs2_init_gl_aspace_once); 108009d8518SSteven Whitehouse 109009d8518SSteven Whitehouse if (!gfs2_glock_aspace_cachep) 1108b0d7f56STetsuo Handa goto fail_cachep2; 111009d8518SSteven Whitehouse 112b3b94faaSDavid Teigland gfs2_inode_cachep = kmem_cache_create("gfs2_inode", 113b3b94faaSDavid Teigland sizeof(struct gfs2_inode), 114eb1dc33aSAlexey Dobriyan 0, SLAB_RECLAIM_ACCOUNT| 1155d097056SVladimir Davydov SLAB_MEM_SPREAD| 1165d097056SVladimir Davydov SLAB_ACCOUNT, 11720c2df83SPaul Mundt gfs2_init_inode_once); 118b3b94faaSDavid Teigland if (!gfs2_inode_cachep) 1198b0d7f56STetsuo Handa goto fail_cachep3; 120b3b94faaSDavid Teigland 121b3b94faaSDavid Teigland gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata", 122b3b94faaSDavid Teigland sizeof(struct gfs2_bufdata), 12320c2df83SPaul Mundt 0, 0, NULL); 124b3b94faaSDavid Teigland if (!gfs2_bufdata_cachep) 1258b0d7f56STetsuo Handa goto fail_cachep4; 126b3b94faaSDavid Teigland 1276bdd9be6SBob Peterson gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd", 1286bdd9be6SBob Peterson sizeof(struct gfs2_rgrpd), 1296bdd9be6SBob Peterson 0, 0, NULL); 1306bdd9be6SBob Peterson if (!gfs2_rgrpd_cachep) 1318b0d7f56STetsuo Handa goto fail_cachep5; 1326bdd9be6SBob Peterson 13337b2c837SSteven Whitehouse gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad", 13437b2c837SSteven Whitehouse sizeof(struct gfs2_quota_data), 13500e8e9bcSZhaoyang Huang 0, SLAB_RECLAIM_ACCOUNT, NULL); 13637b2c837SSteven Whitehouse if (!gfs2_quotad_cachep) 1378b0d7f56STetsuo Handa goto fail_cachep6; 13837b2c837SSteven Whitehouse 139b54e9a0bSBob Peterson gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata", 140b54e9a0bSBob Peterson sizeof(struct gfs2_qadata), 141b54e9a0bSBob Peterson 0, 0, NULL); 142b54e9a0bSBob Peterson if (!gfs2_qadata_cachep) 1438b0d7f56STetsuo Handa goto fail_cachep7; 144b54e9a0bSBob Peterson 145b839dadaSBob Peterson gfs2_trans_cachep = kmem_cache_create("gfs2_trans", 146b839dadaSBob Peterson sizeof(struct gfs2_trans), 147b839dadaSBob Peterson 0, 0, NULL); 148b839dadaSBob Peterson if (!gfs2_trans_cachep) 149b839dadaSBob Peterson goto fail_cachep8; 150b839dadaSBob Peterson 151e0d735c1SChao Yu error = register_shrinker(&gfs2_qd_shrinker); 152e0d735c1SChao Yu if (error) 1538b0d7f56STetsuo Handa goto fail_shrinker; 1540a7ab79cSAbhijith Das 155b3b94faaSDavid Teigland error = register_filesystem(&gfs2_fs_type); 156b3b94faaSDavid Teigland if (error) 1578b0d7f56STetsuo Handa goto fail_fs1; 158b3b94faaSDavid Teigland 159419c93e0SSteven Whitehouse error = register_filesystem(&gfs2meta_fs_type); 160419c93e0SSteven Whitehouse if (error) 1618b0d7f56STetsuo Handa goto fail_fs2; 162419c93e0SSteven Whitehouse 1636ecd7c2dSTejun Heo error = -ENOMEM; 1646ecd7c2dSTejun Heo gfs_recovery_wq = alloc_workqueue("gfs_recovery", 16558a69cb4STejun Heo WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); 1666ecd7c2dSTejun Heo if (!gfs_recovery_wq) 1678b0d7f56STetsuo Handa goto fail_wq1; 168fe64d517SSteven Whitehouse 169e0c2a9aaSDavid Teigland gfs2_control_wq = alloc_workqueue("gfs2_control", 170d08fa65aSTejun Heo WQ_UNBOUND | WQ_FREEZABLE, 0); 171e0c2a9aaSDavid Teigland if (!gfs2_control_wq) 1728b0d7f56STetsuo Handa goto fail_wq2; 17375ca61c1SSteven Whitehouse 1742e60d768SBenjamin Marzinski gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0); 1752e60d768SBenjamin Marzinski 1762e60d768SBenjamin Marzinski if (!gfs2_freeze_wq) 1778b0d7f56STetsuo Handa goto fail_wq3; 1782e60d768SBenjamin Marzinski 179e8c92ed7SSteven Whitehouse gfs2_page_pool = mempool_create_page_pool(64, 0); 180e8c92ed7SSteven Whitehouse if (!gfs2_page_pool) 1818b0d7f56STetsuo Handa goto fail_mempool; 182e0c2a9aaSDavid Teigland 1832abbf9a4SGreg Kroah-Hartman gfs2_register_debugfs(); 1847c52b166SRobert Peterson 185fc554ed3SFabian Frederick pr_info("GFS2 installed\n"); 186b3b94faaSDavid Teigland 187b3b94faaSDavid Teigland return 0; 188b3b94faaSDavid Teigland 1898b0d7f56STetsuo Handa fail_mempool: 1902e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 1918b0d7f56STetsuo Handa fail_wq3: 19275ca61c1SSteven Whitehouse destroy_workqueue(gfs2_control_wq); 1938b0d7f56STetsuo Handa fail_wq2: 194e0c2a9aaSDavid Teigland destroy_workqueue(gfs_recovery_wq); 1958b0d7f56STetsuo Handa fail_wq1: 196fe64d517SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 1978b0d7f56STetsuo Handa fail_fs2: 198419c93e0SSteven Whitehouse unregister_filesystem(&gfs2_fs_type); 1998b0d7f56STetsuo Handa fail_fs1: 2008b0d7f56STetsuo Handa unregister_shrinker(&gfs2_qd_shrinker); 2018b0d7f56STetsuo Handa fail_shrinker: 202b839dadaSBob Peterson kmem_cache_destroy(gfs2_trans_cachep); 203b839dadaSBob Peterson fail_cachep8: 2048b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_qadata_cachep); 2058b0d7f56STetsuo Handa fail_cachep7: 2068b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_quotad_cachep); 2078b0d7f56STetsuo Handa fail_cachep6: 2088b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_rgrpd_cachep); 2098b0d7f56STetsuo Handa fail_cachep5: 2108b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_bufdata_cachep); 2118b0d7f56STetsuo Handa fail_cachep4: 2128b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_inode_cachep); 2138b0d7f56STetsuo Handa fail_cachep3: 2148b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_glock_aspace_cachep); 2158b0d7f56STetsuo Handa fail_cachep2: 2168b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_glock_cachep); 2178b0d7f56STetsuo Handa fail_cachep1: 2188b0d7f56STetsuo Handa gfs2_glock_exit(); 2198b0d7f56STetsuo Handa fail_glock: 2202147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 2212147dbfdSSteven Whitehouse fail_lru: 222b3b94faaSDavid Teigland gfs2_sys_uninit(); 223b3b94faaSDavid Teigland return error; 224b3b94faaSDavid Teigland } 225b3b94faaSDavid Teigland 226b3b94faaSDavid Teigland /** 227b3b94faaSDavid Teigland * exit_gfs2_fs - Unregister the file system 228b3b94faaSDavid Teigland * 229b3b94faaSDavid Teigland */ 230b3b94faaSDavid Teigland 231b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void) 232b3b94faaSDavid Teigland { 2332147dbfdSSteven Whitehouse unregister_shrinker(&gfs2_qd_shrinker); 2348fbbfd21SSteven Whitehouse gfs2_glock_exit(); 2357c52b166SRobert Peterson gfs2_unregister_debugfs(); 236b3b94faaSDavid Teigland unregister_filesystem(&gfs2_fs_type); 237419c93e0SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 2386ecd7c2dSTejun Heo destroy_workqueue(gfs_recovery_wq); 239e0c2a9aaSDavid Teigland destroy_workqueue(gfs2_control_wq); 2402e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 2412147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 242b3b94faaSDavid Teigland 243bc015cb8SSteven Whitehouse rcu_barrier(); 244bc015cb8SSteven Whitehouse 245e8c92ed7SSteven Whitehouse mempool_destroy(gfs2_page_pool); 246b839dadaSBob Peterson kmem_cache_destroy(gfs2_trans_cachep); 247b54e9a0bSBob Peterson kmem_cache_destroy(gfs2_qadata_cachep); 24837b2c837SSteven Whitehouse kmem_cache_destroy(gfs2_quotad_cachep); 2496bdd9be6SBob Peterson kmem_cache_destroy(gfs2_rgrpd_cachep); 250b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_bufdata_cachep); 251b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_inode_cachep); 252009d8518SSteven Whitehouse kmem_cache_destroy(gfs2_glock_aspace_cachep); 253b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_glock_cachep); 254b3b94faaSDavid Teigland 255b3b94faaSDavid Teigland gfs2_sys_uninit(); 256b3b94faaSDavid Teigland } 257b3b94faaSDavid Teigland 258b3b94faaSDavid Teigland MODULE_DESCRIPTION("Global File System"); 259b3b94faaSDavid Teigland MODULE_AUTHOR("Red Hat, Inc."); 260b3b94faaSDavid Teigland MODULE_LICENSE("GPL"); 261b3b94faaSDavid Teigland 262b3b94faaSDavid Teigland module_init(init_gfs2_fs); 263b3b94faaSDavid Teigland module_exit(exit_gfs2_fs); 264b3b94faaSDavid Teigland 265