mirror of https://github.com/torvalds/linux.git
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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
b85d6b2419
commit
7beafd51c4
|
|
@ -765,14 +765,41 @@ static const struct file_operations bm_entry_operations = {
|
||||||
|
|
||||||
/* /register */
|
/* /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,
|
static ssize_t bm_register_write(struct file *file, const char __user *buffer,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
Node *e;
|
Node *e;
|
||||||
struct inode *inode;
|
|
||||||
struct super_block *sb = file_inode(file)->i_sb;
|
struct super_block *sb = file_inode(file)->i_sb;
|
||||||
struct dentry *root = sb->s_root, *dentry;
|
|
||||||
struct binfmt_misc *misc;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct file *f = NULL;
|
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;
|
e->interp_file = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
inode_lock(d_inode(root));
|
err = add_entry(e, sb);
|
||||||
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));
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
if (f)
|
if (f)
|
||||||
filp_close(f, NULL);
|
filp_close(f, NULL);
|
||||||
|
|
@ -1028,7 +1023,7 @@ static struct file_system_type bm_fs_type = {
|
||||||
.name = "binfmt_misc",
|
.name = "binfmt_misc",
|
||||||
.init_fs_context = bm_init_fs_context,
|
.init_fs_context = bm_init_fs_context,
|
||||||
.fs_flags = FS_USERNS_MOUNT,
|
.fs_flags = FS_USERNS_MOUNT,
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_anon_super,
|
||||||
};
|
};
|
||||||
MODULE_ALIAS_FS("binfmt_misc");
|
MODULE_ALIAS_FS("binfmt_misc");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue