4 * Copyright (C) Shailabh Nagar, IBM Corp. 2004
5 * Vivek Kashyap, IBM Corp. 2004
8 * Directory 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 <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>
41 #include <asm/uaccess.h>
43 #include <linux/rcfs.h>
47 #define rcfs_positive(dentry) ((dentry)->d_inode && !d_unhashed((dentry)))
49 int rcfs_empty(struct dentry *dentry)
54 spin_lock(&dcache_lock);
55 list_for_each_entry(child, &dentry->d_subdirs, d_child)
56 if (!rcfs_is_magic(child) && rcfs_positive(child))
60 spin_unlock(&dcache_lock);
67 /* Directory inode operations */
71 rcfs_create(struct inode *dir, struct dentry *dentry, int mode,
74 return rcfs_mknod(dir, dentry, mode | S_IFREG, 0);
76 EXPORT_SYMBOL(rcfs_create);
79 /* Symlinks permitted ?? */
81 rcfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
86 inode = rcfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
88 int l = strlen(symname)+1;
89 error = page_symlink(inode, symname, l);
91 if (dir->i_mode & S_ISGID)
92 inode->i_gid = dir->i_gid;
93 d_instantiate(dentry, inode);
100 EXPORT_SYMBOL(rcfs_symlink);
103 rcfs_create_coredir(struct inode *dir, struct dentry *dentry)
106 struct rcfs_inode_info *ripar, *ridir;
110 ridir = RCFS_I(dentry->d_inode);
112 // Inform RC's - do Core operations
113 if (ckrm_is_core_valid(ripar->core)) {
114 sz = strlen(ripar->name) + strlen(dentry->d_name.name) + 2 ;
115 ridir->name = kmalloc(sz, GFP_KERNEL);
119 snprintf(ridir->name, sz,"%s/%s", ripar->name,
120 dentry->d_name.name);
121 ridir->core = (*(ripar->core->classtype->alloc))
122 (ripar->core,ridir->name);
125 printk(KERN_ERR "rcfs_mkdir: Invalid parent core %p\n",
132 EXPORT_SYMBOL(rcfs_create_coredir);
136 rcfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
140 ckrm_classtype_t *clstype;
143 struct dentry *pd = list_entry(dir->i_dentry.next, struct dentry,
145 if ((!strcmp(pd->d_name.name, "/") &&
146 !strcmp(dentry->d_name.name, "ce"))) {
147 // Call CE's mkdir if it has registered, else fail.
148 if (rcfs_eng_callbacks.mkdir) {
149 return (*rcfs_eng_callbacks.mkdir)(dir, dentry, mode);
156 if (_rcfs_mknod(dir, dentry, mode | S_IFDIR, 0)) {
157 printk(KERN_ERR "rcfs_mkdir: error in _rcfs_mknod\n");
163 // Inherit parent's ops since _rcfs_mknod assigns noperm ops
164 dentry->d_inode->i_op = dir->i_op;
165 dentry->d_inode->i_fop = dir->i_fop;
168 retval = rcfs_create_coredir(dir, dentry);
170 simple_rmdir(dir,dentry);
175 // create the default set of magic files
176 clstype = (RCFS_I(dentry->d_inode))->core->classtype;
177 rcfs_create_magic(dentry, &(((struct rcfs_magf*)clstype->mfdesc)[1]),
186 EXPORT_SYMBOL(rcfs_mkdir);
190 rcfs_rmdir(struct inode * dir, struct dentry * dentry)
192 struct rcfs_inode_info *ri = RCFS_I(dentry->d_inode);
195 struct dentry *pd = list_entry(dir->i_dentry.next,
196 struct dentry, d_alias);
197 if ((!strcmp(pd->d_name.name, "/") &&
198 !strcmp(dentry->d_name.name, "ce"))) {
199 // Call CE's mkdir if it has registered, else fail.
200 if (rcfs_eng_callbacks.rmdir) {
201 return (*rcfs_eng_callbacks.rmdir)(dir, dentry);
203 return simple_rmdir(dir, dentry);
206 else if ((!strcmp(pd->d_name.name, "/") &&
207 !strcmp(dentry->d_name.name, "network"))) {
212 if (!rcfs_empty(dentry)) {
213 printk(KERN_ERR "rcfs_rmdir: directory not empty\n");
217 // Core class removal
219 if (ri->core == NULL) {
220 printk(KERN_ERR "rcfs_rmdir: core==NULL\n");
221 // likely a race condition
225 if ((*(ri->core->classtype->free))(ri->core)) {
226 printk(KERN_ERR "rcfs_rmdir: ckrm_free_core_class failed\n");
229 ri->core = NULL ; // just to be safe
231 // Clear magic files only after core successfully removed
232 rcfs_clear_magic(dentry);
234 return simple_rmdir(dir, dentry);
239 EXPORT_SYMBOL(rcfs_rmdir);
243 rcfs_unlink(struct inode *dir, struct dentry *dentry)
245 // -ENOENT and not -ENOPERM to allow rm -rf to work despite
246 // magic files being present
249 EXPORT_SYMBOL(rcfs_unlink);
251 // rename is allowed on directories only
253 rcfs_rename(struct inode *old_dir, struct dentry *old_dentry,
254 struct inode *new_dir, struct dentry *new_dentry)
256 if (S_ISDIR(old_dentry->d_inode->i_mode))
257 return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
261 EXPORT_SYMBOL(rcfs_rename);
264 struct inode_operations rcfs_dir_inode_operations = {
265 .create = rcfs_create,
266 .lookup = simple_lookup,
268 .unlink = rcfs_unlink,
269 .symlink = rcfs_symlink,
273 .rename = rcfs_rename,
281 rcfs_root_create(struct inode *dir, struct dentry *dentry, int mode,
282 struct nameidata *nd)
289 rcfs_root_symlink(struct inode * dir, struct dentry *dentry,
290 const char * symname)
296 rcfs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
302 rcfs_root_rmdir(struct inode * dir, struct dentry * dentry)
308 rcfs_root_unlink(struct inode *dir, struct dentry *dentry)
314 rcfs_root_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
320 rcfs_root_rename(struct inode *old_dir, struct dentry *old_dentry,
321 struct inode *new_dir, struct dentry *new_dentry)
326 struct inode_operations rcfs_rootdir_inode_operations = {
327 .create = rcfs_root_create,
328 .lookup = simple_lookup,
330 .unlink = rcfs_root_unlink,
331 .symlink = rcfs_root_symlink,
332 .mkdir = rcfs_root_mkdir,
333 .rmdir = rcfs_root_rmdir,
334 .mknod = rcfs_root_mknod,
335 .rename = rcfs_root_rename,