diff mbox series

[08/11] nfsd: change get_parent_attributes() to nfsd_get_mounted_on()

Message ID 162742546555.32498.13169105043649293291.stgit@noble.brown (mailing list archive)
State New, archived
Headers show
Series expose btrfs subvols in mount table correctly | expand

Commit Message

NeilBrown July 27, 2021, 10:37 p.m. UTC
get_parent_attributes() is only used to get the inode number of the
mounted-on directory.  So change it to only do that and call it
nfsd_get_mounted_on().

It will eventually be use by nfs3 as well as nfs4, so move it to vfs.c.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 fs/nfsd/nfs4xdr.c |   29 +++++------------------------
 fs/nfsd/vfs.c     |   18 ++++++++++++++++++
 fs/nfsd/vfs.h     |    2 ++
 3 files changed, 25 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 21c277fa28ae..d5683b6a74b2 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2768,22 +2768,6 @@  static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32
 	return 0;
 }
 
-
-static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
-{
-	struct path path = exp->ex_path;
-	int err;
-
-	path_get(&path);
-	while (follow_up(&path)) {
-		if (path.dentry != path.mnt->mnt_root)
-			break;
-	}
-	err = vfs_getattr(&path, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
-	path_put(&path);
-	return err;
-}
-
 static __be32
 nfsd4_encode_bitmap(struct xdr_stream *xdr, u32 bmval0, u32 bmval1, u32 bmval2)
 {
@@ -3269,8 +3253,7 @@  nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
 		*p++ = cpu_to_be32(stat.mtime.tv_nsec);
 	}
 	if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
-		struct kstat parent_stat;
-		u64 ino = stat.ino;
+		u64 ino;
 
 		p = xdr_reserve_space(xdr, 8);
 		if (!p)
@@ -3279,12 +3262,10 @@  nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
 		 * Get parent's attributes if not ignoring crossmount
 		 * and this is the root of a cross-mounted filesystem.
 		 */
-		if (ignore_crossmnt == 0 && dentry == mnt->mnt_root) {
-			err = get_parent_attributes(exp, &parent_stat);
-			if (err)
-				goto out_nfserr;
-			ino = parent_stat.ino;
-		}
+		if (ignore_crossmnt == 0 && dentry == mnt->mnt_root)
+			ino = nfsd_get_mounted_on(mnt);
+		if (!ino)
+			ino = stat.ino;
 		p = xdr_encode_hyper(p, ino);
 	}
 #ifdef CONFIG_NFSD_PNFS
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c0c6920f25a4..baa12ac36ece 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -2445,3 +2445,21 @@  nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
 
 	return err? nfserrno(err) : 0;
 }
+
+unsigned long nfsd_get_mounted_on(struct vfsmount *mnt)
+{
+	struct kstat stat;
+	struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
+	int err;
+
+	path_get(&path);
+	while (follow_up(&path)) {
+		if (path.dentry != path.mnt->mnt_root)
+			break;
+	}
+	err = vfs_getattr(&path, &stat, STATX_INO, AT_STATX_DONT_SYNC);
+	path_put(&path);
+	if (err)
+		return 0;
+	return stat.ino;
+}
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 52f587716208..11ac36b21b4c 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -132,6 +132,8 @@  __be32		nfsd_statfs(struct svc_rqst *, struct svc_fh *,
 __be32		nfsd_permission(struct svc_rqst *, struct svc_export *,
 				struct dentry *, int);
 
+unsigned long	nfsd_get_mounted_on(struct vfsmount *mnt);
+
 static inline int fh_want_write(struct svc_fh *fh)
 {
 	int ret;