svn commit: r230516 - in head/sys: fs/nfsclient nfsclient
Rick Macklem
rmacklem at FreeBSD.org
Wed Jan 25 00:22:54 UTC 2012
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
More information about the svn-src-head
mailing list