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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to