Date: Sat, 18 Sep 2021 21:41:55 GMT From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: ad6dc3652023 - main - nfscl: Use vfs.nfs.maxalloclen to limit Deallocate RPC RTT Message-ID: <202109182141.18ILftR3080044@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=ad6dc365202390edffb14d725155e230b96f59ae commit ad6dc365202390edffb14d725155e230b96f59ae Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2021-09-18 21:38:43 +0000 Commit: Rick Macklem <rmacklem@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109182141.18ILftR3080044>