[Devel,RHEL7,COMMIT] ms/vfs: rename: check backing inode being equal

Submitted by Konstantin Khorenko on Aug. 9, 2016, 8:17 a.m.

Details

Message ID 201608090817.u798HHsj015286@finist_cl7.x64_64.work.ct
State New
Series "overlayfs: missing detection of hardlinks in vfs_rename() on overlayfs"
Headers show

Commit Message

Konstantin Khorenko Aug. 9, 2016, 8:17 a.m.
The commit is pushed to "branch-rh7-3.10.0-327.22.2.vz7.16.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.22.2.vz7.16.3
------>
commit 2cd01952a8433533f4d898c37c2370513348302e
Author: Maxim Patlasov <mpatlasov@virtuozzo.com>
Date:   Tue Aug 9 12:17:17 2016 +0400

    ms/vfs: rename: check backing inode being equal
    
    The patch backports upstream commit 9409e22acdfc9153f88d9b1ed2bd2a5b34d2d3ca:
    
    > vfs: rename: check backing inode being equal
    >
    > If a file is renamed to a hardlink of itself POSIX specifies that rename(2)
    > should do nothing and return success.
    >
    > This condition is checked in vfs_rename().  However it won't detect hard
    > links on overlayfs where these are given separate inodes on the overlayfs
    > layer.
    >
    > Overlayfs itself detects this condition and returns success without doing
    > anything, but then vfs_rename() will proceed as if this was a successful
    > rename (detach_mounts(), d_move()).
    >
    > The correct thing to do is to detect this condition before even calling
    > into overlayfs.  This patch does this by calling vfs_select_inode() to get
    > the underlying inodes.
    >
    > Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
    
    https://jira.sw.ru/browse/PSBM-47981
    
    Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com>
---
 fs/namei.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/fs/namei.c b/fs/namei.c
index 16820b1..427c740 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4103,7 +4103,11 @@  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	unsigned max_links = new_dir->i_sb->s_max_links;
 	iop_rename2_t rename2;
 
-	if (source == target)
+	/*
+	 * Check source == target.
+	 * On overlayfs need to look at underlying inodes.
+	 */
+	if (vfs_select_inode(old_dentry) == vfs_select_inode(new_dentry))
 		return 0;
 
 	error = may_delete(old_dir, old_dentry, is_dir);