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