lkml.org 
[lkml]   [2005]   [Feb]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH] relayfs redux, part 3
in the filesystem path especially relayfs_create_entry and the functions
called by it seem overly complex, probably because copying from ramfs
which allows namespace operations from userland. See the totally untested
code below for how it could be done more cleanly.

What I really dislike is the code for automatically creating complex
hiearchies. What kinds of hierachies does LTT use? It shouldn't be
more than subsystem/{stream1, stream2, ..., streamN}, right? In that
case I think we could leave it to the user to take of that himself.



static struct inode *relayfs_get_inode(struct super_block *sb, int mode)
{
struct inode * inode = new_inode(sb);

if (!inode)
return NULL;

inode->i_mode = mode;
inode->i_uid = 0;
inode->i_gid = 0;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
inode->i_mapping->backing_dev_info = &relayfs_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;

switch (mode & S_IFMT) {
case S_IFREG:
inode->i_fop = &relayfs_file_operations;
break;
case S_IFDIR:
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
/*
* directory inodes start off with i_nlink == 2 (for "." entry)
*/
inode->i_nlink++;
break;
default:
break;
}

return inode;
}

/**
* relayfs_create_entry - create a relayfs directory or file
* @name: the name of the file to create
* @parent: parent directory
* @dentry: result dentry
* @mode: mode
* @data: data to associate with the file
*
* Creates a file or directory with the specifed permissions.
*/
static int relayfs_create_entry(const char *name, struct dentry *parent,
struct dentry **dentry, int mode, void *data)
{
struct qstr qname;
struct dentry *d;
struct inode *inode;
int error = 0;

BUG_ON(!S_ISREG(mode) || !S_ISDIR(mode));

error = simple_pin_fs("relayfs", &relayfs_mount, &relayfs_mount_count);
if (error) {
printk(KERN_ERR "Couldn't mount relayfs: errcode %d\n", error);
return error;
}

qname.name = name;
qname.len = strlen(name);
qname.hash = full_name_hash(name, qname.len);

if (parent == NULL)
if (relayfs_mount && relayfs_mount->mnt_sb)
parent = relayfs_mount->mnt_sb->s_root;

if (parent == NULL) {
simple_release_fs(&relayfs_mount, &relayfs_mount_count);
return -EINVAL;
}

parent = dget(parent);
down(&parent->d_inode->i_sem);
d = lookup_hash(&qname, parent);
if (IS_ERR(d)) {
error = PTR_ERR(d);
goto release_mount;
}

if (d->d_inode) {
error = -EEXIST;
goto release_mount;
}

inode = relayfs_get_inode(parent->d_inode->i_sb, mode);
if (!inode) {
error = -ENOSPC;
goto release_mount;
}

d_instantiate(d, inode);
dget(d); /* Extra count - pin the dentry in core */

if (mode & S_IFREG)
d->d_inode->u.generic_ip = data;
else
parent->d_inode->i_nlink++;

error = 0;
goto exit;

release_mount:
simple_release_fs(&relayfs_mount, &relayfs_mount_count);

exit:
*dentry = d;
up(&parent->d_inode->i_sem);
dput(parent);

return error;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:10    [W:0.078 / U:0.412 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site