Page MenuHomeFreeBSD

D30826.diff
No OneTemporary

D30826.diff

diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h
--- a/sys/fs/nfs/nfs.h
+++ b/sys/fs/nfs/nfs.h
@@ -156,7 +156,7 @@
(t).tv_sec = time.tv_sec; (t).tv_nsec = 1000 * time.tv_usec; } while (0)
#define NFS_SRVMAXDATA(n) \
(((n)->nd_flag & (ND_NFSV3 | ND_NFSV4)) ? \
- NFS_SRVMAXIO : NFS_V2MAXDATA)
+ nfs_srvmaxio : NFS_V2MAXDATA)
#define NFS64BITSSET 0xffffffffffffffffull
#define NFS64BITSMINUS1 0xfffffffffffffffeull
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -76,6 +76,7 @@
void (*ncl_call_invalcaches)(struct vnode *) = NULL;
vop_advlock_t *nfs_advlock_p = NULL;
vop_reclaim_t *nfs_reclaim_p = NULL;
+uint32_t nfs_srvmaxio = NFS_SRVMAXIO;
int nfs_pnfsio(task_fn_t *, void *);
@@ -303,11 +304,11 @@
if (isdgram)
pref = NFS_MAXDGRAMDATA;
else
- pref = NFS_SRVMAXIO;
- sip->fs_rtmax = NFS_SRVMAXIO;
+ pref = nfs_srvmaxio;
+ sip->fs_rtmax = nfs_srvmaxio;
sip->fs_rtpref = pref;
sip->fs_rtmult = NFS_FABLKSIZE;
- sip->fs_wtmax = NFS_SRVMAXIO;
+ sip->fs_wtmax = nfs_srvmaxio;
sip->fs_wtpref = pref;
sip->fs_wtmult = NFS_FABLKSIZE;
sip->fs_dtpref = pref;
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -85,6 +85,7 @@
extern int nfscl_debuglevel;
extern struct nfsdevicehead nfsrv_devidhead;
extern struct nfsstatsv1 nfsstatsv1;
+extern uint32_t nfs_srvmaxio;
SYSCTL_DECL(_vfs_nfs);
SYSCTL_INT(_vfs_nfs, OID_AUTO, enable_uidtostring, CTLFLAG_RW,
@@ -2201,7 +2202,7 @@
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
attrsum += NFSX_UNSIGNED;
i = fxdr_unsigned(int, *tl);
- if (compare && !(*retcmpp) && i != NFS_SRVMAXIO)
+ if (compare && !(*retcmpp) && i != nfs_srvmaxio)
*retcmpp = NFSERR_NOTSAME;
break;
default:
@@ -3012,7 +3013,7 @@
case NFSATTRBIT_LAYOUTALIGNMENT:
case NFSATTRBIT_LAYOUTBLKSIZE:
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
- *tl = txdr_unsigned(NFS_SRVMAXIO);
+ *tl = txdr_unsigned(nfs_srvmaxio);
retnum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_XATTRSUPPORT:
diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h
--- a/sys/fs/nfs/nfsproto.h
+++ b/sys/fs/nfs/nfsproto.h
@@ -73,7 +73,6 @@
*/
#define NFS_MAXPKTHDR 404
#define NFS_MAXXDR 4096
-#define NFS_MAXPACKET (NFS_SRVMAXIO + NFS_MAXXDR)
#define NFS_MINPACKET 20
#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
#define NFSV4_MINORVERSION 0 /* V4 Minor version */
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -76,6 +76,9 @@
extern volatile int nfsrv_dontlistlen;
extern volatile int nfsrv_devidcnt;
extern int nfsrv_maxpnfsmirror;
+extern uint32_t nfs_srvmaxio;
+extern int nfs_bufpackets;
+extern u_long sb_max_adj;
struct vfsoptlist nfsv4root_opt, nfsv4root_newopt;
NFSDLOCKMUTEX;
NFSSTATESPINLOCK;
@@ -195,6 +198,84 @@
CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof(nfsrv_dsdirsize),
sysctl_dsdirsize, "IU", "Number of dsN subdirs on the DS servers");
+/*
+ * nfs_srvmaxio can only be increased and only when the nfsd threads are
+ * not running. The setting must be a power of 2, with the current limit of
+ * 1Mbyte.
+ */
+static int
+sysctl_srvmaxio(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ u_int newsrvmaxio;
+ uint64_t tval;
+
+ newsrvmaxio = nfs_srvmaxio;
+ error = sysctl_handle_int(oidp, &newsrvmaxio, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (newsrvmaxio == nfs_srvmaxio)
+ return (0);
+ if (newsrvmaxio < nfs_srvmaxio) {
+ printf("nfsd: vfs.nfsd.srvmaxio can only be increased\n");
+ return (EINVAL);
+ }
+ if (newsrvmaxio > 1048576) {
+ printf("nfsd: vfs.nfsd.srvmaxio cannot be > 1Mbyte\n");
+ return (EINVAL);
+ }
+ if ((newsrvmaxio & (newsrvmaxio - 1)) != 0) {
+ printf("nfsd: vfs.nfsd.srvmaxio must be a power of 2\n");
+ return (EINVAL);
+ }
+
+ /*
+ * Check that kern.ipc.maxsockbuf is large enough for
+ * newsrviomax, given the setting of vfs.nfs.bufpackets.
+ */
+ if ((newsrvmaxio + NFS_MAXXDR) * nfs_bufpackets >
+ sb_max_adj) {
+ /*
+ * Suggest vfs.nfs.bufpackets * maximum RPC message for
+ * sb_max_adj.
+ */
+ tval = (newsrvmaxio + NFS_MAXXDR) * nfs_bufpackets;
+
+ /*
+ * Convert suggested sb_max_adj value to a suggested
+ * sb_max value, which is what is set via kern.ipc.maxsockbuf.
+ * Perform the inverse calculation of (from uipc_sockbuf.c):
+ * sb_max_adj = (u_quad_t)sb_max * MCLBYTES /
+ * (MSIZE + MCLBYTES);
+ * XXX If the calculation of sb_max_adj from sb_max changes,
+ * this calculation must be changed as well.
+ */
+ tval *= (MSIZE + MCLBYTES); /* Brackets for readability. */
+ tval += MCLBYTES - 1; /* Round up divide. */
+ tval /= MCLBYTES;
+ printf("nfsd: set kern.ipc.maxsockbuf to a minimum of "
+ "%ju to support %ubyte NFS I/O\n", (uintmax_t)tval,
+ newsrvmaxio);
+ return (EINVAL);
+ }
+
+ NFSD_LOCK();
+ if (newnfs_numnfsd != 0) {
+ NFSD_UNLOCK();
+ printf("nfsd: cannot set vfs.nfsd.srvmaxio when nfsd "
+ "threads are running\n");
+ return (EINVAL);
+ }
+
+
+ nfs_srvmaxio = newsrvmaxio;
+ NFSD_UNLOCK();
+ return (0);
+}
+SYSCTL_PROC(_vfs_nfsd, OID_AUTO, srvmaxio,
+ CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RW, NULL, 0,
+ sysctl_srvmaxio, "IU", "Maximum I/O size in bytes");
+
#define MAX_REORDERED_RPC 16
#define NUM_HEURISTIC 1031
#define NHUSE_INIT 64
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -66,6 +66,7 @@
extern int nfsrv_pnfsatime;
extern int nfsrv_maxpnfsmirror;
extern int nfs_maxcopyrange;
+extern uint32_t nfs_srvmaxio;
static int nfs_async = 0;
SYSCTL_DECL(_vfs_nfsd);
@@ -1023,7 +1024,7 @@
lop->lo_end = NFS64BITSSET;
}
- if (retlen > NFS_SRVMAXIO || retlen < 0)
+ if (retlen > nfs_srvmaxio || retlen < 0)
nd->nd_repstat = EIO;
if (vnode_vtype(vp) != VREG && !nd->nd_repstat) {
if (nd->nd_flag & ND_NFSV3)
@@ -4417,6 +4418,7 @@
struct nfsdsession *sep = NULL;
uint32_t rdmacnt;
struct thread *p = curthread;
+ static bool do_printf = true;
if ((nd->nd_repstat = nfsd_checkrootexp(nd)) != 0)
goto nfsmout;
@@ -4438,12 +4440,16 @@
sep->sess_maxreq = fxdr_unsigned(uint32_t, *tl++);
if (sep->sess_maxreq > sb_max_adj - NFS_MAXXDR) {
sep->sess_maxreq = sb_max_adj - NFS_MAXXDR;
- printf("Consider increasing kern.ipc.maxsockbuf\n");
+ if (do_printf)
+ printf("Consider increasing kern.ipc.maxsockbuf\n");
+ do_printf = false;
}
sep->sess_maxresp = fxdr_unsigned(uint32_t, *tl++);
if (sep->sess_maxresp > sb_max_adj - NFS_MAXXDR) {
sep->sess_maxresp = sb_max_adj - NFS_MAXXDR;
- printf("Consider increasing kern.ipc.maxsockbuf\n");
+ if (do_printf)
+ printf("Consider increasing kern.ipc.maxsockbuf\n");
+ do_printf = false;
}
sep->sess_maxrespcached = fxdr_unsigned(uint32_t, *tl++);
sep->sess_maxops = fxdr_unsigned(uint32_t, *tl++);
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -42,6 +42,7 @@
time_t nfsdev_time = 0;
int nfsrv_layouthashsize;
volatile int nfsrv_layoutcnt = 0;
+extern uint32_t nfs_srvmaxio;
extern int newnfs_numnfsd;
extern struct nfsstatsv1 nfsstatsv1;
@@ -6898,7 +6899,7 @@
tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED);
/* Set the stripe size to the maximum I/O size. */
- *tl++ = txdr_unsigned(NFS_SRVMAXIO & NFSFLAYUTIL_STRIPE_MASK);
+ *tl++ = txdr_unsigned(nfs_srvmaxio & NFSFLAYUTIL_STRIPE_MASK);
*tl++ = 0; /* 1st stripe index. */
pattern_offset = 0;
txdr_hyper(pattern_offset, tl); tl += 2; /* Pattern offset. */
@@ -7964,13 +7965,13 @@
*tl++ = txdr_unsigned(2); /* Two NFS Versions. */
*tl++ = txdr_unsigned(NFS_VER4); /* NFSv4. */
*tl++ = txdr_unsigned(NFSV42_MINORVERSION); /* Minor version 2. */
- *tl++ = txdr_unsigned(NFS_SRVMAXIO); /* DS max rsize. */
- *tl++ = txdr_unsigned(NFS_SRVMAXIO); /* DS max wsize. */
+ *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max rsize. */
+ *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max wsize. */
*tl++ = newnfs_true; /* Tightly coupled. */
*tl++ = txdr_unsigned(NFS_VER4); /* NFSv4. */
*tl++ = txdr_unsigned(NFSV41_MINORVERSION); /* Minor version 1. */
- *tl++ = txdr_unsigned(NFS_SRVMAXIO); /* DS max rsize. */
- *tl++ = txdr_unsigned(NFS_SRVMAXIO); /* DS max wsize. */
+ *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max rsize. */
+ *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max wsize. */
*tl = newnfs_true; /* Tightly coupled. */
ds->nfsdev_hostnamelen = strlen(dnshost);

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 26, 9:51 AM (11 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15603541
Default Alt Text
D30826.diff (8 KB)

Event Timeline