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
This commit is contained in:
rmacklem 2012-01-25 00:22:53 +00:00
parent 538ff2e745
commit 911de30560
2 changed files with 34 additions and 0 deletions

View File

@ -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

View File

@ -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