[prev in list] [next in list] [prev in thread] [next in thread] 

List:       glibc-cvs
Subject:    GNU C Library master sources branch master updated. glibc-2.28.9000-109-g81b9d87
From:       hjl () sourceware ! org
Date:       2018-08-31 20:26:22
Message-ID: 20180831202622.35318.qmail () sourceware ! org
[Download RAW message or body]

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  81b9d87bae23efc42e2121ac066fe38fceb96124 (commit)
      from  d330f31af68f96dde82840d1e9343b479a8c179e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=81b9d87bae23efc42e2121ac066fe38fceb96124

commit 81b9d87bae23efc42e2121ac066fe38fceb96124
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Aug 31 13:07:47 2018 -0700

    test-container: Use xcopy_file_range for cross-device copy [BZ #23597]
    
    copy_file_range can't be used to copy a file from glibc source directory
    to glibc build directory since they may be on different filesystems.
    This patch adds xcopy_file_range for cross-device copy.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    
    	[BZ #23597]
    	* support/Makefile (libsupport-routines): Add
    	support_copy_file_range and xcopy_file_range.
    	* support/support.h: Include <sys/types.h>.
    	(support_copy_file_range): New prototype.
    	* support/support_copy_file_range.c: New file.  Copied and
    	modified from io/copy_file_range-compat.c.
    	* support/test-container.c (copy_one_file): Call xcopy_file_rang
    	instead of copy_file_range.
    	* support/xcopy_file_range.c: New file.
    	* support/xunistd.h (xcopy_file_range): New prototype.

diff --git a/ChangeLog b/ChangeLog
index 21d9141..5288a7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2018-08-31  H.J. Lu  <hongjiu.lu@intel.com>
+
+	[BZ #23597]
+	* support/Makefile (libsupport-routines): Add
+	support_copy_file_range and xcopy_file_range.
+	* support/support.h: Include <sys/types.h>.
+	(support_copy_file_range): New prototype.
+	* support/support_copy_file_range.c: New file.  Copied and
+	modified from io/copy_file_range-compat.c.
+	* support/test-container.c (copy_one_file): Call xcopy_file_rang
+	instead of copy_file_range.
+	* support/xcopy_file_range.c: New file.
+	* support/xunistd.h (xcopy_file_range): New prototype.
+
 2018-08-30  Carlos O'Donell  <carlos@redhat.com>
 
 	* elf/tst-dlopen-aout.c: Include support/xthread.h. Use
diff --git a/support/Makefile b/support/Makefile
index b528f53..545bfa2 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -43,6 +43,7 @@ libsupport-routines = \
   support_capture_subprocess \
   support_capture_subprocess_check \
   support_chroot \
+  support_copy_file_range \
   support_descriptor_supports_holes \
   support_enter_mount_namespace \
   support_enter_network_namespace \
@@ -74,6 +75,7 @@ libsupport-routines = \
   xchroot \
   xclose \
   xconnect \
+  xcopy_file_range \
   xdlfcn \
   xdup2 \
   xfclose \
diff --git a/support/support.h b/support/support.h
index c6ff4ba..d0e15bc 100644
--- a/support/support.h
+++ b/support/support.h
@@ -27,6 +27,8 @@
 #include <sys/cdefs.h>
 /* For mode_t.  */
 #include <sys/stat.h>
+/* For ssize_t and off64_t.  */
+#include <sys/types.h>
 
 __BEGIN_DECLS
 
@@ -94,6 +96,9 @@ extern const char support_install_prefix[];
 /* Corresponds to the install's lib/ or lib64/ directory.  */
 extern const char support_libdir_prefix[];
 
+extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
+					size_t, unsigned int);
+
 __END_DECLS
 
 #endif /* SUPPORT_H */
diff --git a/support/support_copy_file_range.c b/support/support_copy_file_range.c
new file mode 100644
index 0000000..9a1e397
--- /dev/null
+++ b/support/support_copy_file_range.c
@@ -0,0 +1,143 @@
+/* Simplified copy_file_range with cross-device copy.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <support/support.h>
+
+ssize_t
+support_copy_file_range (int infd, __off64_t *pinoff,
+			 int outfd, __off64_t *poutoff,
+			 size_t length, unsigned int flags)
+{
+  if (flags != 0)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  struct stat64 instat;
+  struct stat64 outstat;
+  if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0)
+    return -1;
+  if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode))
+    {
+      errno = EISDIR;
+      return -1;
+    }
+  if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode))
+    {
+      /* We need a regular input file so that the we can seek
+	 backwards in case of a write failure.  */
+      errno = EINVAL;
+      return -1;
+    }
+
+  /* The output descriptor must not have O_APPEND set.  */
+  if (fcntl (outfd, F_GETFL) & O_APPEND)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* Avoid an overflow in the result.  */
+  if (length > SSIZE_MAX)
+    length = SSIZE_MAX;
+
+  /* Main copying loop.  The buffer size is arbitrary and is a
+     trade-off between stack size consumption, cache usage, and
+     amortization of system call overhead.  */
+  size_t copied = 0;
+  char buf[8192];
+  while (length > 0)
+    {
+      size_t to_read = length;
+      if (to_read > sizeof (buf))
+	to_read = sizeof (buf);
+
+      /* Fill the buffer.  */
+      ssize_t read_count;
+      if (pinoff == NULL)
+	read_count = read (infd, buf, to_read);
+      else
+	read_count = pread64 (infd, buf, to_read, *pinoff);
+      if (read_count == 0)
+	/* End of file reached prematurely.  */
+	return copied;
+      if (read_count < 0)
+	{
+	  if (copied > 0)
+	    /* Report the number of bytes copied so far.  */
+	    return copied;
+	  return -1;
+	}
+      if (pinoff != NULL)
+	*pinoff += read_count;
+
+      /* Write the buffer part which was read to the destination.  */
+      char *end = buf + read_count;
+      for (char *p = buf; p < end; )
+	{
+	  ssize_t write_count;
+	  if (poutoff == NULL)
+	    write_count = write (outfd, p, end - p);
+	  else
+	    write_count = pwrite64 (outfd, p, end - p, *poutoff);
+	  if (write_count < 0)
+	    {
+	      /* Adjust the input read position to match what we have
+		 written, so that the caller can pick up after the
+		 error.  */
+	      size_t written = p - buf;
+	      /* NB: This needs to be signed so that we can form the
+		 negative value below.  */
+	      ssize_t overread = read_count - written;
+	      if (pinoff == NULL)
+		{
+		  if (overread > 0)
+		    {
+		      /* We are on an error recovery path, so we
+			 cannot deal with failure here.  */
+		      int save_errno = errno;
+		      (void) lseek64 (infd, -overread, SEEK_CUR);
+		      errno = save_errno;
+		    }
+		}
+	      else /* pinoff != NULL */
+		*pinoff -= overread;
+
+	      if (copied + written > 0)
+		/* Report the number of bytes copied so far.  */
+		return copied + written;
+	      return -1;
+	    }
+	  p += write_count;
+	  if (poutoff != NULL)
+	    *poutoff += write_count;
+	} /* Write loop.  */
+
+      copied += read_count;
+      length -= read_count;
+    }
+  return copied;
+}
diff --git a/support/test-container.c b/support/test-container.c
index 2e91bdf..c56b53e 100644
--- a/support/test-container.c
+++ b/support/test-container.c
@@ -383,8 +383,7 @@ copy_one_file (const char *sname, const char *dname)
   if (dfd < 0)
     FAIL_EXIT1 ("unable to open %s for writing\n", dname);
 
-  if (copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size)
-    FAIL_EXIT1 ("cannot copy file %s to %s\n", sname, dname);
+  xcopy_file_range (sfd, 0, dfd, 0, st.st_size, 0);
 
   xclose (sfd);
   xclose (dfd);
diff --git a/support/xcopy_file_range.c b/support/xcopy_file_range.c
new file mode 100644
index 0000000..b3501a4
--- /dev/null
+++ b/support/xcopy_file_range.c
@@ -0,0 +1,32 @@
+/* copy_file_range with error checking.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/support.h>
+#include <support/xunistd.h>
+#include <support/check.h>
+
+ssize_t
+xcopy_file_range (int infd, off64_t *pinoff, int outfd, off64_t *poutoff,
+		  size_t length, unsigned int flags)
+{
+  ssize_t status = support_copy_file_range (infd, pinoff, outfd,
+					    poutoff, length, flags);
+  if (status == -1)
+    FAIL_EXIT1 ("cannot copy file: %m\n");
+  return status;
+}
diff --git a/support/xunistd.h b/support/xunistd.h
index cdd4e8d..f99f362 100644
--- a/support/xunistd.h
+++ b/support/xunistd.h
@@ -64,6 +64,9 @@ void *xmmap (void *addr, size_t length, int prot, int flags, int fd);
 void xmprotect (void *addr, size_t length, int prot);
 void xmunmap (void *addr, size_t length);
 
+ssize_t xcopy_file_range(int fd_in, loff_t *off_in, int fd_out,
+			 loff_t *off_out, size_t len, unsigned int flags);
+
 __END_DECLS
 
 #endif /* SUPPORT_XUNISTD_H */

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   14 ++
 support/Makefile                                   |    2 +
 support/support.h                                  |    5 +
 support/support_copy_file_range.c                  |  143 ++++++++++++++++++++
 support/test-container.c                           |    3 +-
 .../xcopy_file_range.c                             |   28 ++---
 support/xunistd.h                                  |    3 +
 7 files changed, 179 insertions(+), 19 deletions(-)
 create mode 100644 support/support_copy_file_range.c
 copy elf/tst-absolute-zero.c => support/xcopy_file_range.c (69%)


hooks/post-receive
-- 
GNU C Library master sources
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic