git: ad6dc3652023 - main - nfscl: Use vfs.nfs.maxalloclen to limit Deallocate RPC RTT

Rick Macklem rmacklem at FreeBSD.org
Sat Sep 18 21:41:56 UTC 2021


The branch main has been updated by rmacklem:

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

commit ad6dc365202390edffb14d725155e230b96f59ae
Author:     Rick Macklem <rmacklem at FreeBSD.org>
AuthorDate: 2021-09-18 21:38:43 +0000
Commit:     Rick Macklem <rmacklem at FreeBSD.org>
CommitDate: 2021-09-18 21:38:43 +0000

    nfscl: Use vfs.nfs.maxalloclen to limit Deallocate RPC RTT
    
    Unlike Copy, the NFSv4.2 Allocate and Deallocate operations do 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/deallocation in the NFSv4.2
    client.
    
    This patch uses the sysctl vfs.nfs.maxalloclen to set
    the limit on the size of the Deallocate operation.
    There is no way to know how long a server will take to do an
    deallocate operation, but 64Mbytes results in a reasonable
    RPC RTT for the slow hardware I test on.
    
    For an 8Gbyte deallocation, the elapsed time for doing it in 64Mbyte
    chunks was the same (within margin of variability) as the
    elapsed time taken for a single large deallocation
    operation for a FreeBSD server with a UFS file system.
---
 sys/fs/nfsclient/nfs_clvnops.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 85b5dd9cfbb1..0b60100d1fc9 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3702,12 +3702,15 @@ nfs_deallocate(struct vop_deallocate_args *ap)
 	struct thread *td = curthread;
 	struct nfsvattr nfsva;
 	struct nfsmount *nmp;
-	off_t tlen;
+	struct nfsnode *np;
+	off_t tlen, mlen;
 	int attrflag, error, ret;
+	bool clipped;
 
 	error = 0;
 	attrflag = 0;
 	nmp = VFSTONFS(vp->v_mount);
+	np = VTONFS(vp);
 	mtx_lock(&nmp->nm_mtx);
 	if (NFSHASNFSV4(nmp) && nmp->nm_minorvers >= NFSV42_MINORVERSION &&
 	    (nmp->nm_privflag & NFSMNTP_NODEALLOCATE) == 0) {
@@ -3721,8 +3724,18 @@ nfs_deallocate(struct vop_deallocate_args *ap)
 			*ap->a_len = 0;
 			return (0);
 		}
+		clipped = false;
 		if ((uint64_t)*ap->a_offset + tlen > nmp->nm_maxfilesize)
 			tlen = nmp->nm_maxfilesize - *ap->a_offset;
+		if ((uint64_t)*ap->a_offset < np->n_size) {
+			/* Limit the len to nfs_maxalloclen before EOF. */
+			mlen = omin((off_t)np->n_size - *ap->a_offset, tlen);
+			if ((uint64_t)mlen > nfs_maxalloclen) {
+				NFSCL_DEBUG(4, "dealloc: tlen maxalloclen\n");
+				tlen = nfs_maxalloclen;
+				clipped = true;
+			}
+		}
 		if (error == 0)
 			error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
 		if (error == 0) {
@@ -3741,7 +3754,10 @@ nfs_deallocate(struct vop_deallocate_args *ap)
 					    nfsva.na_size - *ap->a_offset,
 					    tlen);
 			}
-			*ap->a_len = 0;
+			if (clipped && tlen < *ap->a_len)
+				*ap->a_len -= tlen;
+			else
+				*ap->a_len = 0;
 		} else if (error == NFSERR_NOTSUPP) {
 			mtx_lock(&nmp->nm_mtx);
 			nmp->nm_privflag |= NFSMNTP_NODEALLOCATE;


More information about the dev-commits-src-main mailing list