This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / fs / rcfs / rootdir.c
1 /* 
2  * fs/rcfs/rootdir.c 
3  *
4  * Copyright (C)   Vivek Kashyap,   IBM Corp. 2004
5  *           
6  * 
7  * Functions for creating root directories and magic files 
8  * for classtypes and classification engines under rcfs
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 April 2004
22  *        Created.
23  */
24
25 #include <linux/module.h>
26 #include <linux/fs.h>
27 #include <linux/namei.h>
28 #include <linux/namespace.h>
29 #include <linux/dcache.h>
30 #include <linux/seq_file.h>
31 #include <linux/pagemap.h>
32 #include <linux/highmem.h>
33 #include <linux/init.h>
34 #include <linux/string.h>
35 #include <linux/smp_lock.h>
36 #include <linux/backing-dev.h>
37 #include <linux/parser.h>
38
39 #include <asm/uaccess.h>
40
41 #include <linux/rcfs.h>
42
43 rbce_eng_callback_t rcfs_eng_callbacks = {
44         NULL, NULL
45 };
46
47 int rcfs_register_engine(rbce_eng_callback_t * rcbs)
48 {
49         if (!rcbs->mkdir || rcfs_eng_callbacks.mkdir) {
50                 return -EINVAL;
51         }
52         rcfs_eng_callbacks = *rcbs;
53         rcfs_engine_regd++;
54         return 0;
55 }
56
57 EXPORT_SYMBOL(rcfs_register_engine);
58
59 int rcfs_unregister_engine(rbce_eng_callback_t * rcbs)
60 {
61         if (!rcbs->mkdir || !rcfs_eng_callbacks.mkdir ||
62             (rcbs->mkdir != rcfs_eng_callbacks.mkdir)) {
63                 return -EINVAL;
64         }
65         rcfs_eng_callbacks.mkdir = NULL;
66         rcfs_eng_callbacks.rmdir = NULL;
67         rcfs_engine_regd--;
68         return 0;
69 }
70
71 EXPORT_SYMBOL(rcfs_unregister_engine);
72
73 /* rcfs_mkroot
74  * Create and return a "root" dentry under /rcfs. 
75  * Also create associated magic files 
76  *
77  * @mfdesc: array of rcfs_magf describing root dir and its magic files
78  * @count: number of entries in mfdesc
79  * @core:  core class to be associated with root
80  * @rootde: output parameter to return the newly created root dentry
81  */
82
83 int rcfs_mkroot(struct rcfs_magf *mfdesc, int mfcount, struct dentry **rootde)
84 {
85         int sz;
86         struct rcfs_magf *rootdesc = &mfdesc[0];
87         struct dentry *dentry;
88         struct rcfs_inode_info *rootri;
89
90         if ((mfcount < 0) || (!mfdesc))
91                 return -EINVAL;
92
93         rootdesc = &mfdesc[0];
94         printk("allocating classtype root <%s>\n", rootdesc->name);
95         dentry = rcfs_create_internal(rcfs_rootde, rootdesc, 0);
96
97         if (!dentry) {
98                 printk(KERN_ERR "Could not create %s\n", rootdesc->name);
99                 return -ENOMEM;
100         }
101
102         rootri = RCFS_I(dentry->d_inode);
103         sz = strlen(rootdesc->name) + strlen(RCFS_ROOT) + 2;
104         rootri->name = kmalloc(sz, GFP_KERNEL);
105         if (!rootri->name) {
106                 printk(KERN_ERR "Error allocating name for %s\n",
107                        rootdesc->name);
108                 rcfs_delete_internal(dentry);
109                 return -ENOMEM;
110         }
111         snprintf(rootri->name, sz, "%s/%s", RCFS_ROOT, rootdesc->name);
112
113         if (rootdesc->i_fop)
114                 dentry->d_inode->i_fop = rootdesc->i_fop;
115         if (rootdesc->i_op)
116                 dentry->d_inode->i_op = rootdesc->i_op;
117
118         // set output parameters
119         *rootde = dentry;
120
121         return 0;
122 }
123
124 EXPORT_SYMBOL(rcfs_mkroot);
125
126 int rcfs_rmroot(struct dentry *rootde)
127 {
128         struct rcfs_inode_info *ri;
129
130         if (!rootde)
131                 return -EINVAL;
132
133         rcfs_clear_magic(rootde);
134         ri = RCFS_I(rootde->d_inode);
135         kfree(ri->name);
136         ri->name = NULL;
137         rcfs_delete_internal(rootde);
138         return 0;
139 }
140
141 EXPORT_SYMBOL(rcfs_rmroot);
142
143 int rcfs_register_classtype(ckrm_classtype_t * clstype)
144 {
145         int rc;
146         struct rcfs_inode_info *rootri;
147         struct rcfs_magf *mfdesc;
148
149         // Initialize mfdesc, mfcount 
150         clstype->mfdesc = (void *)genmfdesc[clstype->mfidx]->rootmf;
151         clstype->mfcount = genmfdesc[clstype->mfidx]->rootmflen;
152
153         mfdesc = (struct rcfs_magf *)clstype->mfdesc;
154
155         /* rcfs root entry has the same name as the classtype */
156         strncpy(mfdesc[0].name, clstype->name, RCFS_MAGF_NAMELEN);
157
158         rc = rcfs_mkroot(mfdesc, clstype->mfcount,
159                          (struct dentry **)&(clstype->rootde));
160         if (rc)
161                 return rc;
162
163         rootri = RCFS_I(((struct dentry *)(clstype->rootde))->d_inode);
164         rootri->core = clstype->default_class;
165         clstype->default_class->name = rootri->name;
166         ckrm_core_grab(clstype->default_class);
167
168         // Create magic files under root 
169         if ((rc = rcfs_create_magic(clstype->rootde, &mfdesc[1],
170                                     clstype->mfcount - 1))) {
171                 kfree(rootri->name);
172                 rootri->name = NULL;
173                 rcfs_delete_internal(clstype->rootde);
174                 return rc;
175         }
176
177         return rc;
178 }
179
180 EXPORT_SYMBOL(rcfs_register_classtype);
181
182 int rcfs_deregister_classtype(ckrm_classtype_t * clstype)
183 {
184         int rc;
185
186         rc = rcfs_rmroot((struct dentry *)clstype->rootde);
187         if (!rc) {
188                 clstype->default_class->name = NULL;
189                 ckrm_core_drop(clstype->default_class);
190         }
191         return rc;
192 }
193
194 EXPORT_SYMBOL(rcfs_deregister_classtype);
195
196 // Common root and magic file entries.
197 // root name, root permissions, magic file names and magic file permissions 
198 // are needed by all entities (classtypes and classification engines) existing 
199 // under the rcfs mount point
200
201 // The common sets of these attributes are listed here as a table. Individual 
202 // classtypes and classification engines can simple specify the index into the 
203 // table to initialize their magf entries. 
204 //
205
206 #ifdef CONFIG_CKRM_TYPE_TASKCLASS
207 extern struct rcfs_mfdesc tc_mfdesc;
208 #endif
209
210 #ifdef CONFIG_CKRM_TYPE_TASKCLASS
211 extern struct rcfs_mfdesc sock_mfdesc;
212 #endif
213
214 // extern struct rcfs_magf rbce_mfdesc;
215
216 struct rcfs_mfdesc *genmfdesc[] = {
217 #ifdef CONFIG_CKRM_TYPE_TASKCLASS
218         &tc_mfdesc,
219 #else
220         NULL,
221 #endif
222 #ifdef CONFIG_CKRM_TYPE_SOCKETCLASS
223         &sock_mfdesc,
224 #else
225         NULL,
226 #endif
227 };