mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
binfmt_misc: switch to locked_recursive_removal()
... fixing a mount leak, strictly speaking. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8c0e092e38
commit
eacb58fdca
@ -674,44 +674,6 @@ static void bm_evict_inode(struct inode *inode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* unlink_binfmt_dentry - remove the dentry for the binary type handler
|
||||
* @dentry: dentry associated with the binary type handler
|
||||
*
|
||||
* Do the actual filesystem work to remove a dentry for a registered binary
|
||||
* type handler. Since binfmt_misc only allows simple files to be created
|
||||
* directly under the root dentry of the filesystem we ensure that we are
|
||||
* indeed passed a dentry directly beneath the root dentry, that the inode
|
||||
* associated with the root dentry is locked, and that it is a regular file we
|
||||
* are asked to remove.
|
||||
*/
|
||||
static void unlink_binfmt_dentry(struct dentry *dentry)
|
||||
{
|
||||
struct dentry *parent = dentry->d_parent;
|
||||
struct inode *inode, *parent_inode;
|
||||
|
||||
/* All entries are immediate descendants of the root dentry. */
|
||||
if (WARN_ON_ONCE(dentry->d_sb->s_root != parent))
|
||||
return;
|
||||
|
||||
/* We only expect to be called on regular files. */
|
||||
inode = d_inode(dentry);
|
||||
if (WARN_ON_ONCE(!S_ISREG(inode->i_mode)))
|
||||
return;
|
||||
|
||||
/* The parent inode must be locked. */
|
||||
parent_inode = d_inode(parent);
|
||||
if (WARN_ON_ONCE(!inode_is_locked(parent_inode)))
|
||||
return;
|
||||
|
||||
if (simple_positive(dentry)) {
|
||||
dget(dentry);
|
||||
simple_unlink(parent_inode, dentry);
|
||||
d_delete(dentry);
|
||||
dput(dentry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_binfmt_handler - remove a binary type handler
|
||||
* @misc: handle to binfmt_misc instance
|
||||
@ -729,7 +691,7 @@ static void remove_binfmt_handler(struct binfmt_misc *misc, Node *e)
|
||||
write_lock(&misc->entries_lock);
|
||||
list_del_init(&e->list);
|
||||
write_unlock(&misc->entries_lock);
|
||||
unlink_binfmt_dentry(e->dentry);
|
||||
locked_recursive_removal(e->dentry, NULL);
|
||||
}
|
||||
|
||||
/* /<entry> */
|
||||
@ -772,7 +734,7 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
|
||||
case 3:
|
||||
/* Delete this handler. */
|
||||
inode = d_inode(inode->i_sb->s_root);
|
||||
inode_lock(inode);
|
||||
inode_lock_nested(inode, I_MUTEX_PARENT);
|
||||
|
||||
/*
|
||||
* In order to add new element or remove elements from the list
|
||||
@ -922,7 +884,7 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer,
|
||||
case 3:
|
||||
/* Delete all handlers. */
|
||||
inode = d_inode(file_inode(file)->i_sb->s_root);
|
||||
inode_lock(inode);
|
||||
inode_lock_nested(inode, I_MUTEX_PARENT);
|
||||
|
||||
/*
|
||||
* In order to add new element or remove elements from the list
|
||||
|
Loading…
Reference in New Issue
Block a user