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); 42b54e9a0bSBob Peterson ip->i_qadata = NULL; 4321f09c43SAndreas Gruenbacher gfs2_holder_mark_uninitialized(&ip->i_rgd_gh); 44a097dc7eSBob Peterson memset(&ip->i_res, 0, sizeof(ip->i_res)); 45a097dc7eSBob Peterson RB_CLEAR_NODE(&ip->i_res.rs_node); 4617d539f0SSteven Whitehouse ip->i_hash_cache = NULL; 476df9f9a2SAndreas Gruenbacher gfs2_holder_mark_uninitialized(&ip->i_iopen_gh); 48320dd101SSteven Whitehouse } 49320dd101SSteven Whitehouse 5051cc5068SAlexey Dobriyan static void gfs2_init_glock_once(void *foo) 51ec45d9f5SSteven Whitehouse { 52ec45d9f5SSteven Whitehouse struct gfs2_glock *gl = foo; 53a35afb83SChristoph Lameter 54f3dd1649SAndreas Gruenbacher spin_lock_init(&gl->gl_lockref.lock); 55ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_holders); 5697cc1025SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_lru); 57ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_ail_list); 58ec45d9f5SSteven Whitehouse atomic_set(&gl->gl_ail_count, 0); 59ec45d9f5SSteven Whitehouse } 60ec45d9f5SSteven Whitehouse 61009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo) 62009d8518SSteven Whitehouse { 63009d8518SSteven Whitehouse struct gfs2_glock *gl = foo; 64009d8518SSteven Whitehouse struct address_space *mapping = (struct address_space *)(gl + 1); 65009d8518SSteven Whitehouse 66009d8518SSteven Whitehouse gfs2_init_glock_once(gl); 672aa15890SMiklos Szeredi address_space_init_once(mapping); 68009d8518SSteven Whitehouse } 69009d8518SSteven Whitehouse 70b3b94faaSDavid Teigland /** 71b3b94faaSDavid Teigland * init_gfs2_fs - Register GFS2 as a filesystem 72b3b94faaSDavid Teigland * 73b3b94faaSDavid Teigland * Returns: 0 on success, error code on failure 74b3b94faaSDavid Teigland */ 75b3b94faaSDavid Teigland 76b3b94faaSDavid Teigland static int __init init_gfs2_fs(void) 77b3b94faaSDavid Teigland { 78b3b94faaSDavid Teigland int error; 79b3b94faaSDavid Teigland 808d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdot, "."); 818d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdotdot, ".."); 82c754fbbbSSteven Whitehouse gfs2_quota_hash_init(); 838d123585SSteven Whitehouse 84b3b94faaSDavid Teigland error = gfs2_sys_init(); 85b3b94faaSDavid Teigland if (error) 86b3b94faaSDavid Teigland return error; 87b3b94faaSDavid Teigland 882147dbfdSSteven Whitehouse error = list_lru_init(&gfs2_qd_lru); 892147dbfdSSteven Whitehouse if (error) 902147dbfdSSteven Whitehouse goto fail_lru; 912147dbfdSSteven Whitehouse 9285d1da67SSteven Whitehouse error = gfs2_glock_init(); 9385d1da67SSteven Whitehouse if (error) 948b0d7f56STetsuo Handa goto fail_glock; 95b3b94faaSDavid Teigland 9685d1da67SSteven Whitehouse error = -ENOMEM; 97b3b94faaSDavid Teigland gfs2_glock_cachep = kmem_cache_create("gfs2_glock", 98b3b94faaSDavid Teigland sizeof(struct gfs2_glock), 99ec45d9f5SSteven Whitehouse 0, 0, 10020c2df83SPaul Mundt gfs2_init_glock_once); 101b3b94faaSDavid Teigland if (!gfs2_glock_cachep) 1028b0d7f56STetsuo Handa goto fail_cachep1; 103b3b94faaSDavid Teigland 104009d8518SSteven Whitehouse gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)", 105009d8518SSteven Whitehouse sizeof(struct gfs2_glock) + 106009d8518SSteven Whitehouse sizeof(struct address_space), 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), 13537b2c837SSteven Whitehouse 0, 0, 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 145e0d735c1SChao Yu error = register_shrinker(&gfs2_qd_shrinker); 146e0d735c1SChao Yu if (error) 1478b0d7f56STetsuo Handa goto fail_shrinker; 1480a7ab79cSAbhijith Das 149b3b94faaSDavid Teigland error = register_filesystem(&gfs2_fs_type); 150b3b94faaSDavid Teigland if (error) 1518b0d7f56STetsuo Handa goto fail_fs1; 152b3b94faaSDavid Teigland 153419c93e0SSteven Whitehouse error = register_filesystem(&gfs2meta_fs_type); 154419c93e0SSteven Whitehouse if (error) 1558b0d7f56STetsuo Handa goto fail_fs2; 156419c93e0SSteven Whitehouse 1576ecd7c2dSTejun Heo error = -ENOMEM; 1586ecd7c2dSTejun Heo gfs_recovery_wq = alloc_workqueue("gfs_recovery", 15958a69cb4STejun Heo WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); 1606ecd7c2dSTejun Heo if (!gfs_recovery_wq) 1618b0d7f56STetsuo Handa goto fail_wq1; 162fe64d517SSteven Whitehouse 163e0c2a9aaSDavid Teigland gfs2_control_wq = alloc_workqueue("gfs2_control", 164d08fa65aSTejun Heo WQ_UNBOUND | WQ_FREEZABLE, 0); 165e0c2a9aaSDavid Teigland if (!gfs2_control_wq) 1668b0d7f56STetsuo Handa goto fail_wq2; 16775ca61c1SSteven Whitehouse 1682e60d768SBenjamin Marzinski gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0); 1692e60d768SBenjamin Marzinski 1702e60d768SBenjamin Marzinski if (!gfs2_freeze_wq) 1718b0d7f56STetsuo Handa goto fail_wq3; 1722e60d768SBenjamin Marzinski 173e8c92ed7SSteven Whitehouse gfs2_page_pool = mempool_create_page_pool(64, 0); 174e8c92ed7SSteven Whitehouse if (!gfs2_page_pool) 1758b0d7f56STetsuo Handa goto fail_mempool; 176e0c2a9aaSDavid Teigland 1772abbf9a4SGreg Kroah-Hartman gfs2_register_debugfs(); 1787c52b166SRobert Peterson 179fc554ed3SFabian Frederick pr_info("GFS2 installed\n"); 180b3b94faaSDavid Teigland 181b3b94faaSDavid Teigland return 0; 182b3b94faaSDavid Teigland 1838b0d7f56STetsuo Handa fail_mempool: 1842e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 1858b0d7f56STetsuo Handa fail_wq3: 18675ca61c1SSteven Whitehouse destroy_workqueue(gfs2_control_wq); 1878b0d7f56STetsuo Handa fail_wq2: 188e0c2a9aaSDavid Teigland destroy_workqueue(gfs_recovery_wq); 1898b0d7f56STetsuo Handa fail_wq1: 190fe64d517SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 1918b0d7f56STetsuo Handa fail_fs2: 192419c93e0SSteven Whitehouse unregister_filesystem(&gfs2_fs_type); 1938b0d7f56STetsuo Handa fail_fs1: 1948b0d7f56STetsuo Handa unregister_shrinker(&gfs2_qd_shrinker); 1958b0d7f56STetsuo Handa fail_shrinker: 1968b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_qadata_cachep); 1978b0d7f56STetsuo Handa fail_cachep7: 1988b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_quotad_cachep); 1998b0d7f56STetsuo Handa fail_cachep6: 2008b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_rgrpd_cachep); 2018b0d7f56STetsuo Handa fail_cachep5: 2028b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_bufdata_cachep); 2038b0d7f56STetsuo Handa fail_cachep4: 2048b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_inode_cachep); 2058b0d7f56STetsuo Handa fail_cachep3: 2068b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_glock_aspace_cachep); 2078b0d7f56STetsuo Handa fail_cachep2: 2088b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_glock_cachep); 2098b0d7f56STetsuo Handa fail_cachep1: 2108b0d7f56STetsuo Handa gfs2_glock_exit(); 2118b0d7f56STetsuo Handa fail_glock: 2122147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 2132147dbfdSSteven Whitehouse fail_lru: 214b3b94faaSDavid Teigland gfs2_sys_uninit(); 215b3b94faaSDavid Teigland return error; 216b3b94faaSDavid Teigland } 217b3b94faaSDavid Teigland 218b3b94faaSDavid Teigland /** 219b3b94faaSDavid Teigland * exit_gfs2_fs - Unregister the file system 220b3b94faaSDavid Teigland * 221b3b94faaSDavid Teigland */ 222b3b94faaSDavid Teigland 223b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void) 224b3b94faaSDavid Teigland { 2252147dbfdSSteven Whitehouse unregister_shrinker(&gfs2_qd_shrinker); 2268fbbfd21SSteven Whitehouse gfs2_glock_exit(); 2277c52b166SRobert Peterson gfs2_unregister_debugfs(); 228b3b94faaSDavid Teigland unregister_filesystem(&gfs2_fs_type); 229419c93e0SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 2306ecd7c2dSTejun Heo destroy_workqueue(gfs_recovery_wq); 231e0c2a9aaSDavid Teigland destroy_workqueue(gfs2_control_wq); 2322e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 2332147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 234b3b94faaSDavid Teigland 235bc015cb8SSteven Whitehouse rcu_barrier(); 236bc015cb8SSteven Whitehouse 237e8c92ed7SSteven Whitehouse mempool_destroy(gfs2_page_pool); 238b54e9a0bSBob Peterson kmem_cache_destroy(gfs2_qadata_cachep); 23937b2c837SSteven Whitehouse kmem_cache_destroy(gfs2_quotad_cachep); 2406bdd9be6SBob Peterson kmem_cache_destroy(gfs2_rgrpd_cachep); 241b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_bufdata_cachep); 242b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_inode_cachep); 243009d8518SSteven Whitehouse kmem_cache_destroy(gfs2_glock_aspace_cachep); 244b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_glock_cachep); 245b3b94faaSDavid Teigland 246b3b94faaSDavid Teigland gfs2_sys_uninit(); 247b3b94faaSDavid Teigland } 248b3b94faaSDavid Teigland 249b3b94faaSDavid Teigland MODULE_DESCRIPTION("Global File System"); 250b3b94faaSDavid Teigland MODULE_AUTHOR("Red Hat, Inc."); 251b3b94faaSDavid Teigland MODULE_LICENSE("GPL"); 252b3b94faaSDavid Teigland 253b3b94faaSDavid Teigland module_init(init_gfs2_fs); 254b3b94faaSDavid Teigland module_exit(exit_gfs2_fs); 255b3b94faaSDavid Teigland 256