Generic create (CKRM RCFS rewrite)
Generic functions to create files/directories and cache their paths
(for use by RBCE). Use sane names and eliminate special
treatment of root directory entries.
Signed-off-by: Shailabh Nagar <[EMAIL PROTECTED]>
fs/rcfs/inode.c | 176 +++++++++++++++++++++++++++++++++------------------
fs/rcfs/rootdir.c | 52 ---------------
include/linux/rcfs.h | 8 +-
3 files changed, 122 insertions(+), 114 deletions(-)
Index: linux-2.6.12/fs/rcfs/inode.c
===================================================================
--- linux-2.6.12.orig/fs/rcfs/inode.c 2005-08-09 15:30:33.673781528 -0400
+++ linux-2.6.12/fs/rcfs/inode.c 2005-08-09 15:30:33.746770432 -0400
@@ -109,65 +109,6 @@ struct inode_operations rcfs_file_inode_
*/
int RCFS_IS_MAGIC;
-int rcfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
- struct inode *inode;
- int error = -EPERM;
-
- if (dentry->d_inode)
- return -EEXIST;
- inode = rcfs_get_inode(dir->i_sb, mode, dev);
- if (inode) {
- if (dir->i_mode & S_ISGID) {
- inode->i_gid = dir->i_gid;
- if (S_ISDIR(mode))
- inode->i_mode |= S_ISGID;
- }
- d_instantiate(dentry, inode);
- dget(dentry);
- error = 0;
- }
- return error;
-}
-
-struct dentry *rcfs_create_internal(struct dentry *parent,
- struct rcfs_magf *magf, int magic)
-{
- struct qstr qstr;
- struct dentry *mfdentry;
-
- /* Get new dentry for name */
- qstr.name = magf->name;
- qstr.len = strlen(magf->name);
- qstr.hash = full_name_hash(magf->name, qstr.len);
- mfdentry = lookup_hash(&qstr, parent);
-
- if (!IS_ERR(mfdentry)) {
- int err;
-
- down(&parent->d_inode->i_sem);
- if (magic && (magf->mode & S_IFDIR))
- err = parent->d_inode->i_op->mkdir(parent->d_inode,
- mfdentry,
- magf->mode);
- else {
- err = rcfs_mknod(parent->d_inode, mfdentry,
- magf->mode, 0);
- /*
- * rcfs_mknod doesn't increment parent's link count,
- * i_op->mkdir does.
- */
- parent->d_inode->i_nlink++;
- }
- up(&parent->d_inode->i_sem);
- if (err) {
- dput(mfdentry);
- return mfdentry;
- }
- }
- return mfdentry;
-}
-
int rcfs_delete_internal(struct dentry *mfdentry)
{
struct dentry *parent;
@@ -334,6 +275,123 @@ void rcfs_unhash(struct dentry *dentry)
spin_unlock(&dcache_lock);
}
+static int rcfs_mknod(struct inode *dir, struct dentry *dentry,
+ int mode, dev_t dev)
+{
+ struct inode *inode = rcfs_get_inode(dir->i_sb, mode, dev);
+ int error = -EPERM;
+
+ if (dentry->d_inode)
+ return -EEXIST;
+ if (inode) {
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ error = 0;
+ /* Inherit parent's ops by default */
+ inode->i_op = dir->i_op;
+ inode->i_fop = dir->i_fop;
+ }
+ return error;
+}
+
+static int rcfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+ mode = (mode & S_IALLUGO) | S_IFREG;
+ return rcfs_mknod(dir, dentry, mode, 0);
+}
+
+
+int rcfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ int res;
+
+ mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ res = rcfs_mknod(dir, dentry, mode, 0);
+ if (!res)
+ dir->i_nlink++;
+ return res;
+}
+
+static int rcfs_create_by_name(const char *name, mode_t mode,
+ struct dentry *parent, struct dentry **dentry)
+{
+ int error = 0, lockrc;
+
+ if (!parent || !name)
+ return -EFAULT;
+ *dentry = NULL;
+ /* If called to create a subdir, this lock is already held */
+ lockrc = down_trylock(&parent->d_inode->i_sem);
+ *dentry = rcfs_get_dentry(parent, name);
+
+ if (!IS_ERR(*dentry)) {
+ if ((mode & S_IFMT) == S_IFDIR)
+ error = rcfs_mkdir(parent->d_inode, *dentry, mode);
+ else
+ error = rcfs_create(parent->d_inode, *dentry, mode);
+ } else
+ error = PTR_ERR(*dentry);
+
+ if (!lockrc)
+ up(&parent->d_inode->i_sem);
+ return error;
+}
+
+
+struct dentry *rcfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct file_operations *fops,
+ struct inode_operations *iops,
+ void *data)
+{
+ struct dentry *dentry = NULL;
+ int error;
+
+ error = rcfs_create_by_name(name, mode, parent, &dentry);
+ if (error) {
+ dentry = NULL;
+ goto exit;
+ }
+ if (dentry->d_inode) {
+ if (data)
+ dentry->d_inode->u.generic_ip = data;
+ if (fops)
+ dentry->d_inode->i_fop = fops;
+ if (iops)
+ dentry->d_inode->i_op = iops;
+ }
+exit:
+ return dentry;
+}
+
+/* Fill inode name */
+int rcfs_name(struct dentry *parent, struct inode *inode, char *name)
+{
+ struct rcfs_inode_info *ri;
+ char *prefix;
+ int sz;
+
+ if (!parent)
+ prefix = NULL;
+ else if (parent == rcfs_root_dentry)
+ prefix = RCFS_ROOT;
+ else
+ prefix = (rcfs_get_inode_info(parent->d_inode))->name;
+
+ ri = rcfs_get_inode_info(inode);
+ sz = strlen(name) + strlen(prefix) + 2;
+ ri->name = kmalloc(sz, GFP_KERNEL);
+ if (!ri->name)
+ return -ENOMEM;
+ if (prefix)
+ snprintf(ri->name, sz, "%s/%s", prefix, name);
+ else
+ snprintf(ri->name, sz, "%s", name);
+
+ return 0;
+}
+
+
static struct file_system_type rcfs_fs_type = {
.owner = THIS_MODULE,
.name = "rcfs",
Index: linux-2.6.12/fs/rcfs/rootdir.c
===================================================================
--- linux-2.6.12.orig/fs/rcfs/rootdir.c 2005-08-09 15:30:33.673781528 -0400
+++ linux-2.6.12/fs/rcfs/rootdir.c 2005-08-09 15:30:33.746770432 -0400
@@ -60,58 +60,6 @@ int rcfs_unregister_engine(struct rbce_e
EXPORT_SYMBOL_GPL(rcfs_unregister_engine);
-/*
- * rcfs_mkroot
- * Create and return a "root" dentry under /rcfs.
- * Also create associated magic files
- *
- * @mfdesc: array of rcfs_magf describing root dir and its magic files
- * @count: number of entries in mfdesc
- * @core: core class to be associated with root
- * @rootde: output parameter to return the newly created root dentry
- */
-
-int rcfs_mkroot(struct rcfs_magf *mfdesc, int mfcount, struct dentry **rootde)
-{
- int sz;
- struct rcfs_magf *rootdesc = &mfdesc[0];
- struct dentry *dentry;
- struct rcfs_inode_info *rootri;
-
- if ((mfcount < 0) || (!mfdesc))
- return -EINVAL;
-
- rootdesc = &mfdesc[0];
- printk("allocating classtype root <%s>\n", rootdesc->name);
- dentry = rcfs_create_internal(rcfs_rootde, rootdesc, 0);
-
- if (!dentry) {
- printk(KERN_ERR "Could not create %s\n", rootdesc->name);
- return -ENOMEM;
- }
- rootri = rcfs_get_inode_info(dentry->d_inode);
- sz = strlen(rootdesc->name) + strlen(RCFS_ROOT) + 2;
- rootri->name = kmalloc(sz, GFP_KERNEL);
- if (!rootri->name) {
- printk(KERN_ERR "Error allocating name for %s\n",
- rootdesc->name);
- rcfs_delete_internal(dentry);
- return -ENOMEM;
- }
- snprintf(rootri->name, sz, "%s/%s", RCFS_ROOT, rootdesc->name);
- if (rootdesc->i_fop)
- dentry->d_inode->i_fop = rootdesc->i_fop;
- if (rootdesc->i_op)
- dentry->d_inode->i_op = rootdesc->i_op;
-
- /* set output parameters */
- *rootde = dentry;
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(rcfs_mkroot);
-
int rcfs_rmroot(struct dentry *rootde)
{
struct rcfs_inode_info *ri;
Index: linux-2.6.12/include/linux/rcfs.h
===================================================================
--- linux-2.6.12.orig/include/linux/rcfs.h 2005-08-09 15:30:33.673781528 -0400
+++ linux-2.6.12/include/linux/rcfs.h 2005-08-09 15:30:33.747770280 -0400
@@ -57,9 +57,7 @@ struct rcfs_mfdesc {
extern struct rcfs_mfdesc *genmfdesc[];
-int rcfs_mknod(struct inode *, struct dentry *, int, dev_t);
struct dentry *rcfs_set_magf_byname(char *, void *);
-struct dentry *rcfs_create_internal(struct dentry *, struct rcfs_magf *, int);
int rcfs_delete_internal(struct dentry *);
int rcfs_create_magic(struct dentry *, struct rcfs_magf *, int);
int rcfs_clear_magic(struct dentry *);
@@ -79,13 +77,17 @@ extern struct file_operations rcfs_file_
int rcfs_register_classtype(struct ckrm_classtype *);
int rcfs_deregister_classtype(struct ckrm_classtype *);
-int rcfs_mkroot(struct rcfs_magf *, int, struct dentry **);
int rcfs_rmroot(struct dentry *);
#define RCFS_ROOT "/rcfs" /* TODO: Should use the mount point */
extern struct dentry *rcfs_rootde;
extern struct rbce_eng_callback rcfs_eng_callbacks;
+/* Helper functions */
+extern int rcfs_mkdir(struct inode *, struct dentry *, int);
+extern struct dentry *rcfs_create_file(const char *, mode_t, struct dentry *, struct file_operations *, struct inode_operations *, void *);
+extern int rcfs_name(struct dentry *, struct inode *, char *);
+
extern int rcfs_create_noperm(struct inode *, struct dentry *, int , struct nameidata *);
extern int rcfs_symlink_noperm(struct inode *, struct dentry *, const char *);
extern int rcfs_mkdir_noperm(struct inode *, struct dentry *, int );