From: Jeff Mahoney <jeffm@suse.com>
Subject: xfs/dmapi: Remove cached vfsmount
References: bnc#749417
Patch-mainline: Depends on DMAPI

 Previous version of xfs/dmapi were able to cache a vfsmount pointer on
 mount in order to perform lookups. In recent Linux versions, the vfsmount
 pointer is not passed to the mount callbacks anymore.

 For SLE11 SP2 GA, we added
 patches.suse/xfs-dmapi-obtain-vfsmount-for-use-in-xfs_dm_rdwr to cache
 a vfsmount pointer opportunistically when it was needed. This is buggy.

 The spinlock protecting the test-and-set was never initialized. Also,
 if the XFS file system is mounted on multiple mount points and the mount
 point referenced by the cached vfsmount goes away, we'll have a stale
 pointer and will Oops.

 The xfs_mount_t->m_vfsmount{,_lock} members are no longer used but
 removing them would alter the kABI.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 fs/xfs/dmapi/xfs_dm.c |   24 ++++++------------------
 fs/xfs/xfs_mount.h    |    4 ++--
 2 files changed, 8 insertions(+), 20 deletions(-)

--- a/fs/xfs/dmapi/xfs_dm.c
+++ b/fs/xfs/dmapi/xfs_dm.c
@@ -892,26 +892,13 @@ xfs_dm_rdwr(
 		return ENOMEM;
 	}
 
-	/*
-	 * Ugh. This is not ideal, but we can't even keep a private vfsmount
-	 * for this. We'd run into problems with freeing the superblock as
-	 * well as AppArmor refusing access due to the pathnames not matching.
-	 */
-	if (!mp->m_vfsmount) {
-		error = kern_path(mp->m_mtpt, 0, &path);
-		if (error)
-			return -error;
-
-		spin_lock(&mp->m_vfsmount_lock);
-		if (!mp->m_vfsmount)
-			mp->m_vfsmount = path.mnt;
-		spin_unlock(&mp->m_vfsmount_lock);
-		path_put(&path);
-	}
+	error = kern_path(mp->m_mtpt, 0, &path);
+	if (error)
+		return -error;
 
-	file = dentry_open(dentry, mntget(ip->i_mount->m_vfsmount), oflags,
-			   cred);
+	file = dentry_open(dentry, mntget(path.mnt), oflags, cred);
 	if (IS_ERR(file)) {
+		path_put(&path);
 		return -PTR_ERR(file);
 	}
 	file->f_mode |= FMODE_NOCMTIME;
@@ -931,6 +918,7 @@ xfs_dm_rdwr(
 	}
 
 	fput(file);
+	path_put(&path);
 	return error;
 }
 
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -214,8 +214,8 @@ typedef struct xfs_mount {
 	struct shrinker		m_inode_shrink;	/* inode reclaim shrinker */
 	int64_t			m_low_space[XFS_LOWSP_MAX];
 						/* low free space thresholds */
-	struct vfsmount         *m_vfsmount;
-	spinlock_t		m_vfsmount_lock;
+	struct vfsmount         *m_vfsmount;	/* Unused */
+	spinlock_t		m_vfsmount_lock;	/* Unused */
 	const char		*m_mtpt;
 } xfs_mount_t;
 

