diff mbox series

NFSv3: only use NFS timeout for MOUNT when protocols are compatible

Message ID 172800404387.1692160.2013457390996721241@noble.neil.brown.name (mailing list archive)
State New
Headers show
Series NFSv3: only use NFS timeout for MOUNT when protocols are compatible | expand

Commit Message

NeilBrown Oct. 4, 2024, 1:07 a.m. UTC
If a timeout is specified in the mount options, it currently applies to
both the NFS protocol and (with v3) the MOUNT protocol.  This is
sensible when they both use the same underlying protocol, or those
protocols are compatible w.r.t timeouts as RDMA and TCP are.

However if, for example, NFS is using TCP and MOUNT is using UDP then
using the same timeout doesn't make much sense.

If you
   mount -o vers=3,proto=tcp,mountproto=udp,timeo=600,retrans=5 \
      server:/path /mountpoint

then the timeo=600 which was intended for the NFS/TCP request will
apply to the MOUNT/UDP requests with the result that there will only be
one request sent (because UDP has a maximum timeout of 60 seconds).
This is not what a reasonable person might expect.

This patch disables the sharing of timeout information in cases where
the underlying protocols are not compatible.

Fixes: c9301cb35b59 ("nfs: hornor timeo and retrans option when mounting NFSv3")
Signed-off-by: NeilBrown <neilb@suse.de>
---
 fs/nfs/super.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

NeilBrown Nov. 4, 2024, 5:52 a.m. UTC | #1
On Fri, 04 Oct 2024, NeilBrown wrote:
> If a timeout is specified in the mount options, it currently applies to
> both the NFS protocol and (with v3) the MOUNT protocol.  This is
> sensible when they both use the same underlying protocol, or those
> protocols are compatible w.r.t timeouts as RDMA and TCP are.
> 
> However if, for example, NFS is using TCP and MOUNT is using UDP then
> using the same timeout doesn't make much sense.
> 
> If you
>    mount -o vers=3,proto=tcp,mountproto=udp,timeo=600,retrans=5 \
>       server:/path /mountpoint
> 
> then the timeo=600 which was intended for the NFS/TCP request will
> apply to the MOUNT/UDP requests with the result that there will only be
> one request sent (because UDP has a maximum timeout of 60 seconds).
> This is not what a reasonable person might expect.
> 
> This patch disables the sharing of timeout information in cases where
> the underlying protocols are not compatible.
> 
> Fixes: c9301cb35b59 ("nfs: hornor timeo and retrans option when mounting NFSv3")
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
>  fs/nfs/super.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index 9723b6c53397..ae5c5e39afa0 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -885,7 +885,15 @@ static int nfs_request_mount(struct fs_context *fc,
>  	 * Now ask the mount server to map our export path
>  	 * to a file handle.
>  	 */
> -	status = nfs_mount(&request, ctx->timeo, ctx->retrans);
> +	if ((request.protocol == XPRT_TRANSPORT_UDP) ==
> +	    !(ctx->flags & NFS_MOUNT_TCP))
> +		/*
> +		 * NFS protocol and mount protocol are both UDP or neither UDP
> +		 * so timeouts are compatible.  Use NFS timeouts for MOUNT
> +		 */
> +		status = nfs_mount(&request, ctx->timeo, ctx->retrans);
> +	else
> +		status = nfs_mount(&request, NFS_UNSPEC_TIMEO, NFS_UNSPEC_RETRANS);
>  	if (status != 0) {
>  		dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
>  				request.hostname, status);
> -- 
> 2.46.0
> 
> 
> 

Anna, Trond: have you had a chance to look at this yet?

Thanks,
NeilBrown
diff mbox series

Patch

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9723b6c53397..ae5c5e39afa0 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -885,7 +885,15 @@  static int nfs_request_mount(struct fs_context *fc,
 	 * Now ask the mount server to map our export path
 	 * to a file handle.
 	 */
-	status = nfs_mount(&request, ctx->timeo, ctx->retrans);
+	if ((request.protocol == XPRT_TRANSPORT_UDP) ==
+	    !(ctx->flags & NFS_MOUNT_TCP))
+		/*
+		 * NFS protocol and mount protocol are both UDP or neither UDP
+		 * so timeouts are compatible.  Use NFS timeouts for MOUNT
+		 */
+		status = nfs_mount(&request, ctx->timeo, ctx->retrans);
+	else
+		status = nfs_mount(&request, NFS_UNSPEC_TIMEO, NFS_UNSPEC_RETRANS);
 	if (status != 0) {
 		dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
 				request.hostname, status);