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.
This commit is contained in:
parent
7b2ac8eb9b
commit
ad6dc36520
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user