aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2021-09-08 00:35:26 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2021-09-08 00:35:26 +0000
commitc5128c48df3c2f3828432aff2ea536bb9c887e14 (patch)
tree0b1dfc203211a484377625d65109ecbd5d047b7a /sys/kern/vfs_vnops.c
parent92de737996660b70376a8b72b80037f89d876056 (diff)
downloadsrc-c5128c48df3c2f3828432aff2ea536bb9c887e14.tar.gz
src-c5128c48df3c2f3828432aff2ea536bb9c887e14.zip
VOP_COPY_FILE_RANGE: Add a COPY_FILE_RANGE_TIMEO1SEC flag
Although it is not specified in the RFCs, the concept that the NFSv4 server should reply to an RPC request within a reasonable time is accepted practice within the NFSv4 community. Without this patch, the NFSv4.2 server attempts to reply to a Copy operation within 1second by limiting the copy to vfs.nfs.maxcopyrange bytes (default 10Mbytes). This is crude at best, given the large variation in I/O subsystem performance. This patch adds a kernel only flag COPY_FILE_RANGE_TIMEO1SEC that the NFSv4.2 can specify, which tells VOP_COPY_FILE_RANGE() to return after approximately 1 second with a partial result and implements this in vn_generic_copy_file_range(), used by vop_stdcopyfilerange(). Modifying the NFSv4.2 server to set this flag will be done in a separate patch. Also under consideration is exposing the COPY_FILE_RANGE_TIMEO1SEC to userland for use on the FreeBSD copy_file_range(2) syscall. MFC after: 2 weeks Reviewed by: khng Differential Revision: https://reviews.freebsd.org/D31829
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r--sys/kern/vfs_vnops.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index bf1270dc8ad8..93d5a9e6b127 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3162,6 +3162,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
size_t copylen, len, rem, savlen;
char *dat;
long holein, holeout;
+ struct timespec curts, endts;
holein = holeout = 0;
savlen = len = *lenp;
@@ -3258,7 +3259,15 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
* in the inner loop where the data copying is done.
* Note that some file systems such as NFSv3, NFSv4.0 and NFSv4.1 may
* support holes on the server, but do not support FIOSEEKHOLE.
+ * The kernel flag COPY_FILE_RANGE_TIMEO1SEC is used to indicate
+ * that this function should return after 1second with a partial
+ * completion.
*/
+ if ((flags & COPY_FILE_RANGE_TIMEO1SEC) != 0) {
+ getnanouptime(&endts);
+ endts.tv_sec++;
+ } else
+ timespecclear(&endts);
holetoeof = eof = false;
while (len > 0 && error == 0 && !eof && interrupted == 0) {
endoff = 0; /* To shut up compilers. */
@@ -3327,8 +3336,17 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
*inoffp += xfer;
*outoffp += xfer;
len -= xfer;
- if (len < savlen)
+ if (len < savlen) {
interrupted = sig_intr();
+ if (timespecisset(&endts) &&
+ interrupted == 0) {
+ getnanouptime(&curts);
+ if (timespeccmp(&curts,
+ &endts, >=))
+ interrupted =
+ EINTR;
+ }
+ }
}
}
copylen = MIN(len, endoff - startoff);
@@ -3391,8 +3409,17 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
*outoffp += xfer;
copylen -= xfer;
len -= xfer;
- if (len < savlen)
+ if (len < savlen) {
interrupted = sig_intr();
+ if (timespecisset(&endts) &&
+ interrupted == 0) {
+ getnanouptime(&curts);
+ if (timespeccmp(&curts,
+ &endts, >=))
+ interrupted =
+ EINTR;
+ }
+ }
}
}
xfer = blksize;