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); 4221f09c43SAndreas Gruenbacher atomic_set(&ip->i_sizehint, 0); 43320dd101SSteven Whitehouse init_rwsem(&ip->i_rw_mutex); 44813e0c46SSteven Whitehouse INIT_LIST_HEAD(&ip->i_trunc_list); 45b54e9a0bSBob Peterson ip->i_qadata = NULL; 4621f09c43SAndreas Gruenbacher gfs2_holder_mark_uninitialized(&ip->i_rgd_gh); 47a097dc7eSBob Peterson memset(&ip->i_res, 0, sizeof(ip->i_res)); 48a097dc7eSBob Peterson RB_CLEAR_NODE(&ip->i_res.rs_node); 4917d539f0SSteven Whitehouse ip->i_hash_cache = NULL; 506df9f9a2SAndreas Gruenbacher gfs2_holder_mark_uninitialized(&ip->i_iopen_gh); 51320dd101SSteven Whitehouse } 52320dd101SSteven Whitehouse 5351cc5068SAlexey Dobriyan static void gfs2_init_glock_once(void *foo) 54ec45d9f5SSteven Whitehouse { 55ec45d9f5SSteven Whitehouse struct gfs2_glock *gl = foo; 56a35afb83SChristoph Lameter 57f3dd1649SAndreas Gruenbacher spin_lock_init(&gl->gl_lockref.lock); 58ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_holders); 5997cc1025SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_lru); 60ec45d9f5SSteven Whitehouse INIT_LIST_HEAD(&gl->gl_ail_list); 61ec45d9f5SSteven Whitehouse atomic_set(&gl->gl_ail_count, 0); 62f42ab085SSteven Whitehouse atomic_set(&gl->gl_revokes, 0); 63ec45d9f5SSteven Whitehouse } 64ec45d9f5SSteven Whitehouse 65009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo) 66009d8518SSteven Whitehouse { 67009d8518SSteven Whitehouse struct gfs2_glock *gl = foo; 68009d8518SSteven Whitehouse struct address_space *mapping = (struct address_space *)(gl + 1); 69009d8518SSteven Whitehouse 70009d8518SSteven Whitehouse gfs2_init_glock_once(gl); 712aa15890SMiklos Szeredi address_space_init_once(mapping); 72009d8518SSteven Whitehouse } 73009d8518SSteven Whitehouse 74b3b94faaSDavid Teigland /** 75b3b94faaSDavid Teigland * init_gfs2_fs - Register GFS2 as a filesystem 76b3b94faaSDavid Teigland * 77b3b94faaSDavid Teigland * Returns: 0 on success, error code on failure 78b3b94faaSDavid Teigland */ 79b3b94faaSDavid Teigland 80b3b94faaSDavid Teigland static int __init init_gfs2_fs(void) 81b3b94faaSDavid Teigland { 82b3b94faaSDavid Teigland int error; 83b3b94faaSDavid Teigland 848d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdot, "."); 858d123585SSteven Whitehouse gfs2_str2qstr(&gfs2_qdotdot, ".."); 86c754fbbbSSteven Whitehouse gfs2_quota_hash_init(); 878d123585SSteven Whitehouse 88b3b94faaSDavid Teigland error = gfs2_sys_init(); 89b3b94faaSDavid Teigland if (error) 90b3b94faaSDavid Teigland return error; 91b3b94faaSDavid Teigland 922147dbfdSSteven Whitehouse error = list_lru_init(&gfs2_qd_lru); 932147dbfdSSteven Whitehouse if (error) 942147dbfdSSteven Whitehouse goto fail_lru; 952147dbfdSSteven Whitehouse 9685d1da67SSteven Whitehouse error = gfs2_glock_init(); 9785d1da67SSteven Whitehouse if (error) 988b0d7f56STetsuo Handa goto fail_glock; 99b3b94faaSDavid Teigland 10085d1da67SSteven Whitehouse error = -ENOMEM; 101b3b94faaSDavid Teigland gfs2_glock_cachep = kmem_cache_create("gfs2_glock", 102b3b94faaSDavid Teigland sizeof(struct gfs2_glock), 103ec45d9f5SSteven Whitehouse 0, 0, 10420c2df83SPaul Mundt gfs2_init_glock_once); 105b3b94faaSDavid Teigland if (!gfs2_glock_cachep) 1068b0d7f56STetsuo Handa goto fail_cachep1; 107b3b94faaSDavid Teigland 108009d8518SSteven Whitehouse gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)", 109009d8518SSteven Whitehouse sizeof(struct gfs2_glock) + 110009d8518SSteven Whitehouse sizeof(struct address_space), 111009d8518SSteven Whitehouse 0, 0, gfs2_init_gl_aspace_once); 112009d8518SSteven Whitehouse 113009d8518SSteven Whitehouse if (!gfs2_glock_aspace_cachep) 1148b0d7f56STetsuo Handa goto fail_cachep2; 115009d8518SSteven Whitehouse 116b3b94faaSDavid Teigland gfs2_inode_cachep = kmem_cache_create("gfs2_inode", 117b3b94faaSDavid Teigland sizeof(struct gfs2_inode), 118eb1dc33aSAlexey Dobriyan 0, SLAB_RECLAIM_ACCOUNT| 1195d097056SVladimir Davydov SLAB_MEM_SPREAD| 1205d097056SVladimir Davydov SLAB_ACCOUNT, 12120c2df83SPaul Mundt gfs2_init_inode_once); 122b3b94faaSDavid Teigland if (!gfs2_inode_cachep) 1238b0d7f56STetsuo Handa goto fail_cachep3; 124b3b94faaSDavid Teigland 125b3b94faaSDavid Teigland gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata", 126b3b94faaSDavid Teigland sizeof(struct gfs2_bufdata), 12720c2df83SPaul Mundt 0, 0, NULL); 128b3b94faaSDavid Teigland if (!gfs2_bufdata_cachep) 1298b0d7f56STetsuo Handa goto fail_cachep4; 130b3b94faaSDavid Teigland 1316bdd9be6SBob Peterson gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd", 1326bdd9be6SBob Peterson sizeof(struct gfs2_rgrpd), 1336bdd9be6SBob Peterson 0, 0, NULL); 1346bdd9be6SBob Peterson if (!gfs2_rgrpd_cachep) 1358b0d7f56STetsuo Handa goto fail_cachep5; 1366bdd9be6SBob Peterson 13737b2c837SSteven Whitehouse gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad", 13837b2c837SSteven Whitehouse sizeof(struct gfs2_quota_data), 13937b2c837SSteven Whitehouse 0, 0, NULL); 14037b2c837SSteven Whitehouse if (!gfs2_quotad_cachep) 1418b0d7f56STetsuo Handa goto fail_cachep6; 14237b2c837SSteven Whitehouse 143b54e9a0bSBob Peterson gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata", 144b54e9a0bSBob Peterson sizeof(struct gfs2_qadata), 145b54e9a0bSBob Peterson 0, 0, NULL); 146b54e9a0bSBob Peterson if (!gfs2_qadata_cachep) 1478b0d7f56STetsuo Handa goto fail_cachep7; 148b54e9a0bSBob Peterson 149e0d735c1SChao Yu error = register_shrinker(&gfs2_qd_shrinker); 150e0d735c1SChao Yu if (error) 1518b0d7f56STetsuo Handa goto fail_shrinker; 1520a7ab79cSAbhijith Das 153b3b94faaSDavid Teigland error = register_filesystem(&gfs2_fs_type); 154b3b94faaSDavid Teigland if (error) 1558b0d7f56STetsuo Handa goto fail_fs1; 156b3b94faaSDavid Teigland 157419c93e0SSteven Whitehouse error = register_filesystem(&gfs2meta_fs_type); 158419c93e0SSteven Whitehouse if (error) 1598b0d7f56STetsuo Handa goto fail_fs2; 160419c93e0SSteven Whitehouse 1616ecd7c2dSTejun Heo error = -ENOMEM; 1626ecd7c2dSTejun Heo gfs_recovery_wq = alloc_workqueue("gfs_recovery", 16358a69cb4STejun Heo WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); 1646ecd7c2dSTejun Heo if (!gfs_recovery_wq) 1658b0d7f56STetsuo Handa goto fail_wq1; 166fe64d517SSteven Whitehouse 167e0c2a9aaSDavid Teigland gfs2_control_wq = alloc_workqueue("gfs2_control", 168d08fa65aSTejun Heo WQ_UNBOUND | WQ_FREEZABLE, 0); 169e0c2a9aaSDavid Teigland if (!gfs2_control_wq) 1708b0d7f56STetsuo Handa goto fail_wq2; 17175ca61c1SSteven Whitehouse 1722e60d768SBenjamin Marzinski gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0); 1732e60d768SBenjamin Marzinski 1742e60d768SBenjamin Marzinski if (!gfs2_freeze_wq) 1758b0d7f56STetsuo Handa goto fail_wq3; 1762e60d768SBenjamin Marzinski 177e8c92ed7SSteven Whitehouse gfs2_page_pool = mempool_create_page_pool(64, 0); 178e8c92ed7SSteven Whitehouse if (!gfs2_page_pool) 1798b0d7f56STetsuo Handa goto fail_mempool; 180e0c2a9aaSDavid Teigland 1812abbf9a4SGreg Kroah-Hartman gfs2_register_debugfs(); 1827c52b166SRobert Peterson 183fc554ed3SFabian Frederick pr_info("GFS2 installed\n"); 184b3b94faaSDavid Teigland 185b3b94faaSDavid Teigland return 0; 186b3b94faaSDavid Teigland 1878b0d7f56STetsuo Handa fail_mempool: 1882e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 1898b0d7f56STetsuo Handa fail_wq3: 19075ca61c1SSteven Whitehouse destroy_workqueue(gfs2_control_wq); 1918b0d7f56STetsuo Handa fail_wq2: 192e0c2a9aaSDavid Teigland destroy_workqueue(gfs_recovery_wq); 1938b0d7f56STetsuo Handa fail_wq1: 194fe64d517SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 1958b0d7f56STetsuo Handa fail_fs2: 196419c93e0SSteven Whitehouse unregister_filesystem(&gfs2_fs_type); 1978b0d7f56STetsuo Handa fail_fs1: 1988b0d7f56STetsuo Handa unregister_shrinker(&gfs2_qd_shrinker); 1998b0d7f56STetsuo Handa fail_shrinker: 2008b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_qadata_cachep); 2018b0d7f56STetsuo Handa fail_cachep7: 2028b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_quotad_cachep); 2038b0d7f56STetsuo Handa fail_cachep6: 2048b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_rgrpd_cachep); 2058b0d7f56STetsuo Handa fail_cachep5: 2068b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_bufdata_cachep); 2078b0d7f56STetsuo Handa fail_cachep4: 2088b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_inode_cachep); 2098b0d7f56STetsuo Handa fail_cachep3: 2108b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_glock_aspace_cachep); 2118b0d7f56STetsuo Handa fail_cachep2: 2128b0d7f56STetsuo Handa kmem_cache_destroy(gfs2_glock_cachep); 2138b0d7f56STetsuo Handa fail_cachep1: 2148b0d7f56STetsuo Handa gfs2_glock_exit(); 2158b0d7f56STetsuo Handa fail_glock: 2162147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 2172147dbfdSSteven Whitehouse fail_lru: 218b3b94faaSDavid Teigland gfs2_sys_uninit(); 219b3b94faaSDavid Teigland return error; 220b3b94faaSDavid Teigland } 221b3b94faaSDavid Teigland 222b3b94faaSDavid Teigland /** 223b3b94faaSDavid Teigland * exit_gfs2_fs - Unregister the file system 224b3b94faaSDavid Teigland * 225b3b94faaSDavid Teigland */ 226b3b94faaSDavid Teigland 227b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void) 228b3b94faaSDavid Teigland { 2292147dbfdSSteven Whitehouse unregister_shrinker(&gfs2_qd_shrinker); 2308fbbfd21SSteven Whitehouse gfs2_glock_exit(); 2317c52b166SRobert Peterson gfs2_unregister_debugfs(); 232b3b94faaSDavid Teigland unregister_filesystem(&gfs2_fs_type); 233419c93e0SSteven Whitehouse unregister_filesystem(&gfs2meta_fs_type); 2346ecd7c2dSTejun Heo destroy_workqueue(gfs_recovery_wq); 235e0c2a9aaSDavid Teigland destroy_workqueue(gfs2_control_wq); 2362e60d768SBenjamin Marzinski destroy_workqueue(gfs2_freeze_wq); 2372147dbfdSSteven Whitehouse list_lru_destroy(&gfs2_qd_lru); 238b3b94faaSDavid Teigland 239bc015cb8SSteven Whitehouse rcu_barrier(); 240bc015cb8SSteven Whitehouse 241e8c92ed7SSteven Whitehouse mempool_destroy(gfs2_page_pool); 242b54e9a0bSBob Peterson kmem_cache_destroy(gfs2_qadata_cachep); 24337b2c837SSteven Whitehouse kmem_cache_destroy(gfs2_quotad_cachep); 2446bdd9be6SBob Peterson kmem_cache_destroy(gfs2_rgrpd_cachep); 245b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_bufdata_cachep); 246b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_inode_cachep); 247009d8518SSteven Whitehouse kmem_cache_destroy(gfs2_glock_aspace_cachep); 248b3b94faaSDavid Teigland kmem_cache_destroy(gfs2_glock_cachep); 249b3b94faaSDavid Teigland 250b3b94faaSDavid Teigland gfs2_sys_uninit(); 251b3b94faaSDavid Teigland } 252b3b94faaSDavid Teigland 253b3b94faaSDavid Teigland MODULE_DESCRIPTION("Global File System"); 254b3b94faaSDavid Teigland MODULE_AUTHOR("Red Hat, Inc."); 255b3b94faaSDavid Teigland MODULE_LICENSE("GPL"); 256b3b94faaSDavid Teigland 257b3b94faaSDavid Teigland module_init(init_gfs2_fs); 258b3b94faaSDavid Teigland module_exit(exit_gfs2_fs); 259b3b94faaSDavid Teigland 260