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 );

Reply via email to