- PL2545 WAR: disable CKRM numtasks controller
[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 /*
20  * Changes
21  *
22  * 08 April 2004
23  *        Created.
24  */
25
26 #include <linux/module.h>
27 #include <linux/fs.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>
39
40 #include <asm/uaccess.h>
41
42 #include <linux/rcfs.h>
43
44 rbce_eng_callback_t rcfs_eng_callbacks = {
45         NULL, NULL
46 };
47
48 int rcfs_register_engine(rbce_eng_callback_t * rcbs)
49 {
50         if (!rcbs->mkdir || rcfs_eng_callbacks.mkdir) {
51                 return -EINVAL;
52         }
53         rcfs_eng_callbacks = *rcbs;
54         rcfs_engine_regd++;
55         return 0;
56 }
57
58 EXPORT_SYMBOL_GPL(rcfs_register_engine);
59
60 int rcfs_unregister_engine(rbce_eng_callback_t * rcbs)
61 {
62         if (!rcbs->mkdir || !rcfs_eng_callbacks.mkdir ||
63             (rcbs->mkdir != rcfs_eng_callbacks.mkdir)) {
64                 return -EINVAL;
65         }
66         rcfs_eng_callbacks.mkdir = NULL;
67         rcfs_eng_callbacks.rmdir = NULL;
68         rcfs_engine_regd--;
69         return 0;
70 }
71
72 EXPORT_SYMBOL(rcfs_unregister_engine);
73
74 /*
75  * rcfs_mkroot
76  * Create and return a "root" dentry under /rcfs. 
77  * Also create associated magic files 
78  *
79  * @mfdesc: array of rcfs_magf describing root dir and its magic files
80  * @count: number of entries in mfdesc
81  * @core:  core class to be associated with root
82  * @rootde: output parameter to return the newly created root dentry
83  */
84
85 int rcfs_mkroot(struct rcfs_magf *mfdesc, int mfcount, struct dentry **rootde)
86 {
87         int sz;
88         struct rcfs_magf *rootdesc = &mfdesc[0];
89         struct dentry *dentry;
90         struct rcfs_inode_info *rootri;
91
92         if ((mfcount < 0) || (!mfdesc))
93                 return -EINVAL;
94
95         rootdesc = &mfdesc[0];
96         printk(KERN_DEBUG "allocating classtype root <%s>\n", rootdesc->name);
97         dentry = rcfs_create_internal(rcfs_rootde, rootdesc, 0);
98
99         if (!dentry) {
100                 printk(KERN_ERR "Could not create %s\n", rootdesc->name);
101                 return -ENOMEM;
102         }
103         rootri = RCFS_I(dentry->d_inode);
104         sz = strlen(rootdesc->name) + strlen(RCFS_ROOT) + 2;
105         rootri->name = kmalloc(sz, GFP_KERNEL);
106         if (!rootri->name) {
107                 printk(KERN_ERR "Error allocating name for %s\n",
108                        rootdesc->name);
109                 rcfs_delete_internal(dentry);
110                 return -ENOMEM;
111         }
112         snprintf(rootri->name, sz, "%s/%s", RCFS_ROOT, rootdesc->name);
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_GPL(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_GPL(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         if (genmfdesc[clstype->mfidx] == NULL) {
150                 return -ENOMEM;
151         }
152
153         clstype->mfdesc = (void *)genmfdesc[clstype->mfidx]->rootmf;
154         clstype->mfcount = genmfdesc[clstype->mfidx]->rootmflen;
155
156         mfdesc = (struct rcfs_magf *)clstype->mfdesc;
157
158         /* rcfs root entry has the same name as the classtype */
159         strncpy(mfdesc[0].name, clstype->name, RCFS_MAGF_NAMELEN);
160
161         rc = rcfs_mkroot(mfdesc, clstype->mfcount,
162                          (struct dentry **)&(clstype->rootde));
163         if (rc)
164                 return rc;
165         rootri = RCFS_I(((struct dentry *)(clstype->rootde))->d_inode);
166         rootri->core = clstype->default_class;
167         clstype->default_class->name = rootri->name;
168         ckrm_core_grab(clstype->default_class);
169
170         /* Create magic files under root */
171         if ((rc = rcfs_create_magic(clstype->rootde, &mfdesc[1],
172                                     clstype->mfcount - 1))) {
173                 kfree(rootri->name);
174                 rootri->name = NULL;
175                 rcfs_delete_internal(clstype->rootde);
176                 return rc;
177         }
178         return rc;
179 }
180
181 EXPORT_SYMBOL_GPL(rcfs_register_classtype);
182
183 int rcfs_deregister_classtype(ckrm_classtype_t * clstype)
184 {
185         int rc;
186
187         rc = rcfs_rmroot((struct dentry *)clstype->rootde);
188         if (!rc) {
189                 clstype->default_class->name = NULL;
190                 ckrm_core_drop(clstype->default_class);
191         }
192         return rc;
193 }
194
195 EXPORT_SYMBOL_GPL(rcfs_deregister_classtype);
196
197 #ifdef CONFIG_CKRM_TYPE_TASKCLASS
198 extern struct rcfs_mfdesc tc_mfdesc;
199 #endif
200
201 #ifdef CONFIG_CKRM_TYPE_SOCKETCLASS
202 extern struct rcfs_mfdesc sock_mfdesc;
203 #endif
204
205 /* Common root and magic file entries.
206  * root name, root permissions, magic file names and magic file permissions 
207  * are needed by all entities (classtypes and classification engines) existing 
208  * under the rcfs mount point
209  *
210  * The common sets of these attributes are listed here as a table. Individual 
211  * classtypes and classification engines can simple specify the index into the 
212  * table to initialize their magf entries. 
213  */
214
215 struct rcfs_mfdesc *genmfdesc[CKRM_MAX_CLASSTYPES] = {
216 #ifdef CONFIG_CKRM_TYPE_TASKCLASS
217         &tc_mfdesc,
218 #else
219         NULL,
220 #endif
221 #ifdef CONFIG_CKRM_TYPE_SOCKETCLASS
222         &sock_mfdesc,
223 #else
224         NULL,
225 #endif
226
227 };