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#include <linux/slab.h>
  11#include <linux/spinlock.h>
  12#include <linux/completion.h>
  13#include <linux/buffer_head.h>
  14#include <linux/module.h>
  15#include <linux/init.h>
  16#include <linux/gfs2_ondisk.h>
  17#include <linux/rcupdate.h>
  18#include <linux/rculist_bl.h>
  19#include <linux/atomic.h>
  20
  21#include "gfs2.h"
  22#include "incore.h"
  23#include "super.h"
  24#include "sys.h"
  25#include "util.h"
  26#include "glock.h"
  27#include "quota.h"
  28#include "recovery.h"
  29#include "dir.h"
  30
  31struct workqueue_struct *gfs2_control_wq;
  32
  33static struct shrinker qd_shrinker = {
  34        .shrink = gfs2_shrink_qd_memory,
  35        .seeks = DEFAULT_SEEKS,
  36};
  37
  38static void gfs2_init_inode_once(void *foo)
  39{
  40        struct gfs2_inode *ip = foo;
  41
  42        inode_init_once(&ip->i_inode);
  43        init_rwsem(&ip->i_rw_mutex);
  44        INIT_LIST_HEAD(&ip->i_trunc_list);
  45        ip->i_qadata = NULL;
  46        ip->i_res = NULL;
  47        ip->i_hash_cache = NULL;
  48}
  49
  50static void gfs2_init_glock_once(void *foo)
  51{
  52        struct gfs2_glock *gl = foo;
  53
  54        INIT_HLIST_BL_NODE(&gl->gl_list);
  55        spin_lock_init(&gl->gl_spin);
  56        INIT_LIST_HEAD(&gl->gl_holders);
  57        INIT_LIST_HEAD(&gl->gl_lru);
  58        INIT_LIST_HEAD(&gl->gl_ail_list);
  59        atomic_set(&gl->gl_ail_count, 0);
  60        atomic_set(&gl->gl_revokes, 0);
  61}
  62
  63static void gfs2_init_gl_aspace_once(void *foo)
  64{
  65        struct gfs2_glock *gl = foo;
  66        struct address_space *mapping = (struct address_space *)(gl + 1);
  67
  68        gfs2_init_glock_once(gl);
  69        address_space_init_once(mapping);
  70}
  71
  72/**
  73 * init_gfs2_fs - Register GFS2 as a filesystem
  74 *
  75 * Returns: 0 on success, error code on failure
  76 */
  77
  78static int __init init_gfs2_fs(void)
  79{
  80        int error;
  81
  82        gfs2_str2qstr(&gfs2_qdot, ".");
  83        gfs2_str2qstr(&gfs2_qdotdot, "..");
  84
  85        error = gfs2_sys_init();
  86        if (error)
  87                return error;
  88
  89        error = gfs2_glock_init();
  90        if (error)
  91                goto fail;
  92
  93        error = -ENOMEM;
  94        gfs2_glock_cachep = kmem_cache_create("gfs2_glock",
  95                                              sizeof(struct gfs2_glock),
  96                                              0, 0,
  97                                              gfs2_init_glock_once);
  98        if (!gfs2_glock_cachep)
  99                goto fail;
 100
 101        gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)",
 102                                        sizeof(struct gfs2_glock) +
 103                                        sizeof(struct address_space),
 104                                        0, 0, gfs2_init_gl_aspace_once);
 105
 106        if (!gfs2_glock_aspace_cachep)
 107                goto fail;
 108
 109        gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
 110                                              sizeof(struct gfs2_inode),
 111                                              0,  SLAB_RECLAIM_ACCOUNT|
 112                                                  SLAB_MEM_SPREAD,
 113                                              gfs2_init_inode_once);
 114        if (!gfs2_inode_cachep)
 115                goto fail;
 116
 117        gfs2_bufdata_cachep = kmem_cache_create("gfs2_bufdata",
 118                                                sizeof(struct gfs2_bufdata),
 119                                                0, 0, NULL);
 120        if (!gfs2_bufdata_cachep)
 121                goto fail;
 122
 123        gfs2_rgrpd_cachep = kmem_cache_create("gfs2_rgrpd",
 124                                              sizeof(struct gfs2_rgrpd),
 125                                              0, 0, NULL);
 126        if (!gfs2_rgrpd_cachep)
 127                goto fail;
 128
 129        gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad",
 130                                               sizeof(struct gfs2_quota_data),
 131                                               0, 0, NULL);
 132        if (!gfs2_quotad_cachep)
 133                goto fail;
 134
 135        register_shrinker(&qd_shrinker);
 136
 137        error = register_filesystem(&gfs2_fs_type);
 138        if (error)
 139                goto fail;
 140
 141        error = register_filesystem(&gfs2meta_fs_type);
 142        if (error)
 143                goto fail_unregister;
 144
 145        error = -ENOMEM;
 146        gfs_recovery_wq = alloc_workqueue("gfs_recovery",
 147                                          WQ_MEM_RECLAIM | WQ_FREEZABLE, 0);
 148        if (!gfs_recovery_wq)
 149                goto fail_wq;
 150
 151        gfs2_control_wq = alloc_workqueue("gfs2_control",
 152                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_FREEZABLE, 0);
 153        if (!gfs2_control_wq)
 154                goto fail_control;
 155
 156        gfs2_register_debugfs();
 157
 158        printk("GFS2 installed\n");
 159
 160        return 0;
 161
 162fail_control:
 163        destroy_workqueue(gfs_recovery_wq);
 164fail_wq:
 165        unregister_filesystem(&gfs2meta_fs_type);
 166fail_unregister:
 167        unregister_filesystem(&gfs2_fs_type);
 168fail:
 169        unregister_shrinker(&qd_shrinker);
 170        gfs2_glock_exit();
 171
 172        if (gfs2_quotad_cachep)
 173                kmem_cache_destroy(gfs2_quotad_cachep);
 174
 175        if (gfs2_rgrpd_cachep)
 176                kmem_cache_destroy(gfs2_rgrpd_cachep);
 177
 178        if (gfs2_bufdata_cachep)
 179                kmem_cache_destroy(gfs2_bufdata_cachep);
 180
 181        if (gfs2_inode_cachep)
 182                kmem_cache_destroy(gfs2_inode_cachep);
 183
 184        if (gfs2_glock_aspace_cachep)
 185                kmem_cache_destroy(gfs2_glock_aspace_cachep);
 186
 187        if (gfs2_glock_cachep)
 188                kmem_cache_destroy(gfs2_glock_cachep);
 189
 190        gfs2_sys_uninit();
 191        return error;
 192}
 193
 194/**
 195 * exit_gfs2_fs - Unregister the file system
 196 *
 197 */
 198
 199static void __exit exit_gfs2_fs(void)
 200{
 201        unregister_shrinker(&qd_shrinker);
 202        gfs2_glock_exit();
 203        gfs2_unregister_debugfs();
 204        unregister_filesystem(&gfs2_fs_type);
 205        unregister_filesystem(&gfs2meta_fs_type);
 206        destroy_workqueue(gfs_recovery_wq);
 207        destroy_workqueue(gfs2_control_wq);
 208
 209        rcu_barrier();
 210
 211        kmem_cache_destroy(gfs2_quotad_cachep);
 212        kmem_cache_destroy(gfs2_rgrpd_cachep);
 213        kmem_cache_destroy(gfs2_bufdata_cachep);
 214        kmem_cache_destroy(gfs2_inode_cachep);
 215        kmem_cache_destroy(gfs2_glock_aspace_cachep);
 216        kmem_cache_destroy(gfs2_glock_cachep);
 217
 218        gfs2_sys_uninit();
 219}
 220
 221MODULE_DESCRIPTION("Global File System");
 222MODULE_AUTHOR("Red Hat, Inc.");
 223MODULE_LICENSE("GPL");
 224
 225module_init(init_gfs2_fs);
 226module_exit(exit_gfs2_fs);
 227
 228
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.