xref: /openbmc/linux/fs/gfs2/main.c (revision ab8eecf5)
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 
gfs2_init_inode_once(void * foo)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);
417542486bSBob Peterson 	INIT_LIST_HEAD(&ip->i_ordered);
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 
gfs2_init_glock_once(void * foo)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);
59638803d4SBob Peterson 	atomic_set(&gl->gl_revokes, 0);
60ec45d9f5SSteven Whitehouse }
61ec45d9f5SSteven Whitehouse 
gfs2_init_gl_aspace_once(void * foo)62009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo)
63009d8518SSteven Whitehouse {
6411d8b79eSKees Cook 	struct gfs2_glock_aspace *gla = foo;
65009d8518SSteven Whitehouse 
6611d8b79eSKees Cook 	gfs2_init_glock_once(&gla->glock);
6711d8b79eSKees Cook 	address_space_init_once(&gla->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 
init_gfs2_fs(void)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),
9900e8e9bcSZhaoyang Huang 					      0, SLAB_RECLAIM_ACCOUNT,
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)",
10511d8b79eSKees Cook 					sizeof(struct gfs2_glock_aspace),
106009d8518SSteven Whitehouse 					0, 0, gfs2_init_gl_aspace_once);
107009d8518SSteven Whitehouse 
108009d8518SSteven Whitehouse 	if (!gfs2_glock_aspace_cachep)
1098b0d7f56STetsuo Handa 		goto fail_cachep2;
110009d8518SSteven Whitehouse 
111b3b94faaSDavid Teigland 	gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
112b3b94faaSDavid Teigland 					      sizeof(struct gfs2_inode),
113eb1dc33aSAlexey Dobriyan 					      0,  SLAB_RECLAIM_ACCOUNT|
1145d097056SVladimir Davydov 						  SLAB_MEM_SPREAD|
1155d097056SVladimir Davydov 						  SLAB_ACCOUNT,
11620c2df83SPaul Mundt 					      gfs2_init_inode_once);
117b3b94faaSDavid Teigland 	if (!gfs2_inode_cachep)
1188b0d7f56STetsuo Handa 		goto fail_cachep3;
119b3b94faaSDavid Teigland 
120b3b94faaSDavid Teigland 	gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata",
121b3b94faaSDavid Teigland 						sizeof(struct gfs2_bufdata),
12220c2df83SPaul Mundt 					        0, 0, NULL);
123b3b94faaSDavid Teigland 	if (!gfs2_bufdata_cachep)
1248b0d7f56STetsuo Handa 		goto fail_cachep4;
125b3b94faaSDavid Teigland 
1266bdd9be6SBob Peterson 	gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd",
1276bdd9be6SBob Peterson 					      sizeof(struct gfs2_rgrpd),
1286bdd9be6SBob Peterson 					      0, 0, NULL);
1296bdd9be6SBob Peterson 	if (!gfs2_rgrpd_cachep)
1308b0d7f56STetsuo Handa 		goto fail_cachep5;
1316bdd9be6SBob Peterson 
13237b2c837SSteven Whitehouse 	gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad",
13337b2c837SSteven Whitehouse 					       sizeof(struct gfs2_quota_data),
13400e8e9bcSZhaoyang Huang 					       0, SLAB_RECLAIM_ACCOUNT, NULL);
13537b2c837SSteven Whitehouse 	if (!gfs2_quotad_cachep)
1368b0d7f56STetsuo Handa 		goto fail_cachep6;
13737b2c837SSteven Whitehouse 
138b54e9a0bSBob Peterson 	gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata",
139b54e9a0bSBob Peterson 					       sizeof(struct gfs2_qadata),
140b54e9a0bSBob Peterson 					       0, 0, NULL);
141b54e9a0bSBob Peterson 	if (!gfs2_qadata_cachep)
1428b0d7f56STetsuo Handa 		goto fail_cachep7;
143b54e9a0bSBob Peterson 
144b839dadaSBob Peterson 	gfs2_trans_cachep = kmem_cache_create("gfs2_trans",
145b839dadaSBob Peterson 					       sizeof(struct gfs2_trans),
146b839dadaSBob Peterson 					       0, 0, NULL);
147b839dadaSBob Peterson 	if (!gfs2_trans_cachep)
148b839dadaSBob Peterson 		goto fail_cachep8;
149b839dadaSBob Peterson 
150e33c267aSRoman Gushchin 	error = register_shrinker(&gfs2_qd_shrinker, "gfs2-qd");
151e0d735c1SChao Yu 	if (error)
1528b0d7f56STetsuo Handa 		goto fail_shrinker;
1530a7ab79cSAbhijith Das 
1546ecd7c2dSTejun Heo 	error = -ENOMEM;
1555c0dc371SAndreas Gruenbacher 	gfs2_recovery_wq = alloc_workqueue("gfs2_recovery",
15658a69cb4STejun Heo 					  WQ_MEM_RECLAIM | WQ_FREEZABLE, 0);
1575c0dc371SAndreas Gruenbacher 	if (!gfs2_recovery_wq)
1588b0d7f56STetsuo Handa 		goto fail_wq1;
159fe64d517SSteven Whitehouse 
160e0c2a9aaSDavid Teigland 	gfs2_control_wq = alloc_workqueue("gfs2_control",
161d08fa65aSTejun Heo 					  WQ_UNBOUND | WQ_FREEZABLE, 0);
162e0c2a9aaSDavid Teigland 	if (!gfs2_control_wq)
1638b0d7f56STetsuo Handa 		goto fail_wq2;
16475ca61c1SSteven Whitehouse 
165*ab8eecf5SAndreas Gruenbacher 	gfs2_freeze_wq = alloc_workqueue("gfs2_freeze", 0, 0);
1662e60d768SBenjamin Marzinski 
1672e60d768SBenjamin Marzinski 	if (!gfs2_freeze_wq)
1688b0d7f56STetsuo Handa 		goto fail_wq3;
1692e60d768SBenjamin Marzinski 
170e8c92ed7SSteven Whitehouse 	gfs2_page_pool = mempool_create_page_pool(64, 0);
171e8c92ed7SSteven Whitehouse 	if (!gfs2_page_pool)
1728b0d7f56STetsuo Handa 		goto fail_mempool;
173e0c2a9aaSDavid Teigland 
1742abbf9a4SGreg Kroah-Hartman 	gfs2_register_debugfs();
17574b1b10eSBob Peterson 	error = register_filesystem(&gfs2_fs_type);
17674b1b10eSBob Peterson 	if (error)
17774b1b10eSBob Peterson 		goto fail_fs1;
17874b1b10eSBob Peterson 
17974b1b10eSBob Peterson 	error = register_filesystem(&gfs2meta_fs_type);
18074b1b10eSBob Peterson 	if (error)
18174b1b10eSBob Peterson 		goto fail_fs2;
18274b1b10eSBob Peterson 
1837c52b166SRobert Peterson 
184fc554ed3SFabian Frederick 	pr_info("GFS2 installed\n");
185b3b94faaSDavid Teigland 
186b3b94faaSDavid Teigland 	return 0;
187b3b94faaSDavid Teigland 
18874b1b10eSBob Peterson fail_fs2:
18974b1b10eSBob Peterson 	unregister_filesystem(&gfs2_fs_type);
19074b1b10eSBob Peterson fail_fs1:
19174b1b10eSBob Peterson 	mempool_destroy(gfs2_page_pool);
1928b0d7f56STetsuo Handa fail_mempool:
1932e60d768SBenjamin Marzinski 	destroy_workqueue(gfs2_freeze_wq);
1948b0d7f56STetsuo Handa fail_wq3:
19575ca61c1SSteven Whitehouse 	destroy_workqueue(gfs2_control_wq);
1968b0d7f56STetsuo Handa fail_wq2:
1975c0dc371SAndreas Gruenbacher 	destroy_workqueue(gfs2_recovery_wq);
1988b0d7f56STetsuo Handa fail_wq1:
1998b0d7f56STetsuo Handa 	unregister_shrinker(&gfs2_qd_shrinker);
2008b0d7f56STetsuo Handa fail_shrinker:
201b839dadaSBob Peterson 	kmem_cache_destroy(gfs2_trans_cachep);
202b839dadaSBob Peterson fail_cachep8:
2038b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_qadata_cachep);
2048b0d7f56STetsuo Handa fail_cachep7:
2058b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_quotad_cachep);
2068b0d7f56STetsuo Handa fail_cachep6:
2078b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_rgrpd_cachep);
2088b0d7f56STetsuo Handa fail_cachep5:
2098b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_bufdata_cachep);
2108b0d7f56STetsuo Handa fail_cachep4:
2118b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_inode_cachep);
2128b0d7f56STetsuo Handa fail_cachep3:
2138b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_glock_aspace_cachep);
2148b0d7f56STetsuo Handa fail_cachep2:
2158b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_glock_cachep);
2168b0d7f56STetsuo Handa fail_cachep1:
2178b0d7f56STetsuo Handa 	gfs2_glock_exit();
2188b0d7f56STetsuo Handa fail_glock:
2192147dbfdSSteven Whitehouse 	list_lru_destroy(&gfs2_qd_lru);
2202147dbfdSSteven Whitehouse fail_lru:
221b3b94faaSDavid Teigland 	gfs2_sys_uninit();
222b3b94faaSDavid Teigland 	return error;
223b3b94faaSDavid Teigland }
224b3b94faaSDavid Teigland 
225b3b94faaSDavid Teigland /**
226b3b94faaSDavid Teigland  * exit_gfs2_fs - Unregister the file system
227b3b94faaSDavid Teigland  *
228b3b94faaSDavid Teigland  */
229b3b94faaSDavid Teigland 
exit_gfs2_fs(void)230b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void)
231b3b94faaSDavid Teigland {
2322147dbfdSSteven Whitehouse 	unregister_shrinker(&gfs2_qd_shrinker);
2338fbbfd21SSteven Whitehouse 	gfs2_glock_exit();
2347c52b166SRobert Peterson 	gfs2_unregister_debugfs();
235b3b94faaSDavid Teigland 	unregister_filesystem(&gfs2_fs_type);
236419c93e0SSteven Whitehouse 	unregister_filesystem(&gfs2meta_fs_type);
2375c0dc371SAndreas Gruenbacher 	destroy_workqueue(gfs2_recovery_wq);
238e0c2a9aaSDavid Teigland 	destroy_workqueue(gfs2_control_wq);
2392e60d768SBenjamin Marzinski 	destroy_workqueue(gfs2_freeze_wq);
2402147dbfdSSteven Whitehouse 	list_lru_destroy(&gfs2_qd_lru);
241b3b94faaSDavid Teigland 
242bc015cb8SSteven Whitehouse 	rcu_barrier();
243bc015cb8SSteven Whitehouse 
244e8c92ed7SSteven Whitehouse 	mempool_destroy(gfs2_page_pool);
245b839dadaSBob Peterson 	kmem_cache_destroy(gfs2_trans_cachep);
246b54e9a0bSBob Peterson 	kmem_cache_destroy(gfs2_qadata_cachep);
24737b2c837SSteven Whitehouse 	kmem_cache_destroy(gfs2_quotad_cachep);
2486bdd9be6SBob Peterson 	kmem_cache_destroy(gfs2_rgrpd_cachep);
249b3b94faaSDavid Teigland 	kmem_cache_destroy(gfs2_bufdata_cachep);
250b3b94faaSDavid Teigland 	kmem_cache_destroy(gfs2_inode_cachep);
251009d8518SSteven Whitehouse 	kmem_cache_destroy(gfs2_glock_aspace_cachep);
252b3b94faaSDavid Teigland 	kmem_cache_destroy(gfs2_glock_cachep);
253b3b94faaSDavid Teigland 
254b3b94faaSDavid Teigland 	gfs2_sys_uninit();
255b3b94faaSDavid Teigland }
256b3b94faaSDavid Teigland 
257b3b94faaSDavid Teigland MODULE_DESCRIPTION("Global File System");
258b3b94faaSDavid Teigland MODULE_AUTHOR("Red Hat, Inc.");
259b3b94faaSDavid Teigland MODULE_LICENSE("GPL");
260b3b94faaSDavid Teigland 
261b3b94faaSDavid Teigland module_init(init_gfs2_fs);
262b3b94faaSDavid Teigland module_exit(exit_gfs2_fs);
263b3b94faaSDavid Teigland 
264