linux/fs/gfs2/main.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
   3 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
   4 *
   5 * This copyrighted material is made available to anyone wishing to use,
   6 * modify, copy, or redistribute it subject to the terms and conditions
   7 * of the GNU General Public License version 2.
   8 */
   9
  10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11
  12#include <linux/slab.h>
  13#include <linux/spinlock.h>
  14#include <linux/completion.h>
  15#include <linux/buffer_head.h>
  16#include <linux/module.h>
  17#include <linux/init.h>
  18#include <linux/gfs2_ondisk.h>
  19#include <linux/rcupdate.h>
  20#include <linux/rculist_bl.h>
  21#include <linux/atomic.h>
  22#include <linux/mempool.h>
  23
  24#include "gfs2.h"
  25#include "incore.h"
  26#include "super.h"
  27#include "sys.h"
  28#include "util.h"
  29#include "glock.h"
  30#include "quota.h"
  31#include "recovery.h"
  32#include "dir.h"
  33
  34struct workqueue_struct *gfs2_control_wq;
  35
  36static void gfs2_init_inode_once(void *foo)
  37{
  38        struct gfs2_inode *ip = foo;
  39
  40        inode_init_once(&ip->i_inode);
  41        init_rwsem(&ip->i_rw_mutex);
  42        INIT_LIST_HEAD(&ip->i_trunc_list);
  43        ip->i_res = NULL;
  44        ip->i_hash_cache = NULL;
  45}
  46
  47static void gfs2_init_glock_once(void *foo)
  48{
  49        struct gfs2_glock *gl = foo;
  50
  51        INIT_HLIST_BL_NODE(&gl->gl_list);
  52        spin_lock_init(&gl->gl_spin);
  53        INIT_LIST_HEAD(&gl->gl_holders);
  54        INIT_LIST_HEAD(&gl->gl_lru);
  55        INIT_LIST_HEAD(&gl->gl_ail_list);
  56        atomic_set(&gl->gl_ail_count, 0);
  57        atomic_set(&gl->gl_revokes, 0);
  58}
  59
  60static void gfs2_init_gl_aspace_once(void *foo)
  61{
  62        struct gfs2_glock *gl = foo;
  63        struct address_space *mapping = (struct address_space *)(gl + 1);
  64
  65        gfs2_init_glock_once(gl);
  66        address_space_init_once(mapping);
  67}
  68
  69/**
  70 * init_gfs2_fs - Register GFS2 as a filesystem
  71 *
  72 * Returns: 0 on success, error code on failure
  73 */
  74
  75static int __init init_gfs2_fs(void)
  76{
  77        int error;
  78
  79        gfs2_str2qstr(&gfs2_qdot, ".");
  80        gfs2_str2qstr(&gfs2_qdotdot, "..");
  81        gfs2_quota_hash_init();
  82
  83        error = gfs2_sys_init();
  84        if (error)
  85                return error;
  86
  87        error = list_lru_init(&gfs2_qd_lru);
  88        if (error)
  89                goto fail_lru;
  90
  91        error = gfs2_glock_init();
  92        if (error)
  93                goto fail;
  94
  95        error = -ENOMEM;
  96        gfs2_glock_cachep = kmem_cache_create("gfs2_glock",
  97                                              sizeof(struct gfs2_glock),
  98                                              0, 0,
  99                                              gfs2_init_glock_once);
 100        if (!gfs2_glock_cachep)
 101                goto fail;
 102
 103        gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)",
 104                                        sizeof(struct gfs2_glock) +
 105                                        sizeof(struct address_space),
 106                                        0, 0, gfs2_init_gl_aspace_once);
 107
 108        if (!gfs2_glock_aspace_cachep)
 109                goto fail;
 110
 111        gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
 112                                              sizeof(struct gfs2_inode),
 113                                              0,  SLAB_RECLAIM_ACCOUNT|
 114                                                  SLAB_MEM_SPREAD,
 115                                              gfs2_init_inode_once);
 116        if (!gfs2_inode_cachep)
 117                goto fail;
 118
 119        gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata",
 120                                                sizeof(struct gfs2_bufdata),
 121                                                0, 0, NULL);
 122        if (!gfs2_bufdata_cachep)
 123                goto fail;
 124
 125        gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd",
 126                                              sizeof(struct gfs2_rgrpd),
 127                                              0, 0, NULL);
 128        if (!gfs2_rgrpd_cachep)
 129                goto fail;
 130
 131        gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad",
 132                                               sizeof(struct gfs2_quota_data),
 133                                               0, 0, NULL);
 134        if (!gfs2_quotad_cachep)
 135                goto fail;
 136
 137        gfs2_rsrv_cachep = kmem_cache_create("gfs2_mblk",
 138                                             sizeof(struct gfs2_blkreserv),
 139                                               0, 0, NULL);
 140        if (!gfs2_rsrv_cachep)
 141                goto fail;
 142
 143        register_shrinker(&gfs2_qd_shrinker);
 144
 145        error = register_filesystem(&gfs2_fs_type);
 146        if (error)
 147                goto fail;
 148
 149        error = register_filesystem(&gfs2meta_fs_type);
 150        if (error)
 151                goto fail_unregister;
 152
 153        error = -ENOMEM;
 154        gfs_recovery_wq = alloc_workqueue("gfs_recovery",
 155                                          WQ_MEM_RECLAIM | WQ_FREEZABLE, 0);
 156        if (!gfs_recovery_wq)
 157                goto fail_wq;
 158
 159        gfs2_control_wq = alloc_workqueue("gfs2_control",
 160                                          WQ_UNBOUND | WQ_FREEZABLE, 0);
 161        if (!gfs2_control_wq)
 162                goto fail_recovery;
 163
 164        gfs2_page_pool = mempool_create_page_pool(64, 0);
 165        if (!gfs2_page_pool)
 166                goto fail_control;
 167
 168        gfs2_register_debugfs();
 169
 170        pr_info("GFS2 installed\n");
 171
 172        return 0;
 173
 174fail_control:
 175        destroy_workqueue(gfs2_control_wq);
 176fail_recovery:
 177        destroy_workqueue(gfs_recovery_wq);
 178fail_wq:
 179        unregister_filesystem(&gfs2meta_fs_type);
 180fail_unregister:
 181        unregister_filesystem(&gfs2_fs_type);
 182fail:
 183        list_lru_destroy(&gfs2_qd_lru);
 184fail_lru:
 185        unregister_shrinker(&gfs2_qd_shrinker);
 186        gfs2_glock_exit();
 187
 188        if (gfs2_rsrv_cachep)
 189                kmem_cache_destroy(gfs2_rsrv_cachep);
 190
 191        if (gfs2_quotad_cachep)
 192                kmem_cache_destroy(gfs2_quotad_cachep);
 193
 194        if (gfs2_rgrpd_cachep)
 195                kmem_cache_destroy(gfs2_rgrpd_cachep);
 196
 197        if (gfs2_bufdata_cachep)
 198                kmem_cache_destroy(gfs2_bufdata_cachep);
 199
 200        if (gfs2_inode_cachep)
 201                kmem_cache_destroy(gfs2_inode_cachep);
 202
 203        if (gfs2_glock_aspace_cachep)
 204                kmem_cache_destroy(gfs2_glock_aspace_cachep);
 205
 206        if (gfs2_glock_cachep)
 207                kmem_cache_destroy(gfs2_glock_cachep);
 208
 209        gfs2_sys_uninit();
 210        return error;
 211}
 212
 213/**
 214 * exit_gfs2_fs - Unregister the file system
 215 *
 216 */
 217
 218static void __exit exit_gfs2_fs(void)
 219{
 220        unregister_shrinker(&gfs2_qd_shrinker);
 221        gfs2_glock_exit();
 222        gfs2_unregister_debugfs();
 223        unregister_filesystem(&gfs2_fs_type);
 224        unregister_filesystem(&gfs2meta_fs_type);
 225        destroy_workqueue(gfs_recovery_wq);
 226        destroy_workqueue(gfs2_control_wq);
 227        list_lru_destroy(&gfs2_qd_lru);
 228
 229        rcu_barrier();
 230
 231        mempool_destroy(gfs2_page_pool);
 232        kmem_cache_destroy(gfs2_rsrv_cachep);
 233        kmem_cache_destroy(gfs2_quotad_cachep);
 234        kmem_cache_destroy(gfs2_rgrpd_cachep);
 235        kmem_cache_destroy(gfs2_bufdata_cachep);
 236        kmem_cache_destroy(gfs2_inode_cachep);
 237        kmem_cache_destroy(gfs2_glock_aspace_cachep);
 238        kmem_cache_destroy(gfs2_glock_cachep);
 239
 240        gfs2_sys_uninit();
 241}
 242
 243MODULE_DESCRIPTION("Global File System");
 244MODULE_AUTHOR("Red Hat, Inc.");
 245MODULE_LICENSE("GPL");
 246
 247module_init(init_gfs2_fs);
 248module_exit(exit_gfs2_fs);
 249
 250