diff mbox series

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

Message ID 20231011051131.24667-4-neilb@suse.de (mailing list archive)
State New, archived
Headers show
Series fixes for error handling in nfsd_fh | expand

Commit Message

NeilBrown Oct. 11, 2023, 4:58 a.m. UTC
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@suse.de>
---
 support/export/cache.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)
diff mbox series

Patch

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