All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points.
  2021-07-27 22:37 [PATCH/RFC 00/11] expose btrfs subvols in mount table correctly NeilBrown
@ 2021-07-27 22:37 ` NeilBrown
  2021-07-28 19:15   ` J. Bruce Fields
  2021-07-30  0:42   ` Al Viro
  0 siblings, 2 replies; 6+ messages in thread
From: NeilBrown @ 2021-07-27 22:37 UTC (permalink / raw
  To: Christoph Hellwig, Josef Bacik, J. Bruce Fields, Chuck Lever,
	Chris Mason, David Sterba, Alexander Viro
  Cc: linux-fsdevel, linux-nfs, linux-btrfs

Enhance nfsd to detect internal mounts and to cross them without
requiring a new export.

Also ensure the fsid reported is different for different submounts.  We
do this by xoring in the ino of the mounted-on directory.  This makes
sense for btrfs at least.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 fs/nfsd/nfs3xdr.c |   28 +++++++++++++++++++++-------
 fs/nfsd/nfs4xdr.c |   34 +++++++++++++++++++++++-----------
 fs/nfsd/nfsfh.c   |    7 ++++++-
 fs/nfsd/vfs.c     |   11 +++++++++--
 4 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 67af0c5c1543..80b1cc0334fa 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -370,6 +370,8 @@ svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
 	case FSIDSOURCE_UUID:
 		fsid = ((u64 *)fhp->fh_export->ex_uuid)[0];
 		fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1];
+		if (fhp->fh_mnt != fhp->fh_export->ex_path.mnt)
+			fsid ^= nfsd_get_mounted_on(fhp->fh_mnt);
 		break;
 	default:
 		fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev);
@@ -1094,8 +1096,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
 	__be32 rv = nfserr_noent;
 
 	dparent = cd->fh.fh_dentry;
-	exp  = cd->fh.fh_export;
-	child.mnt = cd->fh.fh_mnt;
+	exp  = exp_get(cd->fh.fh_export);
+	child.mnt = mntget(cd->fh.fh_mnt);
 
 	if (isdotent(name, namlen)) {
 		if (namlen == 2) {
@@ -1112,15 +1114,27 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
 			child.dentry = dget(dparent);
 	} else
 		child.dentry = lookup_positive_unlocked(name, dparent, namlen);
-	if (IS_ERR(child.dentry))
+	if (IS_ERR(child.dentry)) {
+		mntput(child.mnt);
+		exp_put(exp);
 		return rv;
-	if (d_mountpoint(child.dentry))
-		goto out;
-	if (child.dentry->d_inode->i_ino != ino)
+	}
+	/* If child is a mountpoint, then we want to expose the fact
+	 * so client can create a mountpoint.  If not, then a different
+	 * ino number probably means a race with rename, so avoid providing
+	 * too much detail.
+	 */
+	if (nfsd_mountpoint(child.dentry, exp)) {
+		int err;
+		err = nfsd_cross_mnt(cd->rqstp, &child, &exp);
+		if (err)
+			goto out;
+	} else if (child.dentry->d_inode->i_ino != ino)
 		goto out;
 	rv = fh_compose(fhp, exp, &child, &cd->fh);
 out:
-	dput(child.dentry);
+	path_put(&child);
+	exp_put(exp);
 	return rv;
 }
 
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index d5683b6a74b2..4dbc99ed2c8b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2817,6 +2817,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
 	struct kstat stat;
 	struct svc_fh *tempfh = NULL;
 	struct kstatfs statfs;
+	u64 mounted_on_ino;
+	u64 sub_fsid;
 	__be32 *p;
 	int starting_len = xdr->buf->len;
 	int attrlen_offset;
@@ -2871,6 +2873,24 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
 			goto out;
 		fhp = tempfh;
 	}
+	if ((bmval0 & FATTR4_WORD0_FSID) ||
+	    (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
+		mounted_on_ino = stat.ino;
+		sub_fsid = 0;
+		/*
+		 * The inode number that the current mnt is mounted on is
+		 * used for MOUNTED_ON_FILED if we are at the root,
+		 * and for sub_fsid if mnt is not the export mnt.
+		 */
+		if (ignore_crossmnt == 0) {
+			u64 moi = nfsd_get_mounted_on(mnt);
+
+			if (dentry == mnt->mnt_root && moi)
+				mounted_on_ino = moi;
+			if (mnt != exp->ex_path.mnt)
+				sub_fsid = moi;
+		}
+	}
 	if (bmval0 & FATTR4_WORD0_ACL) {
 		err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
 		if (err == -EOPNOTSUPP)
@@ -3008,6 +3028,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
 		case FSIDSOURCE_UUID:
 			p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
 								EX_UUID_LEN);
+			if (mnt != exp->ex_path.mnt)
+				*(u64*)(p-2) ^= sub_fsid;
 			break;
 		}
 	}
@@ -3253,20 +3275,10 @@ 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) {
-		u64 ino;
-
 		p = xdr_reserve_space(xdr, 8);
 		if (!p)
 			goto out_resource;
-		/*
-		 * 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)
-			ino = nfsd_get_mounted_on(mnt);
-		if (!ino)
-			ino = stat.ino;
-		p = xdr_encode_hyper(p, ino);
+		p = xdr_encode_hyper(p, mounted_on_ino);
 	}
 #ifdef CONFIG_NFSD_PNFS
 	if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 4023046f63e2..4b53838bca89 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -9,7 +9,7 @@
  */
 
 #include <linux/exportfs.h>
-
+#include <linux/namei.h>
 #include <linux/sunrpc/svcauth_gss.h>
 #include "nfsd.h"
 #include "vfs.h"
@@ -285,6 +285,11 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
 			default:
 				dentry = ERR_PTR(-ESTALE);
 			}
+		} else if (nfsd_mountpoint(dentry, exp)) {
+			struct path path = { .mnt = mnt, .dentry = dentry };
+			follow_down(&path, LOOKUP_AUTOMOUNT);
+			mnt = path.mnt;
+			dentry = path.dentry;
 		}
 	}
 	if (dentry == NULL)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index baa12ac36ece..22523e1cd478 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -64,7 +64,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
 			    .dentry = dget(path_parent->dentry)};
 	int err = 0;
 
-	err = follow_down(&path, 0);
+	err = follow_down(&path, LOOKUP_AUTOMOUNT);
 	if (err < 0)
 		goto out;
 	if (path.mnt == path_parent->mnt && path.dentry == path_parent->dentry &&
@@ -73,6 +73,13 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
 		path_put(&path);
 		goto out;
 	}
+	if (mount_is_internal(path.mnt)) {
+		/* Use the new path, but don't look for a new export */
+		/* FIXME should I check NOHIDE in this case?? */
+		path_put(path_parent);
+		*path_parent = path;
+		goto out;
+	}
 
 	exp2 = rqst_exp_get_by_name(rqstp, &path);
 	if (IS_ERR(exp2)) {
@@ -157,7 +164,7 @@ int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
 		return 1;
 	if (nfsd4_is_junction(dentry))
 		return 1;
-	if (d_mountpoint(dentry))
+	if (d_managed(dentry))
 		/*
 		 * Might only be a mountpoint in a different namespace,
 		 * but we need to check.



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points.
  2021-07-27 22:37 ` [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points NeilBrown
@ 2021-07-28 19:15   ` J. Bruce Fields
  2021-07-28 22:29     ` NeilBrown
  2021-07-30  0:42   ` Al Viro
  1 sibling, 1 reply; 6+ messages in thread
From: J. Bruce Fields @ 2021-07-28 19:15 UTC (permalink / raw
  To: NeilBrown
  Cc: Christoph Hellwig, Josef Bacik, Chuck Lever, Chris Mason,
	David Sterba, Alexander Viro, linux-fsdevel, linux-nfs,
	linux-btrfs

On Wed, Jul 28, 2021 at 08:37:45AM +1000, NeilBrown wrote:
> Enhance nfsd to detect internal mounts and to cross them without
> requiring a new export.

Why don't we want a new export?

(Honest question, it's not obvious to me what the best behavior is.)

--b.

> 
> Also ensure the fsid reported is different for different submounts.  We
> do this by xoring in the ino of the mounted-on directory.  This makes
> sense for btrfs at least.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
>  fs/nfsd/nfs3xdr.c |   28 +++++++++++++++++++++-------
>  fs/nfsd/nfs4xdr.c |   34 +++++++++++++++++++++++-----------
>  fs/nfsd/nfsfh.c   |    7 ++++++-
>  fs/nfsd/vfs.c     |   11 +++++++++--
>  4 files changed, 59 insertions(+), 21 deletions(-)
> 
> diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
> index 67af0c5c1543..80b1cc0334fa 100644
> --- a/fs/nfsd/nfs3xdr.c
> +++ b/fs/nfsd/nfs3xdr.c
> @@ -370,6 +370,8 @@ svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
>  	case FSIDSOURCE_UUID:
>  		fsid = ((u64 *)fhp->fh_export->ex_uuid)[0];
>  		fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1];
> +		if (fhp->fh_mnt != fhp->fh_export->ex_path.mnt)
> +			fsid ^= nfsd_get_mounted_on(fhp->fh_mnt);
>  		break;
>  	default:
>  		fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev);
> @@ -1094,8 +1096,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
>  	__be32 rv = nfserr_noent;
>  
>  	dparent = cd->fh.fh_dentry;
> -	exp  = cd->fh.fh_export;
> -	child.mnt = cd->fh.fh_mnt;
> +	exp  = exp_get(cd->fh.fh_export);
> +	child.mnt = mntget(cd->fh.fh_mnt);
>  
>  	if (isdotent(name, namlen)) {
>  		if (namlen == 2) {
> @@ -1112,15 +1114,27 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
>  			child.dentry = dget(dparent);
>  	} else
>  		child.dentry = lookup_positive_unlocked(name, dparent, namlen);
> -	if (IS_ERR(child.dentry))
> +	if (IS_ERR(child.dentry)) {
> +		mntput(child.mnt);
> +		exp_put(exp);
>  		return rv;
> -	if (d_mountpoint(child.dentry))
> -		goto out;
> -	if (child.dentry->d_inode->i_ino != ino)
> +	}
> +	/* If child is a mountpoint, then we want to expose the fact
> +	 * so client can create a mountpoint.  If not, then a different
> +	 * ino number probably means a race with rename, so avoid providing
> +	 * too much detail.
> +	 */
> +	if (nfsd_mountpoint(child.dentry, exp)) {
> +		int err;
> +		err = nfsd_cross_mnt(cd->rqstp, &child, &exp);
> +		if (err)
> +			goto out;
> +	} else if (child.dentry->d_inode->i_ino != ino)
>  		goto out;
>  	rv = fh_compose(fhp, exp, &child, &cd->fh);
>  out:
> -	dput(child.dentry);
> +	path_put(&child);
> +	exp_put(exp);
>  	return rv;
>  }
>  
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index d5683b6a74b2..4dbc99ed2c8b 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -2817,6 +2817,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
>  	struct kstat stat;
>  	struct svc_fh *tempfh = NULL;
>  	struct kstatfs statfs;
> +	u64 mounted_on_ino;
> +	u64 sub_fsid;
>  	__be32 *p;
>  	int starting_len = xdr->buf->len;
>  	int attrlen_offset;
> @@ -2871,6 +2873,24 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
>  			goto out;
>  		fhp = tempfh;
>  	}
> +	if ((bmval0 & FATTR4_WORD0_FSID) ||
> +	    (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
> +		mounted_on_ino = stat.ino;
> +		sub_fsid = 0;
> +		/*
> +		 * The inode number that the current mnt is mounted on is
> +		 * used for MOUNTED_ON_FILED if we are at the root,
> +		 * and for sub_fsid if mnt is not the export mnt.
> +		 */
> +		if (ignore_crossmnt == 0) {
> +			u64 moi = nfsd_get_mounted_on(mnt);
> +
> +			if (dentry == mnt->mnt_root && moi)
> +				mounted_on_ino = moi;
> +			if (mnt != exp->ex_path.mnt)
> +				sub_fsid = moi;
> +		}
> +	}
>  	if (bmval0 & FATTR4_WORD0_ACL) {
>  		err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
>  		if (err == -EOPNOTSUPP)
> @@ -3008,6 +3028,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
>  		case FSIDSOURCE_UUID:
>  			p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
>  								EX_UUID_LEN);
> +			if (mnt != exp->ex_path.mnt)
> +				*(u64*)(p-2) ^= sub_fsid;
>  			break;
>  		}
>  	}
> @@ -3253,20 +3275,10 @@ 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) {
> -		u64 ino;
> -
>  		p = xdr_reserve_space(xdr, 8);
>  		if (!p)
>  			goto out_resource;
> -		/*
> -		 * 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)
> -			ino = nfsd_get_mounted_on(mnt);
> -		if (!ino)
> -			ino = stat.ino;
> -		p = xdr_encode_hyper(p, ino);
> +		p = xdr_encode_hyper(p, mounted_on_ino);
>  	}
>  #ifdef CONFIG_NFSD_PNFS
>  	if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
> diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
> index 4023046f63e2..4b53838bca89 100644
> --- a/fs/nfsd/nfsfh.c
> +++ b/fs/nfsd/nfsfh.c
> @@ -9,7 +9,7 @@
>   */
>  
>  #include <linux/exportfs.h>
> -
> +#include <linux/namei.h>
>  #include <linux/sunrpc/svcauth_gss.h>
>  #include "nfsd.h"
>  #include "vfs.h"
> @@ -285,6 +285,11 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
>  			default:
>  				dentry = ERR_PTR(-ESTALE);
>  			}
> +		} else if (nfsd_mountpoint(dentry, exp)) {
> +			struct path path = { .mnt = mnt, .dentry = dentry };
> +			follow_down(&path, LOOKUP_AUTOMOUNT);
> +			mnt = path.mnt;
> +			dentry = path.dentry;
>  		}
>  	}
>  	if (dentry == NULL)
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index baa12ac36ece..22523e1cd478 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -64,7 +64,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
>  			    .dentry = dget(path_parent->dentry)};
>  	int err = 0;
>  
> -	err = follow_down(&path, 0);
> +	err = follow_down(&path, LOOKUP_AUTOMOUNT);
>  	if (err < 0)
>  		goto out;
>  	if (path.mnt == path_parent->mnt && path.dentry == path_parent->dentry &&
> @@ -73,6 +73,13 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
>  		path_put(&path);
>  		goto out;
>  	}
> +	if (mount_is_internal(path.mnt)) {
> +		/* Use the new path, but don't look for a new export */
> +		/* FIXME should I check NOHIDE in this case?? */
> +		path_put(path_parent);
> +		*path_parent = path;
> +		goto out;
> +	}
>  
>  	exp2 = rqst_exp_get_by_name(rqstp, &path);
>  	if (IS_ERR(exp2)) {
> @@ -157,7 +164,7 @@ int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
>  		return 1;
>  	if (nfsd4_is_junction(dentry))
>  		return 1;
> -	if (d_mountpoint(dentry))
> +	if (d_managed(dentry))
>  		/*
>  		 * Might only be a mountpoint in a different namespace,
>  		 * but we need to check.
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points.
@ 2021-07-28 22:12 kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-07-28 22:12 UTC (permalink / raw
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 33761 bytes --]

CC: kbuild-all(a)lists.01.org
In-Reply-To: <162742546556.32498.16708762469227881912.stgit@noble.brown>
References: <162742546556.32498.16708762469227881912.stgit@noble.brown>
TO: NeilBrown <neilb@suse.de>
TO: Christoph Hellwig <hch@infradead.org>
TO: Josef Bacik <josef@toxicpanda.com>
TO: "J. Bruce Fields" <bfields@fieldses.org>
TO: Chuck Lever <chuck.lever@oracle.com>
TO: Chris Mason <chris.mason@fusionio.com>
TO: David Sterba <dsterba@suse.com>
TO: Alexander Viro <viro@zeniv.linux.org.uk>
CC: linux-fsdevel(a)vger.kernel.org
CC: linux-nfs(a)vger.kernel.org
CC: linux-btrfs(a)vger.kernel.org

Hi NeilBrown,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on nfsd/nfsd-next]
[also build test WARNING on kdave/for-next hch-configfs/for-next linus/master v5.14-rc3 next-20210727]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/NeilBrown/expose-btrfs-subvols-in-mount-table-correctly/20210728-064502
base:   git://linux-nfs.org/~bfields/linux.git nfsd-next
:::::: branch date: 23 hours ago
:::::: commit date: 23 hours ago
config: mips-randconfig-m031-20210728 (attached as .config)
compiler: mips-linux-gcc (GCC) 10.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
fs/nfsd/nfs4xdr.c:3032 nfsd4_encode_fattr() error: uninitialized symbol 'sub_fsid'.
fs/nfsd/nfs4xdr.c:3281 nfsd4_encode_fattr() error: uninitialized symbol 'mounted_on_ino'.

Old smatch warnings:
fs/nfsd/nfs4xdr.c:3319 nfsd4_encode_fattr() error: uninitialized symbol 'contextlen'.
fs/nfsd/nfs4xdr.c:4803 nfsd4_encode_read_plus_hole() warn: inconsistent indenting

vim +/sub_fsid +3032 fs/nfsd/nfs4xdr.c

18032ca062e621e David Quigley       2013-05-02  2922  
75976de6556f593 Kinglong Mee        2015-07-30  2923  	status = nfsd4_encode_bitmap(xdr, bmval0, bmval1, bmval2);
75976de6556f593 Kinglong Mee        2015-07-30  2924  	if (status)
75976de6556f593 Kinglong Mee        2015-07-30  2925  		goto out;
082d4bd72a4527c J. Bruce Fields     2013-08-29  2926  
082d4bd72a4527c J. Bruce Fields     2013-08-29  2927  	attrlen_offset = xdr->buf->len;
ddd1ea56367202f J. Bruce Fields     2013-08-27  2928  	p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2929  	if (!p)
ddd1ea56367202f J. Bruce Fields     2013-08-27  2930  		goto out_resource;
082d4bd72a4527c J. Bruce Fields     2013-08-29  2931  	p++;                /* to be backfilled later */
^1da177e4c3f415 Linus Torvalds      2005-04-16  2932  
^1da177e4c3f415 Linus Torvalds      2005-04-16  2933  	if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
dcd208697707b12 J. Bruce Fields     2017-01-11  2934  		u32 supp[3];
dcd208697707b12 J. Bruce Fields     2017-01-11  2935  
dcd208697707b12 J. Bruce Fields     2017-01-11  2936  		memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
7e7057064782734 Andy Adamson        2009-04-03  2937  
0c9d65e76a19ad7 Andreas Gruenbacher 2015-04-24  2938  		if (!IS_POSIXACL(dentry->d_inode))
916d2d844afd09d J. Bruce Fields     2016-10-18  2939  			supp[0] &= ~FATTR4_WORD0_ACL;
18032ca062e621e David Quigley       2013-05-02  2940  		if (!contextsupport)
916d2d844afd09d J. Bruce Fields     2016-10-18  2941  			supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
916d2d844afd09d J. Bruce Fields     2016-10-18  2942  		if (!supp[2]) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2943  			p = xdr_reserve_space(xdr, 12);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2944  			if (!p)
2b44f1ba4091477 Benny Halevy        2010-09-30  2945  				goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2946  			*p++ = cpu_to_be32(2);
916d2d844afd09d J. Bruce Fields     2016-10-18  2947  			*p++ = cpu_to_be32(supp[0]);
916d2d844afd09d J. Bruce Fields     2016-10-18  2948  			*p++ = cpu_to_be32(supp[1]);
7e7057064782734 Andy Adamson        2009-04-03  2949  		} else {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2950  			p = xdr_reserve_space(xdr, 16);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2951  			if (!p)
2b44f1ba4091477 Benny Halevy        2010-09-30  2952  				goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2953  			*p++ = cpu_to_be32(3);
916d2d844afd09d J. Bruce Fields     2016-10-18  2954  			*p++ = cpu_to_be32(supp[0]);
916d2d844afd09d J. Bruce Fields     2016-10-18  2955  			*p++ = cpu_to_be32(supp[1]);
916d2d844afd09d J. Bruce Fields     2016-10-18  2956  			*p++ = cpu_to_be32(supp[2]);
7e7057064782734 Andy Adamson        2009-04-03  2957  		}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2958  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2959  	if (bmval0 & FATTR4_WORD0_TYPE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2960  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2961  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  2962  			goto out_resource;
3d2544b1e4909b6 J. Bruce Fields     2011-08-15  2963  		dummy = nfs4_file_type(stat.mode);
6b6d8137f1d3fc7 J. Bruce Fields     2013-01-16  2964  		if (dummy == NF4BAD) {
6b6d8137f1d3fc7 J. Bruce Fields     2013-01-16  2965  			status = nfserr_serverfault;
6b6d8137f1d3fc7 J. Bruce Fields     2013-01-16  2966  			goto out;
6b6d8137f1d3fc7 J. Bruce Fields     2013-01-16  2967  		}
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2968  		*p++ = cpu_to_be32(dummy);
^1da177e4c3f415 Linus Torvalds      2005-04-16  2969  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2970  	if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2971  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2972  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  2973  			goto out_resource;
496400014f22c4d NeilBrown           2005-06-23  2974  		if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2975  			*p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
496400014f22c4d NeilBrown           2005-06-23  2976  		else
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2977  			*p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2978  						NFS4_FH_VOL_RENAME);
^1da177e4c3f415 Linus Torvalds      2005-04-16  2979  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2980  	if (bmval0 & FATTR4_WORD0_CHANGE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2981  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2982  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  2983  			goto out_resource;
b880092109323d1 NeilBrown           2017-01-30  2984  		p = encode_change(p, &stat, d_inode(dentry), exp);
^1da177e4c3f415 Linus Torvalds      2005-04-16  2985  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2986  	if (bmval0 & FATTR4_WORD0_SIZE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2987  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2988  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  2989  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  2990  		p = xdr_encode_hyper(p, stat.size);
^1da177e4c3f415 Linus Torvalds      2005-04-16  2991  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2992  	if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2993  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  2994  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  2995  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  2996  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  2997  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  2998  	if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  2999  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3000  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3001  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3002  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3003  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3004  	if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3005  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3006  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3007  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3008  		*p++ = cpu_to_be32(0);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3009  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3010  	if (bmval0 & FATTR4_WORD0_FSID) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3011  		p = xdr_reserve_space(xdr, 16);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3012  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3013  			goto out_resource;
42ca09938157105 J.Bruce Fields      2006-10-04  3014  		if (exp->ex_fslocs.migrated) {
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3015  			p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3016  			p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
af6a4e280e3ff45 NeilBrown           2007-02-14  3017  		} else switch(fsid_source(fhp)) {
af6a4e280e3ff45 NeilBrown           2007-02-14  3018  		case FSIDSOURCE_FSID:
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3019  			p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3020  			p = xdr_encode_hyper(p, (u64)0);
af6a4e280e3ff45 NeilBrown           2007-02-14  3021  			break;
af6a4e280e3ff45 NeilBrown           2007-02-14  3022  		case FSIDSOURCE_DEV:
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3023  			*p++ = cpu_to_be32(0);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3024  			*p++ = cpu_to_be32(MAJOR(stat.dev));
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3025  			*p++ = cpu_to_be32(0);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3026  			*p++ = cpu_to_be32(MINOR(stat.dev));
af6a4e280e3ff45 NeilBrown           2007-02-14  3027  			break;
af6a4e280e3ff45 NeilBrown           2007-02-14  3028  		case FSIDSOURCE_UUID:
94eb36892d72714 Kinglong Mee        2014-05-23  3029  			p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
94eb36892d72714 Kinglong Mee        2014-05-23  3030  								EX_UUID_LEN);
5caed3f714c903d NeilBrown           2021-07-28  3031  			if (mnt != exp->ex_path.mnt)
5caed3f714c903d NeilBrown           2021-07-28 @3032  				*(u64*)(p-2) ^= sub_fsid;
af6a4e280e3ff45 NeilBrown           2007-02-14  3033  			break;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3034  		}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3035  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3036  	if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3037  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3038  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3039  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3040  		*p++ = cpu_to_be32(0);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3041  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3042  	if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3043  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3044  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3045  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3046  		*p++ = cpu_to_be32(nn->nfsd4_lease);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3047  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3048  	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3049  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3050  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3051  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3052  		*p++ = cpu_to_be32(rdattr_err);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3053  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3054  	if (bmval0 & FATTR4_WORD0_ACL) {
^1da177e4c3f415 Linus Torvalds      2005-04-16  3055  		struct nfs4_ace *ace;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3056  
^1da177e4c3f415 Linus Torvalds      2005-04-16  3057  		if (acl == NULL) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3058  			p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3059  			if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3060  				goto out_resource;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3061  
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3062  			*p++ = cpu_to_be32(0);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3063  			goto out_acl;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3064  		}
ddd1ea56367202f J. Bruce Fields     2013-08-27  3065  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3066  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3067  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3068  		*p++ = cpu_to_be32(acl->naces);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3069  
28e05dd8457c7a7 J. Bruce Fields     2007-02-16  3070  		for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3071  			p = xdr_reserve_space(xdr, 4*3);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3072  			if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3073  				goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3074  			*p++ = cpu_to_be32(ace->type);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3075  			*p++ = cpu_to_be32(ace->flag);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3076  			*p++ = cpu_to_be32(ace->access_mask &
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3077  							NFS4_ACE_MASK_ALL);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3078  			status = nfsd4_encode_aclname(xdr, rqstp, ace);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3079  			if (status)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3080  				goto out;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3081  		}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3082  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3083  out_acl:
^1da177e4c3f415 Linus Torvalds      2005-04-16  3084  	if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3085  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3086  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3087  			goto out_resource;
0c9d65e76a19ad7 Andreas Gruenbacher 2015-04-24  3088  		*p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ?
^1da177e4c3f415 Linus Torvalds      2005-04-16  3089  			ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3090  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3091  	if (bmval0 & FATTR4_WORD0_CANSETTIME) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3092  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3093  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3094  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3095  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3096  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3097  	if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3098  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3099  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3100  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3101  		*p++ = cpu_to_be32(0);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3102  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3103  	if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3104  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3105  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3106  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3107  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3108  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3109  	if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3110  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3111  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3112  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3113  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3114  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3115  	if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3116  		p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3117  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3118  			goto out_resource;
0c0c267ba96f606 J. Bruce Fields     2014-03-22  3119  		p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base,
0c0c267ba96f606 J. Bruce Fields     2014-03-22  3120  					fhp->fh_handle.fh_size);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3121  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3122  	if (bmval0 & FATTR4_WORD0_FILEID) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3123  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3124  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3125  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3126  		p = xdr_encode_hyper(p, stat.ino);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3127  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3128  	if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3129  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3130  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3131  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3132  		p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3133  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3134  	if (bmval0 & FATTR4_WORD0_FILES_FREE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3135  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3136  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3137  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3138  		p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3139  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3140  	if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3141  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3142  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3143  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3144  		p = xdr_encode_hyper(p, (u64) statfs.f_files);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3145  	}
81c3f4130202a1d J.Bruce Fields      2006-10-04  3146  	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3147  		status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
81c3f4130202a1d J.Bruce Fields      2006-10-04  3148  		if (status)
81c3f4130202a1d J.Bruce Fields      2006-10-04  3149  			goto out;
81c3f4130202a1d J.Bruce Fields      2006-10-04  3150  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3151  	if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3152  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3153  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3154  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3155  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3156  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3157  	if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3158  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3159  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3160  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3161  		p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3162  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3163  	if (bmval0 & FATTR4_WORD0_MAXLINK) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3164  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3165  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3166  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3167  		*p++ = cpu_to_be32(255);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3168  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3169  	if (bmval0 & FATTR4_WORD0_MAXNAME) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3170  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3171  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3172  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3173  		*p++ = cpu_to_be32(statfs.f_namelen);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3174  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3175  	if (bmval0 & FATTR4_WORD0_MAXREAD) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3176  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3177  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3178  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3179  		p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
^1da177e4c3f415 Linus Torvalds      2005-04-16  3180  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3181  	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3182  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3183  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3184  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3185  		p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
^1da177e4c3f415 Linus Torvalds      2005-04-16  3186  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3187  	if (bmval1 & FATTR4_WORD1_MODE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3188  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3189  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3190  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3191  		*p++ = cpu_to_be32(stat.mode & S_IALLUGO);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3192  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3193  	if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3194  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3195  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3196  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3197  		*p++ = cpu_to_be32(1);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3198  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3199  	if (bmval1 & FATTR4_WORD1_NUMLINKS) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3200  		p = xdr_reserve_space(xdr, 4);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3201  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3202  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3203  		*p++ = cpu_to_be32(stat.nlink);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3204  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3205  	if (bmval1 & FATTR4_WORD1_OWNER) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3206  		status = nfsd4_encode_user(xdr, rqstp, stat.uid);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3207  		if (status)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3208  			goto out;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3209  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3210  	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3211  		status = nfsd4_encode_group(xdr, rqstp, stat.gid);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3212  		if (status)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3213  			goto out;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3214  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3215  	if (bmval1 & FATTR4_WORD1_RAWDEV) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3216  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3217  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3218  			goto out_resource;
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3219  		*p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3220  		*p++ = cpu_to_be32((u32) MINOR(stat.rdev));
^1da177e4c3f415 Linus Torvalds      2005-04-16  3221  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3222  	if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3223  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3224  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3225  			goto out_resource;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3226  		dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3227  		p = xdr_encode_hyper(p, dummy64);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3228  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3229  	if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3230  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3231  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3232  			goto out_resource;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3233  		dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3234  		p = xdr_encode_hyper(p, dummy64);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3235  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3236  	if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3237  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3238  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3239  			goto out_resource;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3240  		dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3241  		p = xdr_encode_hyper(p, dummy64);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3242  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3243  	if (bmval1 & FATTR4_WORD1_SPACE_USED) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3244  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3245  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3246  			goto out_resource;
^1da177e4c3f415 Linus Torvalds      2005-04-16  3247  		dummy64 = (u64)stat.blocks << 9;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3248  		p = xdr_encode_hyper(p, dummy64);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3249  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3250  	if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3251  		p = xdr_reserve_space(xdr, 12);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3252  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3253  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3254  		p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3255  		*p++ = cpu_to_be32(stat.atime.tv_nsec);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3256  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3257  	if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3258  		p = xdr_reserve_space(xdr, 12);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3259  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3260  			goto out_resource;
16945141c3567bb J. Bruce Fields     2018-04-25  3261  		p = encode_time_delta(p, d_inode(dentry));
^1da177e4c3f415 Linus Torvalds      2005-04-16  3262  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3263  	if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3264  		p = xdr_reserve_space(xdr, 12);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3265  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3266  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3267  		p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3268  		*p++ = cpu_to_be32(stat.ctime.tv_nsec);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3269  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3270  	if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3271  		p = xdr_reserve_space(xdr, 12);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3272  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3273  			goto out_resource;
b64c7f3bdfbb468 J. Bruce Fields     2014-03-22  3274  		p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
c373b0a4289ebf1 J. Bruce Fields     2014-03-22  3275  		*p++ = cpu_to_be32(stat.mtime.tv_nsec);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3276  	}
^1da177e4c3f415 Linus Torvalds      2005-04-16  3277  	if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
ddd1ea56367202f J. Bruce Fields     2013-08-27  3278  		p = xdr_reserve_space(xdr, 8);
ddd1ea56367202f J. Bruce Fields     2013-08-27  3279  		if (!p)
^1da177e4c3f415 Linus Torvalds      2005-04-16  3280  			goto out_resource;
5caed3f714c903d NeilBrown           2021-07-28  3281  		p = xdr_encode_hyper(p, mounted_on_ino);
^1da177e4c3f415 Linus Torvalds      2005-04-16  3282  	}
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3283  #ifdef CONFIG_NFSD_PNFS
6896f15aabde505 Kinglong Mee        2015-07-30  3284  	if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
8a4c3926889e7bf Jeff Layton         2016-07-10  3285  		status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
6896f15aabde505 Kinglong Mee        2015-07-30  3286  		if (status)
6896f15aabde505 Kinglong Mee        2015-07-30  3287  			goto out;
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3288  	}
6896f15aabde505 Kinglong Mee        2015-07-30  3289  
6896f15aabde505 Kinglong Mee        2015-07-30  3290  	if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
8a4c3926889e7bf Jeff Layton         2016-07-10  3291  		status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
6896f15aabde505 Kinglong Mee        2015-07-30  3292  		if (status)
6896f15aabde505 Kinglong Mee        2015-07-30  3293  			goto out;
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3294  	}
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3295  
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3296  	if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3297  		p = xdr_reserve_space(xdr, 4);
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3298  		if (!p)
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3299  			goto out_resource;
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3300  		*p++ = cpu_to_be32(stat.blksize);
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3301  	}
9cf514ccfacb301 Christoph Hellwig   2014-05-05  3302  #endif /* CONFIG_NFSD_PNFS */
8c18f2052e756e7 Benny Halevy        2009-04-03  3303  	if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
b26b78cb7260075 Trond Myklebust     2017-05-09  3304  		u32 supp[3];
b26b78cb7260075 Trond Myklebust     2017-05-09  3305  
b26b78cb7260075 Trond Myklebust     2017-05-09  3306  		memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
b26b78cb7260075 Trond Myklebust     2017-05-09  3307  		supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0;
b26b78cb7260075 Trond Myklebust     2017-05-09  3308  		supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1;
b26b78cb7260075 Trond Myklebust     2017-05-09  3309  		supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
b26b78cb7260075 Trond Myklebust     2017-05-09  3310  
b26b78cb7260075 Trond Myklebust     2017-05-09  3311  		status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]);
75976de6556f593 Kinglong Mee        2015-07-30  3312  		if (status)
75976de6556f593 Kinglong Mee        2015-07-30  3313  			goto out;
8c18f2052e756e7 Benny Halevy        2009-04-03  3314  	}
7e7057064782734 Andy Adamson        2009-04-03  3315  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 37347 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points.
  2021-07-28 19:15   ` J. Bruce Fields
@ 2021-07-28 22:29     ` NeilBrown
  0 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2021-07-28 22:29 UTC (permalink / raw
  To: J. Bruce Fields
  Cc: Christoph Hellwig, Josef Bacik, Chuck Lever, Chris Mason,
	David Sterba, Alexander Viro, linux-fsdevel, linux-nfs,
	linux-btrfs

On Thu, 29 Jul 2021, J. Bruce Fields wrote:
> On Wed, Jul 28, 2021 at 08:37:45AM +1000, NeilBrown wrote:
> > Enhance nfsd to detect internal mounts and to cross them without
> > requiring a new export.
> 
> Why don't we want a new export?
> 
> (Honest question, it's not obvious to me what the best behavior is.)

Because a new export means asking user-space to determine if the mount
is exported and to provide a filehandle-prefix for it.  A large part of
the point of this it to avoid using a different filehandle-prefix.

I haven't yet thought deeply about how the 'crossmnt' flag (for v3)
should affect crossing these internal mounts.  My current feeling is
that it shouldn't as it really is just one big filesystem being
exported, which happens to internally have different inode-number
spaces. 
Unfortuantely this technically violates the RFC as the fsid is not meant
to change when you do a LOOKUP ...

NeilBrown


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points.
  2021-07-27 22:37 ` [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points NeilBrown
  2021-07-28 19:15   ` J. Bruce Fields
@ 2021-07-30  0:42   ` Al Viro
  2021-07-30  5:43     ` NeilBrown
  1 sibling, 1 reply; 6+ messages in thread
From: Al Viro @ 2021-07-30  0:42 UTC (permalink / raw
  To: NeilBrown
  Cc: Christoph Hellwig, Josef Bacik, J. Bruce Fields, Chuck Lever,
	Chris Mason, David Sterba, linux-fsdevel, linux-nfs, linux-btrfs

On Wed, Jul 28, 2021 at 08:37:45AM +1000, NeilBrown wrote:

> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index baa12ac36ece..22523e1cd478 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -64,7 +64,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
>  			    .dentry = dget(path_parent->dentry)};
>  	int err = 0;
>  
> -	err = follow_down(&path, 0);
> +	err = follow_down(&path, LOOKUP_AUTOMOUNT);
>  	if (err < 0)
>  		goto out;
>  	if (path.mnt == path_parent->mnt && path.dentry == path_parent->dentry &&
> @@ -73,6 +73,13 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
>  		path_put(&path);
>  		goto out;
>  	}
> +	if (mount_is_internal(path.mnt)) {
> +		/* Use the new path, but don't look for a new export */
> +		/* FIXME should I check NOHIDE in this case?? */
> +		path_put(path_parent);
> +		*path_parent = path;
> +		goto out;
> +	}

... IOW, mount_is_internal() is called with no exclusion whatsoever.  What's there
to
	* keep its return value valid?
	* prevent fetching ->mnt_mountpoint, getting preempted away, having
the mount moved *and* what used to be ->mnt_mountpoint evicted from dcache,
now that it's no longer pinned, then mount_is_internal() regaining CPU and
dereferencing ->mnt_mountpoint, which now points to hell knows what?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points.
  2021-07-30  0:42   ` Al Viro
@ 2021-07-30  5:43     ` NeilBrown
  0 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2021-07-30  5:43 UTC (permalink / raw
  To: Al Viro
  Cc: Christoph Hellwig, Josef Bacik, J. Bruce Fields, Chuck Lever,
	Chris Mason, David Sterba, linux-fsdevel, linux-nfs, linux-btrfs

On Fri, 30 Jul 2021, Al Viro wrote:
> On Wed, Jul 28, 2021 at 08:37:45AM +1000, NeilBrown wrote:
> 
> > diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> > index baa12ac36ece..22523e1cd478 100644
> > --- a/fs/nfsd/vfs.c
> > +++ b/fs/nfsd/vfs.c
> > @@ -64,7 +64,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
> >  			    .dentry = dget(path_parent->dentry)};
> >  	int err = 0;
> >  
> > -	err = follow_down(&path, 0);
> > +	err = follow_down(&path, LOOKUP_AUTOMOUNT);
> >  	if (err < 0)
> >  		goto out;
> >  	if (path.mnt == path_parent->mnt && path.dentry == path_parent->dentry &&
> > @@ -73,6 +73,13 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct path *path_parent,
> >  		path_put(&path);
> >  		goto out;
> >  	}
> > +	if (mount_is_internal(path.mnt)) {
> > +		/* Use the new path, but don't look for a new export */
> > +		/* FIXME should I check NOHIDE in this case?? */
> > +		path_put(path_parent);
> > +		*path_parent = path;
> > +		goto out;
> > +	}
> 
> ... IOW, mount_is_internal() is called with no exclusion whatsoever.  What's there
> to
> 	* keep its return value valid?
> 	* prevent fetching ->mnt_mountpoint, getting preempted away, having
> the mount moved *and* what used to be ->mnt_mountpoint evicted from dcache,
> now that it's no longer pinned, then mount_is_internal() regaining CPU and
> dereferencing ->mnt_mountpoint, which now points to hell knows what?
> 

Yes, mount_is_internal needs to same mount_lock protection that
lookup_mnt() has.  Thanks.

I don't think it matter how long the result remains valid.  The only
realistic transtion is from True to False, but the fact that it *was*
True means that it is acceptable for the lookup to have succeeded.
i.e.  If the mountpoint was moved which a request was being processed it
will either cause the same result as if it happened before the request
started, or after it finished.  Either seems OK.

Thanks,
NeilBrown


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-30  5:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-07-28 22:12 [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2021-07-27 22:37 [PATCH/RFC 00/11] expose btrfs subvols in mount table correctly NeilBrown
2021-07-27 22:37 ` [PATCH 09/11] nfsd: Allow filehandle lookup to cross internal mount points NeilBrown
2021-07-28 19:15   ` J. Bruce Fields
2021-07-28 22:29     ` NeilBrown
2021-07-30  0:42   ` Al Viro
2021-07-30  5:43     ` NeilBrown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.