[PATCH 3/3 RFC] export: nfsd_fh - always an answer to a well-formed question.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When the kernel asks mountd for some information it is important that
mountd reply as the kernel will not ask again.
When we don't have a useful reply we want the kernel to see this
as a transient failure.  This not currently (v6.6) any way to
communicate a transient failure.  The best we can do is give a
negative answer which is already expired.  This will at least
allow the kernel to ask again.

The kernel needs to be enhanced to not treat an entry that is already
expired as ever reliable.

Signed-off-by: NeilBrown <neilb@xxxxxxx>
---
 support/export/cache.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/support/export/cache.c b/support/export/cache.c
index 5307f6c8d872..74cacea9f0cc 100644
--- a/support/export/cache.c
+++ b/support/export/cache.c
@@ -894,7 +894,7 @@ static void nfsd_fh(int f)
 		 * quiet rather than returning stale yet
 		 */
 		if (dev_missing)
-			goto out;
+			goto out_delay;
 	} else if (found->e_mountpoint &&
 	    !is_mountpoint(found->e_mountpoint[0]?
 			   found->e_mountpoint:
@@ -904,8 +904,7 @@ static void nfsd_fh(int f)
 		   xlog(L_WARNING, "%s not exported as %d not a mountpoint",
 		   found->e_path, found->e_mountpoint);
 		 */
-		/* FIXME we need to make sure we re-visit this later */
-		goto out;
+		goto out_delay;
 	}
 
 	bp = buf; blen = sizeof(buf);
@@ -934,6 +933,26 @@ out:
 	nfs_freeaddrinfo(ai);
 	free(dom);
 	xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL);
+	return;
+
+out_delay:
+	/* We don't have a definitely answer to give the kernel - maybe we will later.
+	 * This could be because an export marked "mountpoint" isn't a mountpoint, or
+	 * because a mountpoint fails with a strange error like ETIMEDOUT as is possible
+	 * with an NFS mount marked "softerr" which is being re-exported.
+	 * If we tell the kernel nothing, it will never ask again, so we have
+	 * to give some answer.  A negative answer that has already expired
+	 * is the best we can do.
+	 */
+	bp = buf; blen = sizeof(buf);
+	qword_add(&bp, &blen, dom);
+	qword_addint(&bp, &blen, fsidtype);
+	qword_addhex(&bp, &blen, fsid, fsidlen);
+	qword_addint(&bp, &blen, time(NULL) - 1);
+	qword_addeol(&bp, &blen);
+	if (blen <= 0 || cache_write(f, buf, bp - buf) != bp - buf)
+		xlog(L_ERROR, "nfsd_fh: error writing reply");
+	xlog(D_AUTH, "unknown access to %s", *dom == '$' ? dom+1 : dom);
 }
 
 #ifdef HAVE_JUNCTION_SUPPORT
-- 
2.42.0




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux