3 * Copyright (C) Vivek Kashyap, IBM Corp. 2004
5 * Latest version, more details at http://ckrm.sf.net
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
18 /*******************************************************************************
21 * Defines the root structure for socket based classes. Currently only inbound
22 * connection control is supported based on prioritized accept queues.
23 ******************************************************************************/
25 #include <linux/rcfs.h>
28 extern int rcfs_create(struct inode *, struct dentry *, int,
30 extern int rcfs_unlink(struct inode *, struct dentry *);
31 extern int rcfs_symlink(struct inode *, struct dentry *, const char *);
32 extern int rcfs_mknod(struct inode *, struct dentry *, int mode, dev_t);
33 extern int rcfs_mkdir(struct inode *, struct dentry *, int);
34 extern int rcfs_rmdir(struct inode *, struct dentry *);
35 extern int rcfs_rename(struct inode *, struct dentry *, struct inode *,
38 extern int rcfs_create_coredir(struct inode *, struct dentry *);
39 int sock_mkdir(struct inode *, struct dentry *, int mode);
40 int sock_rmdir(struct inode *, struct dentry *);
42 int sock_create_noperm(struct inode *, struct dentry *, int,
44 int sock_unlink_noperm(struct inode *, struct dentry *);
45 int sock_mkdir_noperm(struct inode *, struct dentry *, int);
46 int sock_rmdir_noperm(struct inode *, struct dentry *);
47 int sock_mknod_noperm(struct inode *, struct dentry *, int, dev_t);
49 void sock_set_directory(void);
51 extern struct file_operations config_fileops,
52 members_fileops, shares_fileops, stats_fileops, target_fileops;
54 struct inode_operations my_iops = {
55 .create = rcfs_create,
56 .lookup = simple_lookup,
58 .unlink = rcfs_unlink,
59 .symlink = rcfs_symlink,
63 .rename = rcfs_rename,
66 struct inode_operations class_iops = {
67 .create = sock_create_noperm,
68 .lookup = simple_lookup,
70 .unlink = sock_unlink_noperm,
71 .symlink = rcfs_symlink,
72 .mkdir = sock_mkdir_noperm,
73 .rmdir = sock_rmdir_noperm,
74 .mknod = sock_mknod_noperm,
75 .rename = rcfs_rename,
78 struct inode_operations sub_iops = {
79 .create = sock_create_noperm,
80 .lookup = simple_lookup,
82 .unlink = sock_unlink_noperm,
83 .symlink = rcfs_symlink,
84 .mkdir = sock_mkdir_noperm,
85 .rmdir = sock_rmdir_noperm,
86 .mknod = sock_mknod_noperm,
87 .rename = rcfs_rename,
90 struct rcfs_magf def_magf = {
91 .mode = RCFS_DEFAULT_DIR_MODE,
96 struct rcfs_magf sock_rootdesc[] = {
98 // .name = should not be set, copy from classtype name,
99 .mode = RCFS_DEFAULT_DIR_MODE,
101 //.i_fop = &simple_dir_operations,
106 .mode = RCFS_DEFAULT_FILE_MODE,
108 .i_fop = &members_fileops,
112 .mode = RCFS_DEFAULT_FILE_MODE,
114 .i_fop = &target_fileops,
118 struct rcfs_magf sock_magf[] = {
121 .mode = RCFS_DEFAULT_FILE_MODE,
123 .i_fop = &config_fileops,
127 .mode = RCFS_DEFAULT_FILE_MODE,
129 .i_fop = &members_fileops,
133 .mode = RCFS_DEFAULT_FILE_MODE,
135 .i_fop = &shares_fileops,
139 .mode = RCFS_DEFAULT_FILE_MODE,
141 .i_fop = &stats_fileops,
145 .mode = RCFS_DEFAULT_FILE_MODE,
147 .i_fop = &target_fileops,
151 struct rcfs_magf sub_magf[] = {
154 .mode = RCFS_DEFAULT_FILE_MODE,
156 .i_fop = &config_fileops,
160 .mode = RCFS_DEFAULT_FILE_MODE,
162 .i_fop = &shares_fileops,
166 .mode = RCFS_DEFAULT_FILE_MODE,
168 .i_fop = &stats_fileops,
172 struct rcfs_mfdesc sock_mfdesc = {
173 .rootmf = sock_rootdesc,
174 .rootmflen = (sizeof(sock_rootdesc) / sizeof(struct rcfs_magf)),
177 #define SOCK_MAX_MAGF (sizeof(sock_magf)/sizeof(struct rcfs_magf))
178 #define LAQ_MAX_SUBMAGF (sizeof(sub_magf)/sizeof(struct rcfs_magf))
180 int sock_rmdir(struct inode *p, struct dentry *me)
182 struct dentry *mftmp, *mfdentry;
185 // delete all magic sub directories
186 list_for_each_entry_safe(mfdentry, mftmp, &me->d_subdirs, d_child) {
187 if (S_ISDIR(mfdentry->d_inode->i_mode)) {
188 ret = rcfs_rmdir(me->d_inode, mfdentry);
194 ret = rcfs_rmdir(p, me);
199 #ifdef NUM_ACCEPT_QUEUES
200 #define LAQ_NUM_ACCEPT_QUEUES NUM_ACCEPT_QUEUES
202 #define LAQ_NUM_ACCEPT_QUEUES 0
205 int sock_mkdir(struct inode *dir, struct dentry *dentry, int mode)
209 struct dentry *pentry, *mfdentry;
211 if (_rcfs_mknod(dir, dentry, mode | S_IFDIR, 0)) {
212 printk(KERN_ERR "rcfs_mkdir: error reaching parent\n");
215 // Needed if only _rcfs_mknod is used instead of i_op->mkdir
218 retval = rcfs_create_coredir(dir, dentry);
222 /* create the default set of magic files */
223 for (i = 0; i < SOCK_MAX_MAGF; i++) {
224 mfdentry = rcfs_create_internal(dentry, &sock_magf[i], 0);
225 mfdentry->d_fsdata = &RCFS_IS_MAGIC;
226 RCFS_I(mfdentry->d_inode)->core = RCFS_I(dentry->d_inode)->core;
227 if (sock_magf[i].i_fop)
228 mfdentry->d_inode->i_fop = sock_magf[i].i_fop;
229 if (sock_magf[i].i_op)
230 mfdentry->d_inode->i_op = sock_magf[i].i_op;
233 for (i = 1; i < LAQ_NUM_ACCEPT_QUEUES; i++) {
234 j = sprintf(def_magf.name, "%d", i);
235 def_magf.name[j] = '\0';
237 pentry = rcfs_create_internal(dentry, &def_magf, 0);
238 retval = rcfs_create_coredir(dentry->d_inode, pentry);
241 pentry->d_fsdata = &RCFS_IS_MAGIC;
242 for (j = 0; j < LAQ_MAX_SUBMAGF; j++) {
244 rcfs_create_internal(pentry, &sub_magf[j], 0);
245 mfdentry->d_fsdata = &RCFS_IS_MAGIC;
246 RCFS_I(mfdentry->d_inode)->core =
247 RCFS_I(pentry->d_inode)->core;
248 if (sub_magf[j].i_fop)
249 mfdentry->d_inode->i_fop = sub_magf[j].i_fop;
250 if (sub_magf[j].i_op)
251 mfdentry->d_inode->i_op = sub_magf[j].i_op;
253 pentry->d_inode->i_op = &sub_iops;
255 dentry->d_inode->i_op = &class_iops;
264 #ifndef NUM_ACCEPT_QUEUES
265 #define NUM_ACCEPT_QUEUES 0
268 char *sock_get_name(struct ckrm_core_class *c)
270 char *p = (char *)c->name;
274 while (*p != '/' && p != c->name)
281 sock_create_noperm(struct inode *dir, struct dentry *dentry, int mode,
282 struct nameidata *nd)
287 int sock_unlink_noperm(struct inode *dir, struct dentry *dentry)
292 int sock_mkdir_noperm(struct inode *dir, struct dentry *dentry, int mode)
297 int sock_rmdir_noperm(struct inode *dir, struct dentry *dentry)
303 sock_mknod_noperm(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
309 void sock_set_directory()
311 struct dentry *pentry, *dentry;
313 pentry = rcfs_set_magf_byname("listen_aq", (void *)&my_dir_magf[0]);
315 dentry = rcfs_create_internal(pentry, &my_dir_magf[1], 0);
316 if (my_dir_magf[1].i_fop)
317 dentry->d_inode->i_fop = my_dir_magf[1].i_fop;
318 RCFS_I(dentry->d_inode)->core = RCFS_I(pentry->d_inode)->core;
319 dentry = rcfs_create_internal(pentry, &my_dir_magf[2], 0);
320 if (my_dir_magf[2].i_fop)
321 dentry->d_inode->i_fop = my_dir_magf[2].i_fop;
322 RCFS_I(dentry->d_inode)->core = RCFS_I(pentry->d_inode)->core;
324 printk(KERN_ERR "Could not create /rcfs/listen_aq\n"
325 "Perhaps /rcfs needs to be mounted\n");