Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jan 2012 00:22:54 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r230516 - in head/sys: fs/nfsclient nfsclient
Message-ID:  <201201250022.q0P0MsEY098760@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed Jan 25 00:22:53 2012
New Revision: 230516
URL: http://svn.freebsd.org/changeset/base/230516

Log:
  If a mount -u is done to either NFS client that switches it
  from TCP to UDP and the rsize/wsize/readdirsize is greater
  than NFS_MAXDGRAMDATA, it is possible for a thread doing an
  I/O RPC to get stuck repeatedly doing retries. This happens
  because the RPC will use a resize/wsize/readdirsize that won't
  work for UDP and, as such, it will keep failing indefinitely.
  This patch returns an error for this case, to avoid the problem.
  A discussion on freebsd-fs@ seemed to indicate that returning
  an error was preferable to silently ignoring the "udp"/"mntudp"
  option.
  This problem was discovered while investigating a problem reported
  by pjd@ via email.
  
  MFC after:	2 weeks

Modified:
  head/sys/fs/nfsclient/nfs_clvfsops.c
  head/sys/nfsclient/nfs_vfsops.c

Modified: head/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvfsops.c	Tue Jan 24 23:43:13 2012	(r230515)
+++ head/sys/fs/nfsclient/nfs_clvfsops.c	Wed Jan 25 00:22:53 2012	(r230516)
@@ -989,6 +989,23 @@ nfs_mount(struct mount *mp)
 			error = EIO;
 			goto out;
 		}
+
+		/*
+		 * Cannot switch to UDP if current rsize/wsize/readdirsize is
+		 * too large, since there may be an I/O RPC in progress that
+		 * will get retried after the switch to the UDP socket. These
+		 * retries will fail over and over and over again.
+		 */
+		if (args.sotype == SOCK_DGRAM &&
+		    (nmp->nm_rsize > NFS_MAXDGRAMDATA ||
+		     nmp->nm_wsize > NFS_MAXDGRAMDATA ||
+		     nmp->nm_readdirsize > NFS_MAXDGRAMDATA)) {
+			vfs_mount_error(mp,
+			    "old rsize/wsize/readdirsize greater than UDP max");
+			error = EINVAL;
+			goto out;
+		}
+
 		/*
 		 * When doing an update, we can't change version,
 		 * security, switch lockd strategies or change cookie

Modified: head/sys/nfsclient/nfs_vfsops.c
==============================================================================
--- head/sys/nfsclient/nfs_vfsops.c	Tue Jan 24 23:43:13 2012	(r230515)
+++ head/sys/nfsclient/nfs_vfsops.c	Wed Jan 25 00:22:53 2012	(r230516)
@@ -1106,6 +1106,23 @@ nfs_mount(struct mount *mp)
 			error = EIO;
 			goto out;
 		}
+
+		/*
+		 * Cannot switch to UDP if current rsize/wsize/readdirsize is
+		 * too large, since there may be an I/O RPC in progress that
+		 * will get retried after the switch to the UDP socket. These
+		 * retries will fail over and over and over again.
+		 */
+		if (args.sotype == SOCK_DGRAM &&
+		    (nmp->nm_rsize > NFS_MAXDGRAMDATA ||
+		     nmp->nm_wsize > NFS_MAXDGRAMDATA ||
+		     nmp->nm_readdirsize > NFS_MAXDGRAMDATA)) {
+			vfs_mount_error(mp,
+			    "old rsize/wsize/readdirsize greater than UDP max");
+			error = EINVAL;
+			goto out;
+		}
+
 		/*
 		 * When doing an update, we can't change from or to
 		 * v3, switch lockd strategies or change cookie translation



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