diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-08 15:59:33 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-14 16:35:15 +0400 |
commit | ee3efa91e240f513898050ef305a49a653c8ed90 (patch) | |
tree | d6cf061b3636f3c5f9840c09f3ed6ccd625cff22 /fs/dcache.c | |
parent | e77fb7cef87856d9d35f2f4d617d0b97148ee7c2 (diff) | |
download | lwn-ee3efa91e240f513898050ef305a49a653c8ed90.tar.gz lwn-ee3efa91e240f513898050ef305a49a653c8ed90.zip |
__d_unalias() should refuse to move mountpoints
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 015586f1ffc6..8086636bf796 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2387,14 +2387,13 @@ static struct dentry *__d_unalias(struct inode *inode, struct dentry *dentry, struct dentry *alias) { struct mutex *m1 = NULL, *m2 = NULL; - struct dentry *ret; + struct dentry *ret = ERR_PTR(-EBUSY); /* If alias and dentry share a parent, then no extra locks required */ if (alias->d_parent == dentry->d_parent) goto out_unalias; /* See lock_rename() */ - ret = ERR_PTR(-EBUSY); if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) goto out_err; m1 = &dentry->d_sb->s_vfs_rename_mutex; @@ -2402,8 +2401,10 @@ static struct dentry *__d_unalias(struct inode *inode, goto out_err; m2 = &alias->d_parent->d_inode->i_mutex; out_unalias: - __d_move(alias, dentry); - ret = alias; + if (likely(!d_mountpoint(alias))) { + __d_move(alias, dentry); + ret = alias; + } out_err: spin_unlock(&inode->i_lock); if (m2) |