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
|
* remove_binfmt_handler - remove a binary type handler
|
||||||
* @misc: handle to binfmt_misc instance
|
* @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);
|
write_lock(&misc->entries_lock);
|
||||||
list_del_init(&e->list);
|
list_del_init(&e->list);
|
||||||
write_unlock(&misc->entries_lock);
|
write_unlock(&misc->entries_lock);
|
||||||
unlink_binfmt_dentry(e->dentry);
|
locked_recursive_removal(e->dentry, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /<entry> */
|
/* /<entry> */
|
||||||
@ -772,7 +734,7 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
|
|||||||
case 3:
|
case 3:
|
||||||
/* Delete this handler. */
|
/* Delete this handler. */
|
||||||
inode = d_inode(inode->i_sb->s_root);
|
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
|
* 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:
|
case 3:
|
||||||
/* Delete all handlers. */
|
/* Delete all handlers. */
|
||||||
inode = d_inode(file_inode(file)->i_sb->s_root);
|
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
|
* In order to add new element or remove elements from the list
|
||||||
|
Loading…
Reference in New Issue
Block a user