Bug 150910 - [nfs] wsize=16384 on udp nfs mount unusable
Summary: [nfs] wsize=16384 on udp nfs mount unusable
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 8.1-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-fs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-24 12:40 UTC by Robert Schulze
Modified: 2010-10-27 19:11 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Schulze 2010-09-24 12:40:02 UTC
Mounting an NFS filesystem with a large value for wsize results in
unexpected behaviour. Before analysis, I got strange errors from vi
like "close: permission denied" or "no space left on device" when
editing a large textfile and having /var/tmp nfs mounted, although
there was enough space.

The client is 8.1-RELEASE-p1, the server 8.0-RELEASE-p3. Both use nfs version 3.

Fix: 

Applied to head as patch r213756. The soreserve() call in clnt_dg.c
always failed due to the sendsz and recvsz arguments being too large.
Without the patch a workaround is to increase kern.ipc.maxsockbuf.
(Committed to stable/8 as r214415.)
How-To-Repeat: # mount_nfs -o noatime,udp,wsize=16384 10.0.0.xx:/var/tmp /var/tmp
# dd if=/dev/zero of=/var/tmp/foo bs=2M count=100
does not return to prompt

# dmesg
nfs server 10.0.0.xx:/var/tmp: not responding
nfs server 10.0.0.xx:/var/tmp: not responding
nfs server 10.0.0.xx:/var/tmp: not responding
nfs server 10.0.0.xx:/var/tmp: not responding
nfs server 10.0.0.xx:/var/tmp: not responding

# top
dd in state "nfsaio"

# umount -f /var/tmp

# mount_nfs -o noatime,udp,wsize=8192 10.0.0.xx:/var/tmp /var/tmp
# dd if=/dev/zero of=/var/tmp/foo bs=2M count=100
100+0 records in
100+0 records out
209715200 bytes transferred in 3.897668 secs (53805303 bytes/sec)
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2010-09-26 22:18:58 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-fs

reclassify.
Comment 2 dfilter service freebsd_committer freebsd_triage 2010-10-13 01:57:20 UTC
Author: rmacklem
Date: Wed Oct 13 00:57:14 2010
New Revision: 213756
URL: http://svn.freebsd.org/changeset/base/213756

Log:
  Fix the krpc so that it can handle NFSv3,UDP mounts with a read/write
  data size greater than 8192. Since soreserve(so, 256*1024, 256*1024)
  would always fail for the default value of sb_max, modify clnt_dg.c
  so that it uses the calculated values and checks for an error return
  from soreserve(). Also, add a check for error return from soreserve()
  to clnt_vc.c and change __rpc_get_t_size() to use sb_max_adj instead of
  the bogus maxsize == 256*1024.
  
  PR:		kern/150910
  Reviewed by:	jhb
  MFC after:	2 weeks

Modified:
  head/sys/rpc/clnt_dg.c
  head/sys/rpc/clnt_vc.c
  head/sys/rpc/rpc_generic.c

Modified: head/sys/rpc/clnt_dg.c
==============================================================================
--- head/sys/rpc/clnt_dg.c	Wed Oct 13 00:21:53 2010	(r213755)
+++ head/sys/rpc/clnt_dg.c	Wed Oct 13 00:57:14 2010	(r213756)
@@ -193,6 +193,7 @@ clnt_dg_create(
 	struct rpc_msg call_msg;
 	struct __rpc_sockinfo si;
 	XDR xdrs;
+	int error;
 
 	if (svcaddr == NULL) {
 		rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
@@ -267,7 +268,12 @@ clnt_dg_create(
 	 */
 	cu->cu_closeit = FALSE;
 	cu->cu_socket = so;
-	soreserve(so, 256*1024, 256*1024);
+	error = soreserve(so, (u_long)sendsz, (u_long)recvsz);
+	if (error != 0) {
+		rpc_createerr.cf_stat = RPC_FAILED;
+		rpc_createerr.cf_error.re_errno = error;
+		goto err2;
+	}
 
 	sb = &so->so_rcv;
 	SOCKBUF_LOCK(&so->so_rcv);

Modified: head/sys/rpc/clnt_vc.c
==============================================================================
--- head/sys/rpc/clnt_vc.c	Wed Oct 13 00:21:53 2010	(r213755)
+++ head/sys/rpc/clnt_vc.c	Wed Oct 13 00:57:14 2010	(r213756)
@@ -288,13 +288,19 @@ clnt_vc_create(
 	 * Create a client handle which uses xdrrec for serialization
 	 * and authnone for authentication.
 	 */
+	sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
+	recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
+	error = soreserve(ct->ct_socket, sendsz, recvsz);
+	if (error != 0) {
+		if (ct->ct_closeit) {
+			soclose(ct->ct_socket);
+		}
+		goto err;
+	}
 	cl->cl_refs = 1;
 	cl->cl_ops = &clnt_vc_ops;
 	cl->cl_private = ct;
 	cl->cl_auth = authnone_create();
-	sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
-	recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
-	soreserve(ct->ct_socket, sendsz, recvsz);
 
 	SOCKBUF_LOCK(&ct->ct_socket->so_rcv);
 	soupcall_set(ct->ct_socket, SO_RCV, clnt_vc_soupcall, ct);

Modified: head/sys/rpc/rpc_generic.c
==============================================================================
--- head/sys/rpc/rpc_generic.c	Wed Oct 13 00:21:53 2010	(r213755)
+++ head/sys/rpc/rpc_generic.c	Wed Oct 13 00:57:14 2010	(r213756)
@@ -63,6 +63,8 @@ __FBSDID("$FreeBSD$");
 
 #include <rpc/rpc_com.h>
 
+extern	u_long sb_max_adj;	/* not defined in socketvar.h */
+
 #if __FreeBSD_version < 700000
 #define strrchr rindex
 #endif
@@ -113,9 +115,8 @@ u_int
 /*ARGSUSED*/
 __rpc_get_t_size(int af, int proto, int size)
 {
-	int maxsize, defsize;
+	int defsize;
 
-	maxsize = 256 * 1024;	/* XXX */
 	switch (proto) {
 	case IPPROTO_TCP:
 		defsize = 64 * 1024;	/* XXX */
@@ -131,7 +132,7 @@ __rpc_get_t_size(int af, int proto, int 
 		return defsize;
 
 	/* Check whether the value is within the upper max limit */
-	return (size > maxsize ? (u_int)maxsize : (u_int)size);
+	return (size > sb_max_adj ? (u_int)sb_max_adj : (u_int)size);
 }
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 3 Rick Macklem freebsd_committer freebsd_triage 2010-10-13 02:11:13 UTC
State Changed
From-To: open->feedback


Patch for the bug has been applied to head.
Comment 4 Rick Macklem freebsd_committer freebsd_triage 2010-10-27 19:09:10 UTC
State Changed
From-To: feedback->closed


The fix has now been committed to stable/8.