+From: Tony Jones <tonyj@suse.de>
+Subject: Add struct vfsmount parameters to vfs_rename()
+
+The vfsmount will be passed down to the LSM hook so that LSMs can compute
+pathnames.
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+Signed-off-by: John Johansen <jjohansen@suse.de>
+
+---
+ fs/ecryptfs/inode.c | 7 ++++++-
+ fs/namei.c | 19 ++++++++++++-------
+ fs/nfsd/vfs.c | 3 ++-
+ include/linux/fs.h | 2 +-
+ 4 files changed, 21 insertions(+), 10 deletions(-)
+
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -590,19 +590,24 @@ ecryptfs_rename(struct inode *old_dir, s
+ {
+ int rc;
+ struct dentry *lower_old_dentry;
++ struct vfsmount *lower_old_mnt;
+ struct dentry *lower_new_dentry;
++ struct vfsmount *lower_new_mnt;
+ struct dentry *lower_old_dir_dentry;
+ struct dentry *lower_new_dir_dentry;
+
+ lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
++ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
+ lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
++ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
+ dget(lower_old_dentry);
+ dget(lower_new_dentry);
+ lower_old_dir_dentry = dget_parent(lower_old_dentry);
+ lower_new_dir_dentry = dget_parent(lower_new_dentry);
+ lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+ rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
+- lower_new_dir_dentry->d_inode, lower_new_dentry);
++ lower_old_mnt, lower_new_dir_dentry->d_inode,
++ lower_new_dentry, lower_new_mnt);
+ if (rc)
+ goto out_lock;
+ fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -2547,7 +2547,8 @@ SYSCALL_DEFINE2(link, const char __user
+ * locking].
+ */
+ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
+- struct inode *new_dir, struct dentry *new_dentry)
++ struct vfsmount *old_mnt, struct inode *new_dir,
++ struct dentry *new_dentry, struct vfsmount *new_mnt)
+ {
+ int error = 0;
+ struct inode *target;
+@@ -2590,7 +2591,8 @@ static int vfs_rename_dir(struct inode *
+ }
+
+ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
+- struct inode *new_dir, struct dentry *new_dentry)
++ struct vfsmount *old_mnt, struct inode *new_dir,
++ struct dentry *new_dentry, struct vfsmount *new_mnt)
+ {
+ struct inode *target;
+ int error;
+@@ -2618,7 +2620,8 @@ static int vfs_rename_other(struct inode
+ }
+
+ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+- struct inode *new_dir, struct dentry *new_dentry)
++ struct vfsmount *old_mnt, struct inode *new_dir,
++ struct dentry *new_dentry, struct vfsmount *new_mnt)
+ {
+ int error;
+ int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
+@@ -2647,9 +2650,11 @@ int vfs_rename(struct inode *old_dir, st
+ old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+
+ if (is_dir)
+- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
++ error = vfs_rename_dir(old_dir, old_dentry, old_mnt,
++ new_dir, new_dentry, new_mnt);
+ else
+- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
++ error = vfs_rename_other(old_dir, old_dentry, old_mnt,
++ new_dir, new_dentry, new_mnt);
+ if (!error) {
+ const char *new_name = old_dentry->d_name.name;
+ fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
+@@ -2726,8 +2731,8 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
+ error = mnt_want_write(oldnd.path.mnt);
+ if (error)
+ goto exit5;
+- error = vfs_rename(old_dir->d_inode, old_dentry,
+- new_dir->d_inode, new_dentry);
++ error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.path.mnt,
++ new_dir->d_inode, new_dentry, newnd.path.mnt);
+ mnt_drop_write(oldnd.path.mnt);
+ exit5:
+ dput(new_dentry);
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1752,7 +1752,8 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ if (host_err)
+ goto out_dput_new;
+
+- host_err = vfs_rename(fdir, odentry, tdir, ndentry);
++ host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_path.mnt,
++ tdir, ndentry, tfhp->fh_export->ex_path.mnt);
+ if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
+ host_err = nfsd_sync_dir(tdentry);
+ if (!host_err)
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1184,7 +1184,7 @@ extern int vfs_symlink(struct inode *, s
+ extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
+ extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *);
+ extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *);
+-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
++extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
+
+ /*
+ * VFS dentry helper functions.