Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Dec 2022 01:55:53 GMT
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 1815de4fedee - stable/13 - nfsd: Handle file systems without a VOP_VPTOFH()
Message-ID:  <202212300155.2BU1trwe078007@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=1815de4fedee32cb923450d59190dc5aff5a63f4

commit 1815de4fedee32cb923450d59190dc5aff5a63f4
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2022-12-23 23:17:34 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2022-12-30 01:54:32 +0000

    nfsd: Handle file systems without a VOP_VPTOFH()
    
    Unlike NFSv3, the NFSv4 server follows mount points
    within the file system tree below the NFSv4 root directory.
    If there is a file system mounted within this subtree
    that returns EOPNOTSUPP for VOP_VPTOFH(), the NFSv4 server
    would return an error for the mount point entry.
    This resulted in an "I/O error" report from the Linux NFSv4
    client.  It also put an error code in the Readdir reply
    that is not defined in the NFSv4 RFCs.
    
    For the FreeBSD NFSv4 client, the entry with the error would
    be ignored, which I think is reasonable behaviour for a
    mounted file system that can never be exported.
    
    This patch changes the NFSv4 server behaviour to ignore the
    mount point entry and not send it in the Readdir reply.
    It also changes the behaviour of Lookup for the entry so
    that it replies ENOENT for the mount point directory, so
    that it is consistent with no entry in the Readdir reply.
    
    With these two changes, the Linux client behaviour is the
    same as the FreeBSD client behaviour.  It also avoids
    putting an unknown error on the wire to the client.
    
    (cherry picked from commit 6fd6a0e342fbfb8513ae56105cf0f85f55c6276e)
---
 sys/fs/nfsserver/nfs_nfsdport.c | 11 +++++++++--
 sys/fs/nfsserver/nfs_nfsdserv.c |  9 ++++++++-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 51c4d59e5380..407987aa767f 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2725,15 +2725,22 @@ again:
 				 * For NFSv4 the behavior is controlled by
 				 * RDATTRERROR: we either ignore the error or
 				 * fail the request.
+				 * The exception is EOPNOTSUPP, which can be
+				 * returned by nfsvno_getfh() for certain
+				 * file systems, such as devfs.  This indicates
+				 * that the file system cannot be exported,
+				 * so just skip over the entry.
 				 * Note that RDATTRERROR is never set for NFSv3.
 				 */
 				if (r != 0) {
 					if (!NFSISSET_ATTRBIT(&attrbits,
-					    NFSATTRBIT_RDATTRERROR)) {
+					    NFSATTRBIT_RDATTRERROR) ||
+					    r == EOPNOTSUPP) {
 						vput(nvp);
 						if (needs_unbusy != 0)
 							vfs_unbusy(new_mp);
-						if ((nd->nd_flag & ND_NFSV3))
+						if ((nd->nd_flag & ND_NFSV3) ||
+						    r == EOPNOTSUPP)
 							goto invalid;
 						nd->nd_repstat = r;
 						break;
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index 75e764b9b51e..2d1048d26486 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -647,8 +647,15 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int isdgram,
 		 * non-exported volumes during NFSv4 mounting.
 		 */
 		nd->nd_repstat = ENOENT;
-	if (nd->nd_repstat == 0)
+	if (nd->nd_repstat == 0) {
 		nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
+		/*
+		 * EOPNOTSUPP indicates the file system cannot be exported,
+		 * so just pretend the entry does not exist.
+		 */
+		if (nd->nd_repstat == EOPNOTSUPP)
+			nd->nd_repstat = ENOENT;
+	}
 	if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
 		nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
 	if (vpp != NULL && nd->nd_repstat == 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202212300155.2BU1trwe078007>