dcache: close d_move race in d_splice_alias
d_splice_alias will d_move an IS_ROOT() directory dentry into place if one exists. This should be safe as long as the dentry remains IS_ROOT, but I can't see what guarantees that: once we drop the i_lock all we hold here is the i_mutex on an unrelated parent directory. Instead copy the logic of d_materialise_unique. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
3f70bd51cb
commit
75a2352d01
|
@ -2676,9 +2676,14 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
|
|||
new = __d_find_alias(inode, 1);
|
||||
if (new) {
|
||||
BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
|
||||
write_seqlock(&rename_lock);
|
||||
__d_materialise_dentry(dentry, new);
|
||||
write_sequnlock(&rename_lock);
|
||||
__d_drop(new);
|
||||
_d_rehash(new);
|
||||
spin_unlock(&new->d_lock);
|
||||
spin_unlock(&inode->i_lock);
|
||||
security_d_instantiate(new, inode);
|
||||
d_move(new, dentry);
|
||||
iput(inode);
|
||||
} else {
|
||||
/* already taking inode->i_lock, so d_add() by hand */
|
||||
|
|
Loading…
Reference in New Issue