Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Sep 2021 00:38:59 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: c5128c48df3c - main - VOP_COPY_FILE_RANGE: Add a COPY_FILE_RANGE_TIMEO1SEC flag
Message-ID:  <202109080038.1880cxvH090720@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=c5128c48df3c2f3828432aff2ea536bb9c887e14

commit c5128c48df3c2f3828432aff2ea536bb9c887e14
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-09-08 00:35:26 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-09-08 00:35:26 +0000

    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
---
 sys/kern/vfs_vnops.c | 31 +++++++++++++++++++++++++++++--
 sys/sys/vnode.h      |  4 ++++
 2 files changed, 33 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;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 61c6a13010f6..81f3f3d5489c 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -616,6 +616,10 @@ typedef void vop_getpages_iodone_t(void *, vm_page_t *, int, int);
 #define	VN_OPEN_NAMECACHE	0x00000004
 #define	VN_OPEN_INVFS		0x00000008
 
+/* copy_file_range kernel flags */
+#define	COPY_FILE_RANGE_KFLAGS		0xff000000
+#define	COPY_FILE_RANGE_TIMEO1SEC	0x01000000	/* Return after 1sec. */
+
 /*
  * Public vnode manipulation functions.
  */



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