Skip to content

Commit eacb58f

Browse files
author
Al Viro
committed
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>
1 parent 8c0e092 commit eacb58f

File tree

1 file changed

+3
-41
lines changed

1 file changed

+3
-41
lines changed

fs/binfmt_misc.c

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -674,44 +674,6 @@ static void bm_evict_inode(struct inode *inode)
674674
}
675675
}
676676

677-
/**
678-
* unlink_binfmt_dentry - remove the dentry for the binary type handler
679-
* @dentry: dentry associated with the binary type handler
680-
*
681-
* Do the actual filesystem work to remove a dentry for a registered binary
682-
* type handler. Since binfmt_misc only allows simple files to be created
683-
* directly under the root dentry of the filesystem we ensure that we are
684-
* indeed passed a dentry directly beneath the root dentry, that the inode
685-
* associated with the root dentry is locked, and that it is a regular file we
686-
* are asked to remove.
687-
*/
688-
static void unlink_binfmt_dentry(struct dentry *dentry)
689-
{
690-
struct dentry *parent = dentry->d_parent;
691-
struct inode *inode, *parent_inode;
692-
693-
/* All entries are immediate descendants of the root dentry. */
694-
if (WARN_ON_ONCE(dentry->d_sb->s_root != parent))
695-
return;
696-
697-
/* We only expect to be called on regular files. */
698-
inode = d_inode(dentry);
699-
if (WARN_ON_ONCE(!S_ISREG(inode->i_mode)))
700-
return;
701-
702-
/* The parent inode must be locked. */
703-
parent_inode = d_inode(parent);
704-
if (WARN_ON_ONCE(!inode_is_locked(parent_inode)))
705-
return;
706-
707-
if (simple_positive(dentry)) {
708-
dget(dentry);
709-
simple_unlink(parent_inode, dentry);
710-
d_delete(dentry);
711-
dput(dentry);
712-
}
713-
}
714-
715677
/**
716678
* remove_binfmt_handler - remove a binary type handler
717679
* @misc: handle to binfmt_misc instance
@@ -729,7 +691,7 @@ static void remove_binfmt_handler(struct binfmt_misc *misc, Node *e)
729691
write_lock(&misc->entries_lock);
730692
list_del_init(&e->list);
731693
write_unlock(&misc->entries_lock);
732-
unlink_binfmt_dentry(e->dentry);
694+
locked_recursive_removal(e->dentry, NULL);
733695
}
734696

735697
/* /<entry> */
@@ -772,7 +734,7 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
772734
case 3:
773735
/* Delete this handler. */
774736
inode = d_inode(inode->i_sb->s_root);
775-
inode_lock(inode);
737+
inode_lock_nested(inode, I_MUTEX_PARENT);
776738

777739
/*
778740
* 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,
922884
case 3:
923885
/* Delete all handlers. */
924886
inode = d_inode(file_inode(file)->i_sb->s_root);
925-
inode_lock(inode);
887+
inode_lock_nested(inode, I_MUTEX_PARENT);
926888

927889
/*
928890
* In order to add new element or remove elements from the list

0 commit comments

Comments
 (0)