1b3b94faaSDavid Teigland /* 2b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 33a8a9a10SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4b3b94faaSDavid Teigland * 5b3b94faaSDavid Teigland * This copyrighted material is made available to anyone wishing to use, 6b3b94faaSDavid Teigland * modify, copy, or redistribute it subject to the terms and conditions 7e9fc2aa0SSteven Whitehouse * of the GNU General Public License version 2. 8b3b94faaSDavid Teigland */ 9b3b94faaSDavid Teigland 10d77d1b58SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11d77d1b58SJoe Perches 12b3b94faaSDavid Teigland #include <linux/slab.h> 13b3b94faaSDavid Teigland #include <linux/spinlock.h> 14b3b94faaSDavid Teigland #include <linux/completion.h> 15b3b94faaSDavid Teigland #include <linux/buffer_head.h> 16b3b94faaSDavid Teigland #include <linux/module.h> 17b3b94faaSDavid Teigland #include <linux/init.h> 185c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h> 19bc015cb8SSteven Whitehouse #include <linux/rcupdate.h> 20bc015cb8SSteven Whitehouse #include <linux/rculist_bl.h> 2160063497SArun Sharma #include <linux/atomic.h> 2275ca61c1SSteven Whitehouse #include <linux/mempool.h> 23b3b94faaSDavid Teigland 24b3b94faaSDavid Teigland #include "gfs2.h" 255c676f6dSSteven Whitehouse #include "incore.h" 26b2760583SSteven Whitehouse #include "super.h" 27b3b94faaSDavid Teigland #include "sys.h" 285c676f6dSSteven Whitehouse #include "util.h" 2985d1da67SSteven Whitehouse #include "glock.h" 300a7ab79cSAbhijith Das #include "quota.h" 316ecd7c2dSTejun Heo #include "recovery.h" 328d123585SSteven Whitehouse #include "dir.h" 332e60d768SBenjamin Marzinski #include "glops.h" 340a7ab79cSAbhijith Das 35e0c2a9aaSDavid Teigland struct workqueue_struct *gfs2_control_wq; 36e0c2a9aaSDavid Teigland 3751cc5068SAlexey Dobriyan static void gfs2_init_inode_once(void *foo) 38320dd101SSteven Whitehouse { 39320dd101SSteven Whitehouse struct gfs2_inode *ip = foo; 40a35afb83SChristoph Lameter 41320dd101SSteven Whitehouse inode_init_once(&ip->i_inode); 42320dd101SSteven Whitehouse init_rwsem(&ip->i_rw_mutex); 43813e0c46SSteven Whitehouse INIT_LIST_HEAD(&ip->i_trunc_list); 44b54e9a0bSBob Peterson ip->i_qadata = NULL; 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 55bc015cb8SSteven Whitehouse INIT_HLIST_BL_NODE(&gl->gl_list); 56f3dd1649SAndreas Gruenbacher spin_lock_init(&gl->gl_lockref.lock); 57ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_holders); 5897cc1025SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_lru); 59ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_ail_list); 60ec45d9f5SSteven Whitehouse atomic_set(&gl->gl_ail_count, 0); 61f42ab085SSteven Whitehouse atomic_set(&gl->gl_revokes, 0); 62ec45d9f5SSteven Whitehouse } 63ec45d9f5SSteven Whitehouse 64009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo) 65009d8518SSteven Whitehouse { 66009d8518SSteven Whitehouse struct gfs2_glock *gl = foo; 67009d8518SSteven Whitehouse struct address_space *mapping = (struct address_space *)(gl + 1); 68009d8518SSteven Whitehouse 69009d8518SSteven Whitehouse gfs2_init_glock_once(gl); 702aa15890SMiklos Szeredi address_space_init_once(mapping); 71009d8518SSteven Whitehouse } 72009d8518SSteven Whitehouse 73b3b94faaSDavid Teigland /** 74b3b94faaSDavid Teigland * init_gfs2_fs - Register GFS2 as a filesystem 75b3b94faaSDavid Teigland * 76b3b94faaSDavid Teigland * Returns: 0 on success, error code on failure 77b3b94faaSDavid Teigland */ 78b3b94faaSDavid Teigland 79b3b94faaSDavid Teigland static int __init init_gfs2_fs(void) 80b3b94faaSDavid Teigland { 81b3b94faaSDavid Teigland int error; 82b3b94faaSDavid Teigland 838d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdot, "."); 848d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdotdot, ".."); 85c754fbbbSSteven Whitehouse gfs2_quota_hash_init(); 868d123585SSteven Whitehouse 87b3b94faaSDavid Teigland error = gfs2_sys_init(); 88b3b94faaSDavid Teigland if (error) 89b3b94faaSDavid Teigland return error; 90b3b94faaSDavid Teigland 912147dbfdSSteven Whitehouse error = list_lru_init(&gfs2_qd_lru); 922147dbfdSSteven Whitehouse if (error) 932147dbfdSSteven Whitehouse goto fail_lru; 942147dbfdSSteven Whitehouse 9585d1da67SSteven Whitehouse error = gfs2_glock_init(); 9685d1da67SSteven Whitehouse if (error) 9785d1da67SSteven Whitehouse goto fail; 98b3b94faaSDavid Teigland 9985d1da67SSteven Whitehouse error = -ENOMEM; 100b3b94faaSDavid Teigland gfs2_glock_cachep = kmem_cache_create("gfs2_glock", 101b3b94faaSDavid Teigland sizeof(struct gfs2_glock), 102ec45d9f5SSteven Whitehouse 0, 0, 10320c2df83SPaul Mundt gfs2_init_glock_once); 104b3b94faaSDavid Teigland if (!gfs2_glock_cachep) 105b3b94faaSDavid Teigland goto fail; 106b3b94faaSDavid Teigland 107009d8518SSteven Whitehouse gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)", 108009d8518SSteven Whitehouse sizeof(struct gfs2_glock) + 109009d8518SSteven Whitehouse sizeof(struct address_space), 110009d8518SSteven Whitehouse 0, 0, gfs2_init_gl_aspace_once); 111009d8518SSteven Whitehouse 112009d8518SSteven Whitehouse if (!gfs2_glock_aspace_cachep) 113009d8518SSteven Whitehouse goto fail; 114009d8518SSteven Whitehouse 115b3b94faaSDavid Teigland gfs2_inode_cachep = kmem_cache_create("gfs2_inode", 116b3b94faaSDavid Teigland sizeof(struct gfs2_inode), 117eb1dc33aSAlexey Dobriyan 0, SLAB_RECLAIM_ACCOUNT| 1185d097056SVladimir Davydov SLAB_MEM_SPREAD| 1195d097056SVladimir Davydov SLAB_ACCOUNT, 12020c2df83SPaul Mundt gfs2_init_inode_once); 121b3b94faaSDavid Teigland if (!gfs2_inode_cachep) 122b3b94faaSDavid Teigland goto fail; 123b3b94faaSDavid Teigland 124b3b94faaSDavid Teigland gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata", 125b3b94faaSDavid Teigland sizeof(struct gfs2_bufdata), 12620c2df83SPaul Mundt 0, 0, NULL); 127b3b94faaSDavid Teigland if (!gfs2_bufdata_cachep) 128b3b94faaSDavid Teigland goto fail; 129b3b94faaSDavid Teigland 1306bdd9be6SBob Peterson gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd", 1316bdd9be6SBob Peterson sizeof(struct gfs2_rgrpd), 1326bdd9be6SBob Peterson 0, 0, NULL); 1336bdd9be6SBob Peterson if (!gfs2_rgrpd_cachep) 1346bdd9be6SBob Peterson goto fail; 1356bdd9be6SBob Peterson 13637b2c837SSteven Whitehouse gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad", 13737b2c837SSteven Whitehouse sizeof(struct gfs2_quota_data), 13837b2c837SSteven Whitehouse 0, 0, NULL); 13937b2c837SSteven Whitehouse if (!gfs2_quotad_cachep) 14037b2c837SSteven Whitehouse goto fail; 14137b2c837SSteven Whitehouse 142b54e9a0bSBob Peterson gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata", 143b54e9a0bSBob Peterson sizeof(struct gfs2_qadata), 144b54e9a0bSBob Peterson 0, 0, NULL); 145b54e9a0bSBob Peterson if (!gfs2_qadata_cachep) 146b54e9a0bSBob Peterson goto fail; 147b54e9a0bSBob Peterson 148e0d735c1SChao Yu error = register_shrinker(&gfs2_qd_shrinker); 149e0d735c1SChao Yu if (error) 150e0d735c1SChao Yu goto fail; 1510a7ab79cSAbhijith Das 152b3b94faaSDavid Teigland error = register_filesystem(&gfs2_fs_type); 153b3b94faaSDavid Teigland if (error) 154b3b94faaSDavid Teigland goto fail; 155b3b94faaSDavid Teigland 156419c93e0SSteven Whitehouse error = register_filesystem(&gfs2meta_fs_type); 157419c93e0SSteven Whitehouse if (error) 158419c93e0SSteven Whitehouse goto fail_unregister; 159419c93e0SSteven Whitehouse 1606ecd7c2dSTejun Heo error = -ENOMEM; 1616ecd7c2dSTejun Heo gfs_recovery_wq = alloc_workqueue("gfs_recovery", 16258a69cb4STejun Heo WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); 1636ecd7c2dSTejun Heo if (!gfs_recovery_wq) 1646ecd7c2dSTejun Heo goto fail_wq; 165fe64d517SSteven Whitehouse 166e0c2a9aaSDavid Teigland gfs2_control_wq = alloc_workqueue("gfs2_control", 167d08fa65aSTejun Heo WQ_UNBOUND | WQ_FREEZABLE, 0); 168e0c2a9aaSDavid Teigland if (!gfs2_control_wq) 16975ca61c1SSteven Whitehouse goto fail_recovery; 17075ca61c1SSteven Whitehouse 1712e60d768SBenjamin Marzinski gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0); 1722e60d768SBenjamin Marzinski 1732e60d768SBenjamin Marzinski if (!gfs2_freeze_wq) 1742e60d768SBenjamin Marzinski goto fail_control; 1752e60d768SBenjamin Marzinski 176e8c92ed7SSteven Whitehouse gfs2_page_pool = mempool_create_page_pool(64, 0); 177e8c92ed7SSteven Whitehouse if (!gfs2_page_pool) 1782e60d768SBenjamin Marzinski goto fail_freeze; 179e0c2a9aaSDavid Teigland 1807c52b166SRobert Peterson gfs2_register_debugfs(); 1817c52b166SRobert Peterson 182fc554ed3SFabian Frederick pr_info("GFS2 installed\n"); 183b3b94faaSDavid Teigland 184b3b94faaSDavid Teigland return 0; 185b3b94faaSDavid Teigland 1862e60d768SBenjamin Marzinski fail_freeze: 1872e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 188e0c2a9aaSDavid Teigland fail_control: 18975ca61c1SSteven Whitehouse destroy_workqueue(gfs2_control_wq); 19075ca61c1SSteven Whitehouse fail_recovery: 191e0c2a9aaSDavid Teigland destroy_workqueue(gfs_recovery_wq); 1926ecd7c2dSTejun Heo fail_wq: 193fe64d517SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 194419c93e0SSteven Whitehouse fail_unregister: 195419c93e0SSteven Whitehouse unregister_filesystem(&gfs2_fs_type); 196b3b94faaSDavid Teigland fail: 1972147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 1982147dbfdSSteven Whitehouse fail_lru: 1992147dbfdSSteven Whitehouse unregister_shrinker(&gfs2_qd_shrinker); 2008fbbfd21SSteven Whitehouse gfs2_glock_exit(); 2018fbbfd21SSteven Whitehouse 202b54e9a0bSBob Peterson if (gfs2_qadata_cachep) 203b54e9a0bSBob Peterson kmem_cache_destroy(gfs2_qadata_cachep); 204b54e9a0bSBob Peterson 20537b2c837SSteven Whitehouse if (gfs2_quotad_cachep) 20637b2c837SSteven Whitehouse kmem_cache_destroy(gfs2_quotad_cachep); 20737b2c837SSteven Whitehouse 2086bdd9be6SBob Peterson if (gfs2_rgrpd_cachep) 2096bdd9be6SBob Peterson kmem_cache_destroy(gfs2_rgrpd_cachep); 2106bdd9be6SBob Peterson 211b3b94faaSDavid Teigland if (gfs2_bufdata_cachep) 212b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_bufdata_cachep); 213b3b94faaSDavid Teigland 214b3b94faaSDavid Teigland if (gfs2_inode_cachep) 215b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_inode_cachep); 216b3b94faaSDavid Teigland 217009d8518SSteven Whitehouse if (gfs2_glock_aspace_cachep) 218009d8518SSteven Whitehouse kmem_cache_destroy(gfs2_glock_aspace_cachep); 219009d8518SSteven Whitehouse 220b3b94faaSDavid Teigland if (gfs2_glock_cachep) 221b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_glock_cachep); 222b3b94faaSDavid Teigland 223b3b94faaSDavid Teigland gfs2_sys_uninit(); 224b3b94faaSDavid Teigland return error; 225b3b94faaSDavid Teigland } 226b3b94faaSDavid Teigland 227b3b94faaSDavid Teigland /** 228b3b94faaSDavid Teigland * exit_gfs2_fs - Unregister the file system 229b3b94faaSDavid Teigland * 230b3b94faaSDavid Teigland */ 231b3b94faaSDavid Teigland 232b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void) 233b3b94faaSDavid Teigland { 2342147dbfdSSteven Whitehouse unregister_shrinker(&gfs2_qd_shrinker); 2358fbbfd21SSteven Whitehouse gfs2_glock_exit(); 2367c52b166SRobert Peterson gfs2_unregister_debugfs(); 237b3b94faaSDavid Teigland unregister_filesystem(&gfs2_fs_type); 238419c93e0SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 2396ecd7c2dSTejun Heo destroy_workqueue(gfs_recovery_wq); 240e0c2a9aaSDavid Teigland destroy_workqueue(gfs2_control_wq); 2412e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 2422147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 243b3b94faaSDavid Teigland 244bc015cb8SSteven Whitehouse rcu_barrier(); 245bc015cb8SSteven Whitehouse 246e8c92ed7SSteven Whitehouse mempool_destroy(gfs2_page_pool); 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