The branch main has been updated by rmacklem:

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

commit c5128c48df3c2f3828432aff2ea536bb9c887e14
Author:     Rick Macklem <[email protected]>
AuthorDate: 2021-09-08 00:35:26 +0000
Commit:     Rick Macklem <[email protected]>
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.
  */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "[email protected]"

Reply via email to