xref: /openbmc/linux/fs/gfs2/main.c (revision 7336d0e6)
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);
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 
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);
59ec45d9f5SSteven Whitehouse }
60ec45d9f5SSteven Whitehouse 
61009d8518SSteven Whitehouse static void gfs2_init_gl_aspace_once(void *foo)
62009d8518SSteven Whitehouse {
63009d8518SSteven Whitehouse 	struct gfs2_glock *gl = foo;
64009d8518SSteven Whitehouse 	struct address_space *mapping = (struct address_space *)(gl + 1);
65009d8518SSteven Whitehouse 
66009d8518SSteven Whitehouse 	gfs2_init_glock_once(gl);
672aa15890SMiklos Szeredi 	address_space_init_once(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 
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),
99ec45d9f5SSteven Whitehouse 					      0, 0,
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)",
105009d8518SSteven Whitehouse 					sizeof(struct gfs2_glock) +
106009d8518SSteven Whitehouse 					sizeof(struct address_space),
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),
13537b2c837SSteven Whitehouse 					       0, 0, 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 
145e0d735c1SChao Yu 	error = register_shrinker(&gfs2_qd_shrinker);
146e0d735c1SChao Yu 	if (error)
1478b0d7f56STetsuo Handa 		goto fail_shrinker;
1480a7ab79cSAbhijith Das 
149b3b94faaSDavid Teigland 	error = register_filesystem(&gfs2_fs_type);
150b3b94faaSDavid Teigland 	if (error)
1518b0d7f56STetsuo Handa 		goto fail_fs1;
152b3b94faaSDavid Teigland 
153419c93e0SSteven Whitehouse 	error = register_filesystem(&gfs2meta_fs_type);
154419c93e0SSteven Whitehouse 	if (error)
1558b0d7f56STetsuo Handa 		goto fail_fs2;
156419c93e0SSteven Whitehouse 
1576ecd7c2dSTejun Heo 	error = -ENOMEM;
1586ecd7c2dSTejun Heo 	gfs_recovery_wq = alloc_workqueue("gfs_recovery",
15958a69cb4STejun Heo 					  WQ_MEM_RECLAIM | WQ_FREEZABLE, 0);
1606ecd7c2dSTejun Heo 	if (!gfs_recovery_wq)
1618b0d7f56STetsuo Handa 		goto fail_wq1;
162fe64d517SSteven Whitehouse 
163e0c2a9aaSDavid Teigland 	gfs2_control_wq = alloc_workqueue("gfs2_control",
164d08fa65aSTejun Heo 					  WQ_UNBOUND | WQ_FREEZABLE, 0);
165e0c2a9aaSDavid Teigland 	if (!gfs2_control_wq)
1668b0d7f56STetsuo Handa 		goto fail_wq2;
16775ca61c1SSteven Whitehouse 
1682e60d768SBenjamin Marzinski 	gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0);
1692e60d768SBenjamin Marzinski 
1702e60d768SBenjamin Marzinski 	if (!gfs2_freeze_wq)
1718b0d7f56STetsuo Handa 		goto fail_wq3;
1722e60d768SBenjamin Marzinski 
173e8c92ed7SSteven Whitehouse 	gfs2_page_pool = mempool_create_page_pool(64, 0);
174e8c92ed7SSteven Whitehouse 	if (!gfs2_page_pool)
1758b0d7f56STetsuo Handa 		goto fail_mempool;
176e0c2a9aaSDavid Teigland 
1772abbf9a4SGreg Kroah-Hartman 	gfs2_register_debugfs();
1787c52b166SRobert Peterson 
179fc554ed3SFabian Frederick 	pr_info("GFS2 installed\n");
180b3b94faaSDavid Teigland 
181b3b94faaSDavid Teigland 	return 0;
182b3b94faaSDavid Teigland 
1838b0d7f56STetsuo Handa fail_mempool:
1842e60d768SBenjamin Marzinski 	destroy_workqueue(gfs2_freeze_wq);
1858b0d7f56STetsuo Handa fail_wq3:
18675ca61c1SSteven Whitehouse 	destroy_workqueue(gfs2_control_wq);
1878b0d7f56STetsuo Handa fail_wq2:
188e0c2a9aaSDavid Teigland 	destroy_workqueue(gfs_recovery_wq);
1898b0d7f56STetsuo Handa fail_wq1:
190fe64d517SSteven Whitehouse 	unregister_filesystem(&gfs2meta_fs_type);
1918b0d7f56STetsuo Handa fail_fs2:
192419c93e0SSteven Whitehouse 	unregister_filesystem(&gfs2_fs_type);
1938b0d7f56STetsuo Handa fail_fs1:
1948b0d7f56STetsuo Handa 	unregister_shrinker(&gfs2_qd_shrinker);
1958b0d7f56STetsuo Handa fail_shrinker:
1968b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_qadata_cachep);
1978b0d7f56STetsuo Handa fail_cachep7:
1988b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_quotad_cachep);
1998b0d7f56STetsuo Handa fail_cachep6:
2008b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_rgrpd_cachep);
2018b0d7f56STetsuo Handa fail_cachep5:
2028b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_bufdata_cachep);
2038b0d7f56STetsuo Handa fail_cachep4:
2048b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_inode_cachep);
2058b0d7f56STetsuo Handa fail_cachep3:
2068b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_glock_aspace_cachep);
2078b0d7f56STetsuo Handa fail_cachep2:
2088b0d7f56STetsuo Handa 	kmem_cache_destroy(gfs2_glock_cachep);
2098b0d7f56STetsuo Handa fail_cachep1:
2108b0d7f56STetsuo Handa 	gfs2_glock_exit();
2118b0d7f56STetsuo Handa fail_glock:
2122147dbfdSSteven Whitehouse 	list_lru_destroy(&gfs2_qd_lru);
2132147dbfdSSteven Whitehouse fail_lru:
214b3b94faaSDavid Teigland 	gfs2_sys_uninit();
215b3b94faaSDavid Teigland 	return error;
216b3b94faaSDavid Teigland }
217b3b94faaSDavid Teigland 
218b3b94faaSDavid Teigland /**
219b3b94faaSDavid Teigland  * exit_gfs2_fs - Unregister the file system
220b3b94faaSDavid Teigland  *
221b3b94faaSDavid Teigland  */
222b3b94faaSDavid Teigland 
223b3b94faaSDavid Teigland static void __exit exit_gfs2_fs(void)
224b3b94faaSDavid Teigland {
2252147dbfdSSteven Whitehouse 	unregister_shrinker(&gfs2_qd_shrinker);
2268fbbfd21SSteven Whitehouse 	gfs2_glock_exit();
2277c52b166SRobert Peterson 	gfs2_unregister_debugfs();
228b3b94faaSDavid Teigland 	unregister_filesystem(&gfs2_fs_type);
229419c93e0SSteven Whitehouse 	unregister_filesystem(&gfs2meta_fs_type);
2306ecd7c2dSTejun Heo 	destroy_workqueue(gfs_recovery_wq);
231e0c2a9aaSDavid Teigland 	destroy_workqueue(gfs2_control_wq);
2322e60d768SBenjamin Marzinski 	destroy_workqueue(gfs2_freeze_wq);
2332147dbfdSSteven Whitehouse 	list_lru_destroy(&gfs2_qd_lru);
234b3b94faaSDavid Teigland 
235bc015cb8SSteven Whitehouse 	rcu_barrier();
236bc015cb8SSteven Whitehouse 
237e8c92ed7SSteven Whitehouse 	mempool_destroy(gfs2_page_pool);
238b54e9a0bSBob Peterson 	kmem_cache_destroy(gfs2_qadata_cachep);
23937b2c837SSteven Whitehouse 	kmem_cache_destroy(gfs2_quotad_cachep);
2406bdd9be6SBob Peterson 	kmem_cache_destroy(gfs2_rgrpd_cachep);
241b3b94faaSDavid Teigland 	kmem_cache_destroy(gfs2_bufdata_cachep);
242b3b94faaSDavid Teigland 	kmem_cache_destroy(gfs2_inode_cachep);
243009d8518SSteven Whitehouse 	kmem_cache_destroy(gfs2_glock_aspace_cachep);
244b3b94faaSDavid Teigland 	kmem_cache_destroy(gfs2_glock_cachep);
245b3b94faaSDavid Teigland 
246b3b94faaSDavid Teigland 	gfs2_sys_uninit();
247b3b94faaSDavid Teigland }
248b3b94faaSDavid Teigland 
249b3b94faaSDavid Teigland MODULE_DESCRIPTION("Global File System");
250b3b94faaSDavid Teigland MODULE_AUTHOR("Red Hat, Inc.");
251b3b94faaSDavid Teigland MODULE_LICENSE("GPL");
252b3b94faaSDavid Teigland 
253b3b94faaSDavid Teigland module_init(init_gfs2_fs);
254b3b94faaSDavid Teigland module_exit(exit_gfs2_fs);
255b3b94faaSDavid Teigland 
256