svn commit: r366303 - head/sys/fs/nfsclient

Rick Macklem rmacklem at FreeBSD.org
Thu Oct 1 00:47:36 UTC 2020


Author: rmacklem
Date: Thu Oct  1 00:47:35 2020
New Revision: 366303
URL: https://svnweb.freebsd.org/changeset/base/366303

Log:
  Modify the NFSv4.2 VOP_COPY_FILE_RANGE() client call to return after one
  successful RPC.
  
  Without this patch, the NFSv4.2 VOP_COPY_FILE_RANGE() client call would
  loop until the copy "len" was completed.  The problem with doing this is
  that it might take a considerable time to complete for a large "len".
  By returning after a single successful Copy RPC that copied some of the
  data, the application that did the copy_file_range(2) syscall will be
  more responsive to signal delivery for large "len" copies.

Modified:
  head/sys/fs/nfsclient/nfs_clvnops.c

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c	Thu Oct  1 00:33:44 2020	(r366302)
+++ head/sys/fs/nfsclient/nfs_clvnops.c	Thu Oct  1 00:47:35 2020	(r366303)
@@ -3638,7 +3638,7 @@ nfs_copy_file_range(struct vop_copy_file_range_args *a
 	struct vattr *vap;
 	struct uio io;
 	struct nfsmount *nmp;
-	size_t len, len2, copiedlen;
+	size_t len, len2;
 	int error, inattrflag, outattrflag, ret, ret2;
 	off_t inoff, outoff;
 	bool consecutive, must_commit, tryoutcred;
@@ -3731,7 +3731,11 @@ nfs_copy_file_range(struct vop_copy_file_range_args *a
 		} else
 			error = 0;
 	}
-	copiedlen = 0;
+
+	/*
+	 * len will be set to 0 upon a successful Copy RPC.
+	 * As such, this only loops when the Copy RPC needs to be retried.
+	 */
 	while (len > 0 && error == 0) {
 		inattrflag = outattrflag = 0;
 		len2 = len;
@@ -3761,18 +3765,9 @@ nfs_copy_file_range(struct vop_copy_file_range_args *a
 				} else
 					error = NFSERR_OFFLOADNOREQS;
 			}
-			/*
-			 * If the Copy returns a length == 0, it hit the
-			 * EOF on the input file.
-			 */
-			if (len2 == 0) {
-				*ap->a_lenp = copiedlen;
-				len = 0;
-			} else {
-				len -= len2;
-				copiedlen += len2;
-			}
-			if (len == 0 && must_commit && error == 0)
+			*ap->a_lenp = len2;
+			len = 0;
+			if (len2 > 0 && must_commit && error == 0)
 				error = ncl_commit(outvp, outoff, *ap->a_lenp,
 				    ap->a_outcred, curthread);
 			if (error == 0 && ret != 0)
@@ -3783,6 +3778,9 @@ nfs_copy_file_range(struct vop_copy_file_range_args *a
 			/*
 			 * Try consecutive == false, which is ok only if all
 			 * bytes are copied.
+			 * If only some bytes were copied when consecutive
+			 * is false, there is no way to know which bytes
+			 * still need to be written.
 			 */
 			consecutive = false;
 			error = 0;


More information about the svn-src-all mailing list