1/*
2 * Copyright 2016, NICTA
3 *
4 * This software may be distributed and modified according to the terms of
5 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
6 * See "LICENSE_GPLv2.txt" for details.
7 *
8 * @TAG(NICTA_GPL)
9 */
10
11#include <plat/linux/wrapper_pp_inferred.c>
12
13void bilbyfs_kill_super(struct super_block *sb);
14struct dentry *bilbyfs_mount(struct file_system_type *fs_type, int flags,
15                             const char *name, void *data);
16
17static struct file_system_type bilbyfs_fs_type = {
18        .name    = "bilbyfs",
19        .owner   = THIS_MODULE,
20        .mount   = bilbyfs_mount,
21        .kill_sb = bilbyfs_kill_super,
22};
23
24struct kmem_cache *node_slab;
25struct kmem_cache *bilbyfs_inode_slab;
26static void bilbyfs_free_inode(struct rcu_head *head)
27{
28        struct inode *inode = container_of(head, struct inode, i_rcu);
29
30        bilbyfs_debug("bilbyfs_free_inode(ino = %lu)\n", inode->i_ino);
31        kmem_cache_free(bilbyfs_inode_slab, inode);
32}
33
34
35static void bilbyfs_destroy_inode(struct inode *inode)
36{
37        bilbyfs_debug("bilbyfs_destroy_inode(ino=%lu)\n", inode->i_ino);
38        kfree(inode->i_private);
39        inode->i_private = NULL;
40
41        call_rcu(&inode->i_rcu, bilbyfs_free_inode);
42}
43
44
45static struct inode *bilbyfs_alloc_inode(struct super_block *sb)
46{
47        return kmem_cache_alloc(bilbyfs_inode_slab, GFP_NOFS);
48}
49
50static const struct super_operations bilbyfs_super_operations =
51{
52        .alloc_inode    = bilbyfs_alloc_inode,
53        .destroy_inode  = bilbyfs_destroy_inode,
54        .put_super      = bilbyfs_put_super,
55        .statfs         = bilbyfs_statfs,
56        /* .remount_fs     = bilbyfs_remount_fs, */
57        .evict_inode    = bilbyfs_evict_inode,
58        .sync_fs        = bilbyfs_sync_fs,
59};
60
61
62#define NODE_SIZE max(sizeof(BilbyFsRbtIndexNode), sizeof(BilbyFsRbtGimNode))
63static inline void node_slab_ctor(void *node)
64{
65       memset(node, 0, NODE_SIZE);
66        /* We don't initialise node */
67}
68
69static inline int allocpool_init(void)
70{
71        bilbyfs_debug("allocpool_init(%u)\n", NODE_SIZE);
72        node_slab = kmem_cache_create("bilbyfs_node_slab",
73                                NODE_SIZE, 0,
74                                SLAB_MEM_SPREAD | SLAB_RECLAIM_ACCOUNT,
75                                &node_slab_ctor);
76        if (!node_slab)
77                return -ENOMEM;
78        return 0;
79}
80
81static inline void allocpool_destroy(void)
82{
83        if (node_slab)
84                kmem_cache_destroy(node_slab);
85}
86
87/*
88 * Inode slab cache constructor.
89 */
90static void inode_slab_ctor(void *obj)
91{
92        inode_init_once(obj);
93}
94
95static int __init bilbyfs_init(void)
96{
97        int err;
98
99        /* Make sure node sizes are 8-byte aligned (BILBYFS_OBJ_PADDING) */
100        bilbyfs_inode_slab = kmem_cache_create("bilbyfs_inode_slab",
101                                sizeof(BilbyFsVfsInode), 0,
102                                SLAB_MEM_SPREAD | SLAB_RECLAIM_ACCOUNT,
103                                &inode_slab_ctor);
104        if (!bilbyfs_inode_slab)
105                return -ENOMEM;
106        err = allocpool_init();
107        if (!err)
108                err = register_filesystem(&bilbyfs_fs_type);
109        if (err) {
110                bilbyfs_err("cannot register file system, error %d", err);
111                kmem_cache_destroy(bilbyfs_inode_slab);
112                allocpool_destroy();
113                return err;
114        }
115        return 0;
116}
117module_init(bilbyfs_init);
118
119static void __exit bilbyfs_exit(void)
120{
121        /* Not sure why UBIFS destroy the slab before unregistering
122         * but for now we do the same. FIXME More investigation required.
123         */
124        rcu_barrier();
125        kmem_cache_destroy(bilbyfs_inode_slab);
126        unregister_filesystem(&bilbyfs_fs_type);
127}
128module_exit(bilbyfs_exit);
129
130MODULE_LICENSE("GPL");
131MODULE_VERSION(__stringify(BILBYFS_VERSION));
132MODULE_AUTHOR("Sidney Amani");
133MODULE_DESCRIPTION("BilbyFs - Bilby File System");
134
135