xref: /openbmc/linux/fs/gfs2/main.c (revision 11d8b79e)
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 
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);
41813e0c46SSteven Whitehouse 	INIT_LIST_HEAD(&ip->i_trunc_list);
427542486bSBob Peterson 	INIT_LIST_HEAD(&ip->i_ordered);
43b54e9a0bSBob Peterson 	ip->i_qadata = NULL;
4421f09c43SAndreas Gruenbacher 	gfs2_holder_mark_uninitialized(&ip->i_rgd_gh);
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 
55f3dd1649SAndreas Gruenbacher 	spin_lock_init(&gl->gl_lockref.lock);
56ec45d9f5SSteven Whitehouse 	INIT_LIST_HEAD(&gl->gl_holders);
5797cc1025SSteven Whitehouse 	INIT_LIST_HEAD(&gl->gl_lru);
58ec45d9f5SSteven Whitehouse 	INIT_LIST_HEAD(&gl->gl_ail_list);
59ec45d9f5SSteven Whitehouse 	atomic_set(&gl->gl_ail_count, 0);
60638803d4SBob Peterson 	atomic_set(&gl->gl_revokes, 0);
61ec45d9f5SSteven Whitehouse }
62ec45d9f5SSteven Whitehouse 
63009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo)
64009d8518SSteven Whitehouse {
65*11d8b79eSKees Cook 	struct gfs2_glock_aspace *gla = foo;
66009d8518SSteven Whitehouse 
67*11d8b79eSKees Cook 	gfs2_init_glock_once(&gla->glock);
68*11d8b79eSKees Cook 	address_space_init_once(&gla->mapping);
69009d8518SSteven Whitehouse }
70009d8518SSteven Whitehouse 
71b3b94faaSDavid Teigland /**
72b3b94faaSDavid Teigland  * init_gfs2_fs - Register GFS2 as a filesystem
73b3b94faaSDavid Teigland  *
74b3b94faaSDavid Teigland  * Returns: 0 on success, error code on failure
75b3b94faaSDavid Teigland  */
76b3b94faaSDavid Teigland 
77b3b94faaSDavid Teigland static int __init init_gfs2_fs(void)
78b3b94faaSDavid Teigland {
79b3b94faaSDavid Teigland 	int error;
80b3b94faaSDavid Teigland 
818d123585SSteven Whitehouse 	gfs2_str2qstr(&gfs2_qdot, ".");
828d123585SSteven Whitehouse 	gfs2_str2qstr(&gfs2_qdotdot, "..");
83c754fbbbSSteven Whitehouse 	gfs2_quota_hash_init();
848d123585SSteven Whitehouse 
85b3b94faaSDavid Teigland 	error = gfs2_sys_init();
86b3b94faaSDavid Teigland 	if (error)
87b3b94faaSDavid Teigland 		return error;
88b3b94faaSDavid Teigland 
892147dbfdSSteven Whitehouse 	error = list_lru_init(&gfs2_qd_lru);
902147dbfdSSteven Whitehouse 	if (error)
912147dbfdSSteven Whitehouse 		goto fail_lru;
922147dbfdSSteven Whitehouse 
9385d1da67SSteven Whitehouse 	error = gfs2_glock_init();
9485d1da67SSteven Whitehouse 	if (error)
958b0d7f56STetsuo Handa 		goto fail_glock;
96b3b94faaSDavid Teigland 
9785d1da67SSteven Whitehouse 	error = -ENOMEM;
98b3b94faaSDavid Teigland 	gfs2_glock_cachep = kmem_cache_create("gfs2_glock",
99b3b94faaSDavid Teigland 					      sizeof(struct gfs2_glock),
10000e8e9bcSZhaoyang Huang 					      0, SLAB_RECLAIM_ACCOUNT,
10120c2df83SPaul Mundt 					      gfs2_init_glock_once);
102b3b94faaSDavid Teigland 	if (!gfs2_glock_cachep)
1038b0d7f56STetsuo Handa 		goto fail_cachep1;
104b3b94faaSDavid Teigland 
105009d8518SSteven Whitehouse 	gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)",
106*11d8b79eSKees Cook 					sizeof(struct gfs2_glock_aspace),
107009d8518SSteven Whitehouse 					0, 0, gfs2_init_gl_aspace_once);
108009d8518SSteven Whitehouse 
109009d8518SSteven Whitehouse 	if (!gfs2_glock_aspace_cachep)
1108b0d7f56STetsuo Handa 		goto fail_cachep2;
111009d8518SSteven Whitehouse 
112b3b94faaSDavid Teigland 	gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
113b3b94faaSDavid Teigland 					      sizeof(struct gfs2_inode),
114eb1dc33aSAlexey Dobriyan 					      0,  SLAB_RECLAIM_ACCOUNT|
1155d097056SVladimir Davydov 						  SLAB_MEM_SPREAD|
1165d097056SVladimir Davydov 						  SLAB_ACCOUNT,
11720c2df83SPaul Mundt 					      gfs2_init_inode_once);
118b3b94faaSDavid Teigland 	if (!gfs2_inode_cachep)
1198b0d7f56STetsuo Handa 		goto fail_cachep3;
120b3b94faaSDavid Teigland 
121b3b94faaSDavid Teigland 	gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata",
122b3b94faaSDavid Teigland 						sizeof(struct gfs2_bufdata),
12320c2df83SPaul Mundt 					        0, 0, NULL);
124b3b94faaSDavid Teigland 	if (!gfs2_bufdata_cachep)
1258b0d7f56STetsuo Handa 		goto fail_cachep4;
126b3b94faaSDavid Teigland 
1276bdd9be6SBob Peterson 	gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd",
1286bdd9be6SBob Peterson 					      sizeof(struct gfs2_rgrpd),
1296bdd9be6SBob Peterson 					      0, 0, NULL);
1306bdd9be6SBob Peterson 	if (!gfs2_rgrpd_cachep)
1318b0d7f56STetsuo Handa 		goto fail_cachep5;
1326bdd9be6SBob Peterson 
13337b2c837SSteven Whitehouse 	gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad",
13437b2c837SSteven Whitehouse 					       sizeof(struct gfs2_quota_data),
13500e8e9bcSZhaoyang Huang 					       0, SLAB_RECLAIM_ACCOUNT, NULL);
13637b2c837SSteven Whitehouse 	if (!gfs2_quotad_cachep)
1378b0d7f56STetsuo Handa 		goto fail_cachep6;
13837b2c837SSteven Whitehouse 
139b54e9a0bSBob Peterson 	gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata",
140b54e9a0bSBob Peterson 					       sizeof(struct gfs2_qadata),
141b54e9a0bSBob Peterson 					       0, 0, NULL);
142b54e9a0bSBob Peterson 	if (!gfs2_qadata_cachep)
1438b0d7f56STetsuo Handa 		goto fail_cachep7;
144b54e9a0bSBob Peterson 
145b839dadaSBob Peterson 	gfs2_trans_cachep = kmem_cache_create("gfs2_trans",
146b839dadaSBob Peterson 					       sizeof(struct gfs2_trans),
147b839dadaSBob Peterson 					       0, 0, NULL);
148b839dadaSBob Peterson 	if (!gfs2_trans_cachep)
149b839dadaSBob Peterson 		goto fail_cachep8;
150b839dadaSBob Peterson 
151e0d735c1SChao Yu 	error = register_shrinker(&gfs2_qd_shrinker);
152e0d735c1SChao Yu 	if (error)
1538b0d7f56STetsuo Handa 		goto fail_shrinker;
1540a7ab79cSAbhijith Das 
155b3b94faaSDavid Teigland 	error = register_filesystem(&gfs2_fs_type);
156b3b94faaSDavid Teigland 	if (error)
1578b0d7f56STetsuo Handa 		goto fail_fs1;
158b3b94faaSDavid Teigland 
159419c93e0SSteven Whitehouse 	error = register_filesystem(&gfs2meta_fs_type);
160419c93e0SSteven Whitehouse 	if (error)
1618b0d7f56STetsuo Handa 		goto fail_fs2;
162419c93e0SSteven Whitehouse 
1636ecd7c2dSTejun Heo 	error = -ENOMEM;
1646ecd7c2dSTejun Heo 	gfs_recovery_wq = alloc_workqueue("gfs_recovery",
16558a69cb4STejun Heo 					  WQ_MEM_RECLAIM | WQ_FREEZABLE, 0);
1666ecd7c2dSTejun Heo 	if (!gfs_recovery_wq)
1678b0d7f56STetsuo Handa 		goto fail_wq1;
168fe64d517SSteven Whitehouse 
169e0c2a9aaSDavid Teigland 	gfs2_control_wq = alloc_workqueue("gfs2_control",
170d08fa65aSTejun Heo 					  WQ_UNBOUND | WQ_FREEZABLE, 0);
171e0c2a9aaSDavid Teigland 	if (!gfs2_control_wq)
1728b0d7f56STetsuo Handa 		goto fail_wq2;
17375ca61c1SSteven Whitehouse 
1742e60d768SBenjamin Marzinski 	gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0);
1752e60d768SBenjamin Marzinski 
1762e60d768SBenjamin Marzinski 	if (!gfs2_freeze_wq)
1778b0d7f56STetsuo Handa 		goto fail_wq3;
1782e60d768SBenjamin Marzinski 
179e8c92ed7SSteven Whitehouse 	gfs2_page_pool = mempool_create_page_pool(64, 0);
180e8c92ed7SSteven Whitehouse 	if (!gfs2_page_pool)
1818b0d7f56STetsuo Handa 		goto fail_mempool;
182e0c2a9aaSDavid Teigland 
1832abbf9a4SGreg Kroah-Hartman 	gfs2_register_debugfs();
1847c52b166SRobert Peterson 
185fc554ed3SFabian Frederick 	pr_info("GFS2 installed\n");
186b3b94faaSDavid Teigland 
187b3b94faaSDavid Teigland 	return 0;
188b3b94faaSDavid Teigland 
1898b0d7f56STetsuo Handa fail_mempool:
1902e60d768SBenjamin Marzinski 	destroy_workqueue(gfs2_freeze_wq);
1918b0d7f56STetsuo Handa fail_wq3:
19275ca61c1SSteven Whitehouse 	destroy_workqueue(gfs2_control_wq);
1938b0d7f56STetsuo Handa fail_wq2:
194e0c2a9aaSDavid Teigland 	destroy_workqueue(gfs_recovery_wq);
1958b0d7f56STetsuo Handa fail_wq1:
196fe64d517SSteven Whitehouse 	unregister_filesystem(&gfs2meta_fs_type);
1978b0d7f56STetsuo Handa fail_fs2:
198419c93e0SSteven Whitehouse 	unregister_filesystem(&gfs2_fs_type);
1998b0d7f56STetsuo Handa fail_fs1:
2008b0d7f56STetsuo Handa 	unregister_shrinker(&gfs2_qd_shrinker);
2018b0d7f56STetsuo Handa fail_shrinker:
202b839dadaSBob Peterson 	kmem_cache_destroy(gfs2_trans_cachep);
203b839dadaSBob Peterson fail_cachep8:
2048b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_qadata_cachep);
2058b0d7f56STetsuo Handa fail_cachep7:
2068b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_quotad_cachep);
2078b0d7f56STetsuo Handa fail_cachep6:
2088b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_rgrpd_cachep);
2098b0d7f56STetsuo Handa fail_cachep5:
2108b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_bufdata_cachep);
2118b0d7f56STetsuo Handa fail_cachep4:
2128b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_inode_cachep);
2138b0d7f56STetsuo Handa fail_cachep3:
2148b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_glock_aspace_cachep);
2158b0d7f56STetsuo Handa fail_cachep2:
2168b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_glock_cachep);
2178b0d7f56STetsuo Handa fail_cachep1:
2188b0d7f56STetsuo Handa 	gfs2_glock_exit();
2198b0d7f56STetsuo Handa fail_glock:
2202147dbfdSSteven Whitehouse 	list_lru_destroy(&gfs2_qd_lru);
2212147dbfdSSteven Whitehouse fail_lru:
222b3b94faaSDavid Teigland 	gfs2_sys_uninit();
223b3b94faaSDavid Teigland 	return error;
224b3b94faaSDavid Teigland }
225b3b94faaSDavid Teigland 
226b3b94faaSDavid Teigland /**
227b3b94faaSDavid Teigland  * exit_gfs2_fs - Unregister the file system
228b3b94faaSDavid Teigland  *
229b3b94faaSDavid Teigland  */
230b3b94faaSDavid Teigland 
231b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void)
232b3b94faaSDavid Teigland {
2332147dbfdSSteven Whitehouse 	unregister_shrinker(&gfs2_qd_shrinker);
2348fbbfd21SSteven Whitehouse 	gfs2_glock_exit();
2357c52b166SRobert Peterson 	gfs2_unregister_debugfs();
236b3b94faaSDavid Teigland 	unregister_filesystem(&gfs2_fs_type);
237419c93e0SSteven Whitehouse 	unregister_filesystem(&gfs2meta_fs_type);
2386ecd7c2dSTejun Heo 	destroy_workqueue(gfs_recovery_wq);
239e0c2a9aaSDavid Teigland 	destroy_workqueue(gfs2_control_wq);
2402e60d768SBenjamin Marzinski 	destroy_workqueue(gfs2_freeze_wq);
2412147dbfdSSteven Whitehouse 	list_lru_destroy(&gfs2_qd_lru);
242b3b94faaSDavid Teigland 
243bc015cb8SSteven Whitehouse 	rcu_barrier();
244bc015cb8SSteven Whitehouse 
245e8c92ed7SSteven Whitehouse 	mempool_destroy(gfs2_page_pool);
246b839dadaSBob Peterson 	kmem_cache_destroy(gfs2_trans_cachep);
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