This commit was manufactured by cvs2svn to create branch 'ckrm'.
[linux-2.6.git] / fs / rcfs / super.c
1 /* 
2  * fs/rcfs/super.c 
3  *
4  * Copyright (C) Shailabh Nagar,  IBM Corp. 2004
5  *               Vivek Kashyap,   IBM Corp. 2004
6  *           
7  * Super block operations for rcfs
8  * 
9  *
10  * Latest version, more details at http://ckrm.sf.net
11  * 
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  */
18
19 /* Changes
20  *
21  * 08 Mar 2004
22  *        Created.
23  */
24
25
26 #include <linux/module.h>
27 #include <linux/fs.h>
28 #include <linux/namei.h>
29 #include <asm/namei.h>
30 #include <linux/namespace.h>
31 #include <linux/dcache.h>
32 #include <linux/seq_file.h>
33 #include <linux/pagemap.h>
34 #include <linux/highmem.h>
35 #include <linux/init.h>
36 #include <linux/string.h>
37 #include <linux/smp_lock.h>
38 #include <linux/backing-dev.h>
39 #include <linux/parser.h>
40
41 #include <asm/uaccess.h>
42
43 #include <linux/rcfs.h>
44 #include <linux/ckrm.h>
45
46
47 static kmem_cache_t *rcfs_inode_cachep;
48
49
50 inline struct rcfs_inode_info *RCFS_I(struct inode *inode)
51 {
52         return container_of(inode, struct rcfs_inode_info, vfs_inode);
53 }
54 EXPORT_SYMBOL(RCFS_I);
55
56
57
58 static struct inode *
59 rcfs_alloc_inode(struct super_block *sb)
60 {
61         struct rcfs_inode_info *ri;
62         ri = (struct rcfs_inode_info *) kmem_cache_alloc(rcfs_inode_cachep, 
63                                                          SLAB_KERNEL);
64         if (!ri)
65                 return NULL;
66         ri->name = NULL;
67         return &ri->vfs_inode;
68 }
69
70 static void 
71 rcfs_destroy_inode(struct inode *inode)
72 {
73         struct rcfs_inode_info *ri = RCFS_I(inode);
74
75         kfree(ri->name);
76         kmem_cache_free(rcfs_inode_cachep, RCFS_I(inode));
77 }
78
79 static void 
80 rcfs_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
81 {
82         struct rcfs_inode_info *ri = (struct rcfs_inode_info *) foo;
83
84         if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
85             SLAB_CTOR_CONSTRUCTOR)
86                 inode_init_once(&ri->vfs_inode);
87 }
88
89 int 
90 rcfs_init_inodecache(void)
91 {
92         rcfs_inode_cachep = kmem_cache_create("rcfs_inode_cache",
93                                 sizeof(struct rcfs_inode_info),
94                                 0, SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT,
95                                 rcfs_init_once, NULL);
96         if (rcfs_inode_cachep == NULL)
97                 return -ENOMEM;
98         return 0;
99 }
100
101 void rcfs_destroy_inodecache(void)
102 {
103         printk(KERN_WARNING "destroy inodecache was called\n");
104         if (kmem_cache_destroy(rcfs_inode_cachep))
105                 printk(KERN_INFO "rcfs_inode_cache: not all structures were freed\n");
106 }
107
108 struct super_operations rcfs_super_ops =
109 {
110         .alloc_inode    = rcfs_alloc_inode,
111         .destroy_inode  = rcfs_destroy_inode,
112         .statfs         = simple_statfs,
113         .drop_inode     = generic_delete_inode,
114 };
115
116
117 struct dentry *rcfs_rootde; /* redundant since one can also get it from sb */
118 static struct inode *rcfs_root;
119 static struct rcfs_inode_info *rcfs_rootri;
120
121 static int rcfs_mounted;
122
123 static int rcfs_fill_super(struct super_block * sb, void * data, int silent)
124 {
125         struct inode * inode;
126         struct dentry * root;
127         struct rcfs_inode_info *rootri;
128         struct ckrm_classtype *clstype;
129         int i,rc;
130
131         sb->s_fs_info = NULL;
132         if (rcfs_mounted) {
133                 return -EPERM;
134         }
135         rcfs_mounted++;
136
137         sb->s_blocksize = PAGE_CACHE_SIZE;
138         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;        
139         sb->s_magic = RCFS_MAGIC;
140         sb->s_op = &rcfs_super_ops;
141         inode = rcfs_get_inode(sb, S_IFDIR | 0755, 0);
142         if (!inode)
143                 return -ENOMEM;
144         inode->i_op = &rcfs_rootdir_inode_operations;
145
146         root = d_alloc_root(inode);
147         if (!root) {
148                 iput(inode);
149                 return -ENOMEM;
150         }
151         sb->s_root = root;
152
153         
154         // Link inode and core class 
155         rootri = RCFS_I(inode);
156         rootri->name = kmalloc(strlen(RCFS_ROOT) + 1, GFP_KERNEL);
157         if (!rootri->name) {
158                 d_delete(root);
159                 iput(inode);
160                 return -ENOMEM;
161         }
162         strcpy(rootri->name, RCFS_ROOT);
163         rootri->core = NULL;
164
165         rcfs_root = inode;
166         sb->s_fs_info = rcfs_root = inode;
167         rcfs_rootde = root ;
168         rcfs_rootri = rootri ;
169
170         // register metatypes
171         for ( i=0; i<CKRM_MAX_CLASSTYPES; i++) {
172                 clstype = ckrm_classtypes[i];
173                 if (clstype == NULL) 
174                         continue;
175                 printk("A non null classtype\n");
176
177                 if ((rc = rcfs_register_classtype(clstype)))
178                         continue ;  // could return with an error too 
179         }
180
181         // register CE's with rcfs 
182         // check if CE loaded
183         // call rcfs_register_engine for each classtype
184         // AND rcfs_mkroot (preferably subsume latter in former) 
185
186         return 0;
187 }
188
189
190 static struct super_block *rcfs_get_sb(struct file_system_type *fs_type,
191         int flags, const char *dev_name, void *data)
192 {
193         return get_sb_nodev(fs_type, flags, data, rcfs_fill_super);
194 }
195
196
197 void 
198 rcfs_kill_sb(struct super_block *sb)
199 {
200         int i,rc;
201         struct ckrm_classtype *clstype;
202
203         if (sb->s_fs_info != rcfs_root) {
204                 generic_shutdown_super(sb);
205                 return;
206         }
207         rcfs_mounted--;
208
209         for ( i=0; i < CKRM_MAX_CLASSTYPES; i++) {
210
211                 clstype = ckrm_classtypes[i];
212                 if (clstype == NULL || clstype->rootde == NULL) 
213                         continue;
214
215                 if ((rc = rcfs_deregister_classtype(clstype))) {
216                         printk(KERN_ERR "Error removing classtype %s\n",
217                                clstype->name);
218                         // return ;   // can also choose to stop here
219                 }
220         }
221         
222         // do not remove comment block until ce directory issue resolved
223         // deregister CE with rcfs
224         // Check if loaded
225         // if ce is in  one directory /rcfs/ce, 
226         //       rcfs_deregister_engine for all classtypes within above 
227         //             codebase 
228         //       followed by
229         //       rcfs_rmroot here
230         // if ce in multiple (per-classtype) directories
231         //       call rbce_deregister_engine within ckrm_deregister_classtype
232
233         // following will automatically clear rcfs root entry including its 
234         //  rcfs_inode_info
235
236         generic_shutdown_super(sb);
237
238         // printk(KERN_ERR "Removed all entries\n");
239 }       
240
241
242 static struct file_system_type rcfs_fs_type = {
243         .name           = "rcfs",
244         .get_sb         = rcfs_get_sb,
245         .kill_sb        = rcfs_kill_sb,
246 };
247
248 struct rcfs_functions my_rcfs_fn = {
249         .mkroot               = rcfs_mkroot,
250         .rmroot               = rcfs_rmroot,
251         .register_classtype   = rcfs_register_classtype,
252         .deregister_classtype = rcfs_deregister_classtype,
253 };
254
255 extern struct rcfs_functions rcfs_fn ;
256
257 static int __init init_rcfs_fs(void)
258 {
259         int ret;
260
261         ret = register_filesystem(&rcfs_fs_type);
262         if (ret)
263                 goto init_register_err;
264
265         ret = rcfs_init_inodecache();
266         if (ret)
267                 goto init_cache_err;
268
269         rcfs_fn = my_rcfs_fn ;
270         
271         return ret;
272
273 init_cache_err:
274         unregister_filesystem(&rcfs_fs_type);
275 init_register_err:
276         return ret;
277 }
278
279 static void __exit exit_rcfs_fs(void)
280 {
281         rcfs_destroy_inodecache();
282         unregister_filesystem(&rcfs_fs_type);
283 }
284
285 module_init(init_rcfs_fs)
286 module_exit(exit_rcfs_fs)
287
288 MODULE_LICENSE("GPL");