Commit 7beafd51 authored by Al Viro's avatar Al Viro
Browse files

convert binfmt_misc



removals are done with locked_recursive_removal(); switch creations to
simple_start_creating()/d_make_persistent()/simple_done_creating() and
take them to a helper (add_entry()), while we are at it - simpler control
flow that way.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent b85d6b24
Loading
Loading
Loading
Loading
+32 −37
Original line number Diff line number Diff line
@@ -765,14 +765,41 @@ static const struct file_operations bm_entry_operations = {

/* /register */

/* add to filesystem */
static int add_entry(Node *e, struct super_block *sb)
{
	struct dentry *dentry = simple_start_creating(sb->s_root, e->name);
	struct inode *inode;
	struct binfmt_misc *misc;

	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	inode = bm_get_inode(sb, S_IFREG | 0644);
	if (unlikely(!inode)) {
		simple_done_creating(dentry);
		return -ENOMEM;
	}

	refcount_set(&e->users, 1);
	e->dentry = dentry;
	inode->i_private = e;
	inode->i_fop = &bm_entry_operations;

	d_make_persistent(dentry, inode);
	misc = i_binfmt_misc(inode);
	write_lock(&misc->entries_lock);
	list_add(&e->list, &misc->entries);
	write_unlock(&misc->entries_lock);
	simple_done_creating(dentry);
	return 0;
}

static ssize_t bm_register_write(struct file *file, const char __user *buffer,
			       size_t count, loff_t *ppos)
{
	Node *e;
	struct inode *inode;
	struct super_block *sb = file_inode(file)->i_sb;
	struct dentry *root = sb->s_root, *dentry;
	struct binfmt_misc *misc;
	int err = 0;
	struct file *f = NULL;

@@ -803,39 +830,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
		e->interp_file = f;
	}

	inode_lock(d_inode(root));
	dentry = lookup_noperm(&QSTR(e->name), root);
	err = PTR_ERR(dentry);
	if (IS_ERR(dentry))
		goto out;

	err = -EEXIST;
	if (d_really_is_positive(dentry))
		goto out2;

	inode = bm_get_inode(sb, S_IFREG | 0644);

	err = -ENOMEM;
	if (!inode)
		goto out2;

	refcount_set(&e->users, 1);
	e->dentry = dget(dentry);
	inode->i_private = e;
	inode->i_fop = &bm_entry_operations;

	d_instantiate(dentry, inode);
	misc = i_binfmt_misc(inode);
	write_lock(&misc->entries_lock);
	list_add(&e->list, &misc->entries);
	write_unlock(&misc->entries_lock);

	err = 0;
out2:
	dput(dentry);
out:
	inode_unlock(d_inode(root));

	err = add_entry(e, sb);
	if (err) {
		if (f)
			filp_close(f, NULL);
@@ -1028,7 +1023,7 @@ static struct file_system_type bm_fs_type = {
	.name		= "binfmt_misc",
	.init_fs_context = bm_init_fs_context,
	.fs_flags	= FS_USERNS_MOUNT,
	.kill_sb	= kill_litter_super,
	.kill_sb	= kill_anon_super,
};
MODULE_ALIAS_FS("binfmt_misc");