--- /dev/null
+From: Tony Jones <tonyj@suse.de>
+Subject: Add a struct vfsmount parameter to vfs_rmdir()
+
+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 | 4 +++-
+ fs/namei.c | 4 ++--
+ fs/nfsd/nfs4recover.c | 2 +-
+ fs/nfsd/vfs.c | 8 +++++---
+ include/linux/fs.h | 2 +-
+ 5 files changed, 12 insertions(+), 8 deletions(-)
+
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -534,14 +534,16 @@ out:
+ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
+ {
+ struct dentry *lower_dentry;
++ struct vfsmount *lower_mnt;
+ struct dentry *lower_dir_dentry;
+ int rc;
+
+ lower_dentry = ecryptfs_dentry_to_lower(dentry);
++ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ dget(dentry);
+ lower_dir_dentry = lock_parent(lower_dentry);
+ dget(lower_dentry);
+- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
++ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt);
+ dput(lower_dentry);
+ if (!rc)
+ d_delete(lower_dentry);
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -2167,7 +2167,7 @@ void dentry_unhash(struct dentry *dentry
+ spin_unlock(&dcache_lock);
+ }
+
+-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
++int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt)
+ {
+ int error = may_delete(dir, dentry, 1);
+
+@@ -2230,7 +2230,7 @@ static long do_rmdir(int dfd, const char
+ error = mnt_want_write(nd.path.mnt);
+ if (error)
+ goto exit3;
+- error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
++ error = vfs_rmdir(nd.path.dentry->d_inode, dentry, nd.path.mnt);
+ mnt_drop_write(nd.path.mnt);
+ exit3:
+ dput(dentry);
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -279,7 +279,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
+ * a kernel from the future.... */
+ nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
+- status = vfs_rmdir(dir->d_inode, dentry);
++ status = vfs_rmdir(dir->d_inode, dentry, rec_dir.path.mnt);
+ mutex_unlock(&dir->d_inode->i_mutex);
+ return status;
+ }
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1790,6 +1790,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ char *fname, int flen)
+ {
+ struct dentry *dentry, *rdentry;
++ struct svc_export *exp;
+ struct inode *dirp;
+ __be32 err;
+ int host_err;
+@@ -1804,6 +1805,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ fh_lock_nested(fhp, I_MUTEX_PARENT);
+ dentry = fhp->fh_dentry;
+ dirp = dentry->d_inode;
++ exp = fhp->fh_export;
+
+ rdentry = lookup_one_len(fname, dentry, flen);
+ host_err = PTR_ERR(rdentry);
+@@ -1825,21 +1827,21 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+
+ if (type != S_IFDIR) { /* It's UNLINK */
+ #ifdef MSNFS
+- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
++ if ((exp->ex_flags & NFSEXP_MSNFS) &&
+ (atomic_read(&rdentry->d_count) > 1)) {
+ host_err = -EPERM;
+ } else
+ #endif
+ host_err = vfs_unlink(dirp, rdentry);
+ } else { /* It's RMDIR */
+- host_err = vfs_rmdir(dirp, rdentry);
++ host_err = vfs_rmdir(dirp, rdentry, exp->ex_path.mnt);
+ }
+
+ dput(rdentry);
+
+ if (host_err)
+ goto out_drop;
+- if (EX_ISSYNC(fhp->fh_export))
++ if (EX_ISSYNC(exp))
+ host_err = nfsd_sync_dir(dentry);
+
+ out_drop:
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1182,7 +1182,7 @@ extern int vfs_mkdir(struct inode *, str
+ extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t);
+ extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *);
+ extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
+-extern int vfs_rmdir(struct inode *, struct dentry *);
++extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *);
+ extern int vfs_unlink(struct inode *, struct dentry *);
+ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
+