4 * Copyright (C) Shailabh Nagar, IBM Corp. 2004
5 * Vivek Kashyap, IBM Corp. 2004
7 * Super block operations for rcfs
10 * Latest version, more details at http://ckrm.sf.net
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.
26 #include <linux/module.h>
28 #include <linux/namei.h>
29 #include <linux/namespace.h>
30 #include <linux/dcache.h>
31 #include <linux/seq_file.h>
32 #include <linux/pagemap.h>
33 #include <linux/highmem.h>
34 #include <linux/init.h>
35 #include <linux/string.h>
36 #include <linux/smp_lock.h>
37 #include <linux/backing-dev.h>
38 #include <linux/parser.h>
40 #include <asm/uaccess.h>
42 #include <linux/rcfs.h>
43 #include <linux/ckrm_rc.h>
44 #include <linux/ckrm_ce.h>
46 static kmem_cache_t *rcfs_inode_cachep;
48 struct rcfs_inode_info *RCFS_I(struct inode *inode)
50 return container_of(inode, struct rcfs_inode_info, vfs_inode);
53 EXPORT_SYMBOL_GPL(RCFS_I);
55 static struct inode *rcfs_alloc_inode(struct super_block *sb)
57 struct rcfs_inode_info *ri;
58 ri = (struct rcfs_inode_info *)kmem_cache_alloc(rcfs_inode_cachep,
63 return &ri->vfs_inode;
66 static void rcfs_destroy_inode(struct inode *inode)
68 struct rcfs_inode_info *ri = RCFS_I(inode);
71 kmem_cache_free(rcfs_inode_cachep, ri);
75 rcfs_init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
77 struct rcfs_inode_info *ri = (struct rcfs_inode_info *)foo;
79 if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
80 SLAB_CTOR_CONSTRUCTOR)
81 inode_init_once(&ri->vfs_inode);
84 int rcfs_init_inodecache(void)
86 rcfs_inode_cachep = kmem_cache_create("rcfs_inode_cache",
87 sizeof(struct rcfs_inode_info),
91 rcfs_init_once, NULL);
92 if (rcfs_inode_cachep == NULL)
97 void rcfs_destroy_inodecache(void)
99 printk(KERN_WARNING "destroy inodecache was called\n");
100 if (kmem_cache_destroy(rcfs_inode_cachep))
102 "rcfs_inode_cache: not all structures were freed\n");
105 struct super_operations rcfs_super_ops = {
106 .alloc_inode = rcfs_alloc_inode,
107 .destroy_inode = rcfs_destroy_inode,
108 .statfs = simple_statfs,
109 .drop_inode = generic_delete_inode,
112 struct dentry *rcfs_rootde; /* redundant; can also get it from sb */
113 static struct inode *rcfs_root;
114 static struct rcfs_inode_info *rcfs_rootri;
116 static int rcfs_fill_super(struct super_block *sb, void *data, int silent)
120 struct rcfs_inode_info *rootri;
121 struct ckrm_classtype *clstype;
124 sb->s_fs_info = NULL;
130 sb->s_blocksize = PAGE_CACHE_SIZE;
131 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
132 sb->s_magic = RCFS_MAGIC;
133 sb->s_op = &rcfs_super_ops;
134 inode = rcfs_get_inode(sb, S_IFDIR | 0755, 0);
137 inode->i_op = &rcfs_rootdir_inode_operations;
139 root = d_alloc_root(inode);
146 /* Link inode and core class */
147 rootri = RCFS_I(inode);
148 rootri->name = kmalloc(strlen(RCFS_ROOT) + 1, GFP_KERNEL);
154 strcpy(rootri->name, RCFS_ROOT);
158 sb->s_fs_info = rcfs_root = inode;
160 rcfs_rootri = rootri;
162 /* register metatypes */
163 for (i = 0; i < CKRM_MAX_CLASSTYPES; i++) {
164 clstype = ckrm_classtypes[i];
167 printk(KERN_DEBUG "A non null classtype\n");
169 if ((rc = rcfs_register_classtype(clstype)))
170 continue; /* could return with an error too */
174 * do post-mount initializations needed by CE
175 * this is distinct from CE registration done on rcfs module load
177 if (rcfs_engine_regd) {
178 if (rcfs_eng_callbacks.mnt)
179 if ((rc = (*rcfs_eng_callbacks.mnt) ())) {
180 printk(KERN_ERR "Error in CE mnt %d\n", rc);
184 * Following comment handled by code above; keep nonetheless if it
187 * register CE's with rcfs
189 * call rcfs_register_engine for each classtype
190 * AND rcfs_mkroot (preferably subsume latter in former)
195 static struct super_block *rcfs_get_sb(struct file_system_type *fs_type,
196 int flags, const char *dev_name,
199 return get_sb_nodev(fs_type, flags, data, rcfs_fill_super);
202 void rcfs_kill_sb(struct super_block *sb)
205 struct ckrm_classtype *clstype;
207 if (sb->s_fs_info != rcfs_root) {
208 generic_shutdown_super(sb);
213 for (i = 0; i < CKRM_MAX_CLASSTYPES; i++) {
214 clstype = ckrm_classtypes[i];
215 if (clstype == NULL || clstype->rootde == NULL)
218 if ((rc = rcfs_deregister_classtype(clstype))) {
219 printk(KERN_ERR "Error removing classtype %s\n",
225 * do pre-umount shutdown needed by CE
226 * this is distinct from CE deregistration done on rcfs module unload
228 if (rcfs_engine_regd) {
229 if (rcfs_eng_callbacks.umnt)
230 if ((rc = (*rcfs_eng_callbacks.umnt) ())) {
231 printk(KERN_ERR "Error in CE umnt %d\n", rc);
232 /* TODO: return ; until error handling improves */
236 * Following comment handled by code above; keep nonetheless if it
239 * deregister CE with rcfs
241 * if ce is in one directory /rcfs/ce,
242 * rcfs_deregister_engine for all classtypes within above
246 * if ce in multiple (per-classtype) directories
247 * call rbce_deregister_engine within ckrm_deregister_classtype
249 * following will automatically clear rcfs root entry including its
253 generic_shutdown_super(sb);
256 static struct file_system_type rcfs_fs_type = {
258 .get_sb = rcfs_get_sb,
259 .kill_sb = rcfs_kill_sb,
262 struct rcfs_functions my_rcfs_fn = {
263 .mkroot = rcfs_mkroot,
264 .rmroot = rcfs_rmroot,
265 .register_classtype = rcfs_register_classtype,
266 .deregister_classtype = rcfs_deregister_classtype,
269 extern struct rcfs_functions rcfs_fn;
271 static int __init init_rcfs_fs(void)
275 ret = register_filesystem(&rcfs_fs_type);
277 goto init_register_err;
278 ret = rcfs_init_inodecache();
281 rcfs_fn = my_rcfs_fn;
283 * Due to tight coupling of this module with ckrm
284 * do not allow this module to be removed.
286 try_module_get(THIS_MODULE);
290 unregister_filesystem(&rcfs_fs_type);
295 static void __exit exit_rcfs_fs(void)
297 rcfs_destroy_inodecache();
298 unregister_filesystem(&rcfs_fs_type);
301 module_init(init_rcfs_fs)
302 module_exit(exit_rcfs_fs)
304 MODULE_LICENSE("GPL");