1 /* 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4 * 5 * This copyrighted material is made available to anyone wishing to use, 6 * modify, copy, or redistribute it subject to the terms and conditions 7 * of the GNU General Public License version 2. 8 */ 9 10 #include <linux/slab.h> 11 #include <linux/spinlock.h> 12 #include <linux/completion.h> 13 #include <linux/buffer_head.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/gfs2_ondisk.h> 17 #include <linux/rcupdate.h> 18 #include <linux/rculist_bl.h> 19 #include <linux/atomic.h> 20 #include <linux/mempool.h> 21 22 #include "gfs2.h" 23 #include "incore.h" 24 #include "super.h" 25 #include "sys.h" 26 #include "util.h" 27 #include "glock.h" 28 #include "quota.h" 29 #include "recovery.h" 30 #include "dir.h" 31 32 struct workqueue_struct *gfs2_control_wq; 33 34 static void gfs2_init_inode_once(void *foo) 35 { 36 struct gfs2_inode *ip = foo; 37 38 inode_init_once(&ip->i_inode); 39 init_rwsem(&ip->i_rw_mutex); 40 INIT_LIST_HEAD(&ip->i_trunc_list); 41 ip->i_res = NULL; 42 ip->i_hash_cache = NULL; 43 } 44 45 static void gfs2_init_glock_once(void *foo) 46 { 47 struct gfs2_glock *gl = foo; 48 49 INIT_HLIST_BL_NODE(&gl->gl_list); 50 spin_lock_init(&gl->gl_spin); 51 INIT_LIST_HEAD(&gl->gl_holders); 52 INIT_LIST_HEAD(&gl->gl_lru); 53 INIT_LIST_HEAD(&gl->gl_ail_list); 54 atomic_set(&gl->gl_ail_count, 0); 55 atomic_set(&gl->gl_revokes, 0); 56 } 57 58 static void gfs2_init_gl_aspace_once(void *foo) 59 { 60 struct gfs2_glock *gl = foo; 61 struct address_space *mapping = (struct address_space *)(gl + 1); 62 63 gfs2_init_glock_once(gl); 64 address_space_init_once(mapping); 65 } 66 67 /** 68 * init_gfs2_fs - Register GFS2 as a filesystem 69 * 70 * Returns: 0 on success, error code on failure 71 */ 72 73 static int __init init_gfs2_fs(void) 74 { 75 int error; 76 77 gfs2_str2qstr(&gfs2_qdot, "."); 78 gfs2_str2qstr(&gfs2_qdotdot, ".."); 79 80 error = gfs2_sys_init(); 81 if (error) 82 return error; 83 84 error = list_lru_init(&gfs2_qd_lru); 85 if (error) 86 goto fail_lru; 87 88 error = gfs2_glock_init(); 89 if (error) 90 goto fail; 91 92 error = -ENOMEM; 93 gfs2_glock_cachep = kmem_cache_create("gfs2_glock", 94 sizeof(struct gfs2_glock), 95 0, 0, 96 gfs2_init_glock_once); 97 if (!gfs2_glock_cachep) 98 goto fail; 99 100 gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)", 101 sizeof(struct gfs2_glock) + 102 sizeof(struct address_space), 103 0, 0, gfs2_init_gl_aspace_once); 104 105 if (!gfs2_glock_aspace_cachep) 106 goto fail; 107 108 gfs2_inode_cachep = kmem_cache_create("gfs2_inode", 109 sizeof(struct gfs2_inode), 110 0, SLAB_RECLAIM_ACCOUNT| 111 SLAB_MEM_SPREAD, 112 gfs2_init_inode_once); 113 if (!gfs2_inode_cachep) 114 goto fail; 115 116 gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata", 117 sizeof(struct gfs2_bufdata), 118 0, 0, NULL); 119 if (!gfs2_bufdata_cachep) 120 goto fail; 121 122 gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd", 123 sizeof(struct gfs2_rgrpd), 124 0, 0, NULL); 125 if (!gfs2_rgrpd_cachep) 126 goto fail; 127 128 gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad", 129 sizeof(struct gfs2_quota_data), 130 0, 0, NULL); 131 if (!gfs2_quotad_cachep) 132 goto fail; 133 134 gfs2_rsrv_cachep = kmem_cache_create("gfs2_mblk", 135 sizeof(struct gfs2_blkreserv), 136 0, 0, NULL); 137 if (!gfs2_rsrv_cachep) 138 goto fail; 139 140 register_shrinker(&gfs2_qd_shrinker); 141 142 error = register_filesystem(&gfs2_fs_type); 143 if (error) 144 goto fail; 145 146 error = register_filesystem(&gfs2meta_fs_type); 147 if (error) 148 goto fail_unregister; 149 150 error = -ENOMEM; 151 gfs_recovery_wq = alloc_workqueue("gfs_recovery", 152 WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); 153 if (!gfs_recovery_wq) 154 goto fail_wq; 155 156 gfs2_control_wq = alloc_workqueue("gfs2_control", 157 WQ_UNBOUND | WQ_FREEZABLE, 0); 158 if (!gfs2_control_wq) 159 goto fail_recovery; 160 161 gfs2_page_pool = mempool_create_page_pool(64, 0); 162 if (!gfs2_page_pool) 163 goto fail_control; 164 165 gfs2_register_debugfs(); 166 167 printk("GFS2 installed\n"); 168 169 return 0; 170 171 fail_control: 172 destroy_workqueue(gfs2_control_wq); 173 fail_recovery: 174 destroy_workqueue(gfs_recovery_wq); 175 fail_wq: 176 unregister_filesystem(&gfs2meta_fs_type); 177 fail_unregister: 178 unregister_filesystem(&gfs2_fs_type); 179 fail: 180 list_lru_destroy(&gfs2_qd_lru); 181 fail_lru: 182 unregister_shrinker(&gfs2_qd_shrinker); 183 gfs2_glock_exit(); 184 185 if (gfs2_rsrv_cachep) 186 kmem_cache_destroy(gfs2_rsrv_cachep); 187 188 if (gfs2_quotad_cachep) 189 kmem_cache_destroy(gfs2_quotad_cachep); 190 191 if (gfs2_rgrpd_cachep) 192 kmem_cache_destroy(gfs2_rgrpd_cachep); 193 194 if (gfs2_bufdata_cachep) 195 kmem_cache_destroy(gfs2_bufdata_cachep); 196 197 if (gfs2_inode_cachep) 198 kmem_cache_destroy(gfs2_inode_cachep); 199 200 if (gfs2_glock_aspace_cachep) 201 kmem_cache_destroy(gfs2_glock_aspace_cachep); 202 203 if (gfs2_glock_cachep) 204 kmem_cache_destroy(gfs2_glock_cachep); 205 206 gfs2_sys_uninit(); 207 return error; 208 } 209 210 /** 211 * exit_gfs2_fs - Unregister the file system 212 * 213 */ 214 215 static void __exit exit_gfs2_fs(void) 216 { 217 unregister_shrinker(&gfs2_qd_shrinker); 218 gfs2_glock_exit(); 219 gfs2_unregister_debugfs(); 220 unregister_filesystem(&gfs2_fs_type); 221 unregister_filesystem(&gfs2meta_fs_type); 222 destroy_workqueue(gfs_recovery_wq); 223 destroy_workqueue(gfs2_control_wq); 224 list_lru_destroy(&gfs2_qd_lru); 225 226 rcu_barrier(); 227 228 mempool_destroy(gfs2_page_pool); 229 kmem_cache_destroy(gfs2_rsrv_cachep); 230 kmem_cache_destroy(gfs2_quotad_cachep); 231 kmem_cache_destroy(gfs2_rgrpd_cachep); 232 kmem_cache_destroy(gfs2_bufdata_cachep); 233 kmem_cache_destroy(gfs2_inode_cachep); 234 kmem_cache_destroy(gfs2_glock_aspace_cachep); 235 kmem_cache_destroy(gfs2_glock_cachep); 236 237 gfs2_sys_uninit(); 238 } 239 240 MODULE_DESCRIPTION("Global File System"); 241 MODULE_AUTHOR("Red Hat, Inc."); 242 MODULE_LICENSE("GPL"); 243 244 module_init(init_gfs2_fs); 245 module_exit(exit_gfs2_fs); 246 247