Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Oct 2021 23:03:57 GMT
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 263a7cc1379f - stable/13 - nfscl: Add vfs.nfs.maxalloclen to limit Allocate RPC RTT
Message-ID:  <202110032303.193N3vKi035087@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=263a7cc1379f5b8afb8781f365db76736b9222de

commit 263a7cc1379f5b8afb8781f365db76736b9222de
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-09-16 00:29:45 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-10-03 22:58:59 +0000

    nfscl: Add vfs.nfs.maxalloclen to limit Allocate RPC RTT
    
    Unlike Copy, the NFSv4.2 Allocate operation does not
    allow a reply with partial completion.  As such, the only way to
    limit the time the operation takes to provide a reasonable RPC RTT
    is to limit the size of the allocation in the NFSv4.2
    client.
    
    This patch adds a sysctl called vfs.nfs.maxalloclen to set
    the limit on the size of the Allocate operation.
    There is no way to know how long a server will take to do an
    allocate operation, but 64Mbytes results in a reasonable
    RPC RTT for the slow hardware I test on, so that is what
    the default value for vfs.nfs.maxalloclen is set to.
    
    For an 8Gbyte allocation, the elapsed time for doing it in 64Mbyte
    chunks was the same as the elapsed time taken for a single large
    allocation operation for a FreeBSD server with a UFS file system.
    
    (cherry picked from commit 9ebe4b8c67bf823e62617ba9fbd3c9c1768c8b3b)
---
 sys/fs/nfsclient/nfs_clvnops.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 72d9eac8e962..29b0cdce4bbc 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -299,6 +299,10 @@ int newnfs_directio_allow_mmap = 1;
 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW,
 	   &newnfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens");
 
+static uint64_t	nfs_maxalloclen = 64 * 1024 * 1024;
+SYSCTL_U64(_vfs_nfs, OID_AUTO, maxalloclen, CTLFLAG_RW,
+	   &nfs_maxalloclen, 0, "NFS max allocate/deallocate length");
+
 #define	NFSACCESS_ALL (NFSACCESS_READ | NFSACCESS_MODIFY		\
 			 | NFSACCESS_EXTEND | NFSACCESS_EXECUTE	\
 			 | NFSACCESS_DELETE | NFSACCESS_LOOKUP)
@@ -3617,6 +3621,7 @@ nfs_allocate(struct vop_allocate_args *ap)
 	struct thread *td = curthread;
 	struct nfsvattr nfsva;
 	struct nfsmount *nmp;
+	off_t alen;
 	int attrflag, error, ret;
 
 	attrflag = 0;
@@ -3630,12 +3635,16 @@ nfs_allocate(struct vop_allocate_args *ap)
 		 * file's allocation on the server.
 		 */
 		error = ncl_flush(vp, MNT_WAIT, td, 1, 0);
-		if (error == 0)
-			error = nfsrpc_allocate(vp, *ap->a_offset, *ap->a_len,
+		if (error == 0) {
+			alen = *ap->a_len;
+			if ((uint64_t)alen > nfs_maxalloclen)
+				alen = nfs_maxalloclen;
+			error = nfsrpc_allocate(vp, *ap->a_offset, alen,
 			    &nfsva, &attrflag, td->td_ucred, td, NULL);
+		}
 		if (error == 0) {
-			*ap->a_offset += *ap->a_len;
-			*ap->a_len = 0;
+			*ap->a_offset += alen;
+			*ap->a_len -= alen;
 		} else if (error == NFSERR_NOTSUPP) {
 			mtx_lock(&nmp->nm_mtx);
 			nmp->nm_privflag |= NFSMNTP_NOALLOCATE;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202110032303.193N3vKi035087>