xref: /openbmc/linux/fs/gfs2/main.c (revision 2abbf9a4)
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