d8307d
commit 5a659ccc0ec217ab02a4c273a1f6d346a359560a
d8307d
Author: Florian Weimer <fweimer@redhat.com>
d8307d
Date:   Fri Jun 28 09:39:21 2019 +0200
d8307d
d8307d
    io: Remove copy_file_range emulation [BZ #24744]
d8307d
    
d8307d
    The kernel is evolving this interface (e.g., removal of the
d8307d
    restriction on cross-device copies), and keeping up with that
d8307d
    is difficult.  Applications which need the function should
d8307d
    run kernels which support the system call instead of relying on
d8307d
    the imperfect glibc emulation.
d8307d
    
d8307d
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
d8307d
d8307d
# Conflicts:
d8307d
#	io/copy_file_range-compat.c
d8307d
#	io/copy_file_range.c
d8307d
#	io/tst-copy_file_range-compat.c
d8307d
#	io/tst-copy_file_range.c
d8307d
#	sysdeps/unix/sysv/linux/arm/kernel-features.h
d8307d
#	sysdeps/unix/sysv/linux/microblaze/kernel-features.h
d8307d
#	sysdeps/unix/sysv/linux/sh/kernel-features.h
d8307d
d8307d
diff --git a/io/Makefile b/io/Makefile
d8307d
index 787a5c550ab64b17..62e71b4cbe879dbc 100644
d8307d
--- a/io/Makefile
d8307d
+++ b/io/Makefile
d8307d
@@ -75,11 +75,6 @@ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
d8307d
 		   tst-fts tst-fts-lfs tst-open-tmpfile \
d8307d
 		   tst-copy_file_range tst-getcwd-abspath \
d8307d
 
d8307d
-# This test includes the compat implementation of copy_file_range,
d8307d
-# which uses internal, unexported libc functions.
d8307d
-tests-static += tst-copy_file_range-compat
d8307d
-tests-internal += tst-copy_file_range-compat
d8307d
-
d8307d
 # Likewise for statx, but we do not need static linking here.
d8307d
 tests-internal += tst-statx
d8307d
 
d8307d
diff --git a/io/copy_file_range-compat.c b/io/copy_file_range-compat.c
d8307d
deleted file mode 100644
d8307d
index 4ab22cad19146ca9..0000000000000000
d8307d
--- a/io/copy_file_range-compat.c
d8307d
+++ /dev/null
d8307d
@@ -1,160 +0,0 @@
d8307d
-/* Emulation of copy_file_range.
d8307d
-   Copyright (C) 2017-2018 Free Software Foundation, Inc.
d8307d
-   This file is part of the GNU C Library.
d8307d
-
d8307d
-   The GNU C Library is free software; you can redistribute it and/or
d8307d
-   modify it under the terms of the GNU Lesser General Public
d8307d
-   License as published by the Free Software Foundation; either
d8307d
-   version 2.1 of the License, or (at your option) any later version.
d8307d
-
d8307d
-   The GNU C Library is distributed in the hope that it will be useful,
d8307d
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
d8307d
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
d8307d
-   Lesser General Public License for more details.
d8307d
-
d8307d
-   You should have received a copy of the GNU Lesser General Public
d8307d
-   License along with the GNU C Library; if not, see
d8307d
-   <http://www.gnu.org/licenses/>.  */
d8307d
-
d8307d
-/* The following macros should be defined before including this
d8307d
-   file:
d8307d
-
d8307d
-   COPY_FILE_RANGE_DECL   Declaration specifiers for the function below.
d8307d
-   COPY_FILE_RANGE        Name of the function to define.  */
d8307d
-
d8307d
-#include <errno.h>
d8307d
-#include <fcntl.h>
d8307d
-#include <inttypes.h>
d8307d
-#include <limits.h>
d8307d
-#include <sys/stat.h>
d8307d
-#include <sys/types.h>
d8307d
-#include <unistd.h>
d8307d
-
d8307d
-COPY_FILE_RANGE_DECL
d8307d
-ssize_t
d8307d
-COPY_FILE_RANGE (int infd, __off64_t *pinoff,
d8307d
-                 int outfd, __off64_t *poutoff,
d8307d
-                 size_t length, unsigned int flags)
d8307d
-{
d8307d
-  if (flags != 0)
d8307d
-    {
d8307d
-      __set_errno (EINVAL);
d8307d
-      return -1;
d8307d
-    }
d8307d
-
d8307d
-  {
d8307d
-    struct stat64 instat;
d8307d
-    struct stat64 outstat;
d8307d
-    if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0)
d8307d
-      return -1;
d8307d
-    if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode))
d8307d
-      {
d8307d
-        __set_errno (EISDIR);
d8307d
-        return -1;
d8307d
-      }
d8307d
-    if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode))
d8307d
-      {
d8307d
-        /* We need a regular input file so that the we can seek
d8307d
-           backwards in case of a write failure.  */
d8307d
-        __set_errno (EINVAL);
d8307d
-        return -1;
d8307d
-      }
d8307d
-    if (instat.st_dev != outstat.st_dev)
d8307d
-      {
d8307d
-        /* Cross-device copies are not supported.  */
d8307d
-        __set_errno (EXDEV);
d8307d
-        return -1;
d8307d
-      }
d8307d
-  }
d8307d
-
d8307d
-  /* The output descriptor must not have O_APPEND set.  */
d8307d
-  {
d8307d
-    int flags = __fcntl (outfd, F_GETFL);
d8307d
-    if (flags & O_APPEND)
d8307d
-      {
d8307d
-        __set_errno (EBADF);
d8307d
-        return -1;
d8307d
-      }
d8307d
-  }
d8307d
-
d8307d
-  /* Avoid an overflow in the result.  */
d8307d
-  if (length > SSIZE_MAX)
d8307d
-    length = SSIZE_MAX;
d8307d
-
d8307d
-  /* Main copying loop.  The buffer size is arbitrary and is a
d8307d
-     trade-off between stack size consumption, cache usage, and
d8307d
-     amortization of system call overhead.  */
d8307d
-  size_t copied = 0;
d8307d
-  char buf[8192];
d8307d
-  while (length > 0)
d8307d
-    {
d8307d
-      size_t to_read = length;
d8307d
-      if (to_read > sizeof (buf))
d8307d
-        to_read = sizeof (buf);
d8307d
-
d8307d
-      /* Fill the buffer.  */
d8307d
-      ssize_t read_count;
d8307d
-      if (pinoff == NULL)
d8307d
-        read_count = read (infd, buf, to_read);
d8307d
-      else
d8307d
-        read_count = __libc_pread64 (infd, buf, to_read, *pinoff);
d8307d
-      if (read_count == 0)
d8307d
-        /* End of file reached prematurely.  */
d8307d
-        return copied;
d8307d
-      if (read_count < 0)
d8307d
-        {
d8307d
-          if (copied > 0)
d8307d
-            /* Report the number of bytes copied so far.  */
d8307d
-            return copied;
d8307d
-          return -1;
d8307d
-        }
d8307d
-      if (pinoff != NULL)
d8307d
-        *pinoff += read_count;
d8307d
-
d8307d
-      /* Write the buffer part which was read to the destination.  */
d8307d
-      char *end = buf + read_count;
d8307d
-      for (char *p = buf; p < end; )
d8307d
-        {
d8307d
-          ssize_t write_count;
d8307d
-          if (poutoff == NULL)
d8307d
-            write_count = write (outfd, p, end - p);
d8307d
-          else
d8307d
-            write_count = __libc_pwrite64 (outfd, p, end - p, *poutoff);
d8307d
-          if (write_count < 0)
d8307d
-            {
d8307d
-              /* Adjust the input read position to match what we have
d8307d
-                 written, so that the caller can pick up after the
d8307d
-                 error.  */
d8307d
-              size_t written = p - buf;
d8307d
-              /* NB: This needs to be signed so that we can form the
d8307d
-                 negative value below.  */
d8307d
-              ssize_t overread = read_count - written;
d8307d
-              if (pinoff == NULL)
d8307d
-                {
d8307d
-                  if (overread > 0)
d8307d
-                    {
d8307d
-                      /* We are on an error recovery path, so we
d8307d
-                         cannot deal with failure here.  */
d8307d
-                      int save_errno = errno;
d8307d
-                      (void) __libc_lseek64 (infd, -overread, SEEK_CUR);
d8307d
-                      __set_errno (save_errno);
d8307d
-                    }
d8307d
-                }
d8307d
-              else /* pinoff != NULL */
d8307d
-                *pinoff -= overread;
d8307d
-
d8307d
-              if (copied + written > 0)
d8307d
-                /* Report the number of bytes copied so far.  */
d8307d
-                return copied + written;
d8307d
-              return -1;
d8307d
-            }
d8307d
-          p += write_count;
d8307d
-          if (poutoff != NULL)
d8307d
-            *poutoff += write_count;
d8307d
-        } /* Write loop.  */
d8307d
-
d8307d
-      copied += read_count;
d8307d
-      length -= read_count;
d8307d
-    }
d8307d
-  return copied;
d8307d
-}
d8307d
diff --git a/io/copy_file_range.c b/io/copy_file_range.c
d8307d
index 98bff8bd2615b214..59fb979773b2b202 100644
d8307d
--- a/io/copy_file_range.c
d8307d
+++ b/io/copy_file_range.c
d8307d
@@ -1,5 +1,5 @@
d8307d
-/* Generic implementation of copy_file_range.
d8307d
-   Copyright (C) 2017-2018 Free Software Foundation, Inc.
d8307d
+/* Stub implementation of copy_file_range.
d8307d
+   Copyright (C) 2017-2019 Free Software Foundation, Inc.
d8307d
    This file is part of the GNU C Library.
d8307d
 
d8307d
    The GNU C Library is free software; you can redistribute it and/or
d8307d
@@ -16,7 +16,15 @@
d8307d
    License along with the GNU C Library; if not, see
d8307d
    <http://www.gnu.org/licenses/>.  */
d8307d
 
d8307d
-#define COPY_FILE_RANGE_DECL
d8307d
-#define COPY_FILE_RANGE copy_file_range
d8307d
+#include <errno.h>
d8307d
+#include <unistd.h>
d8307d
 
d8307d
-#include <io/copy_file_range-compat.c>
d8307d
+ssize_t
d8307d
+copy_file_range (int infd, __off64_t *pinoff,
d8307d
+                 int outfd, __off64_t *poutoff,
d8307d
+                 size_t length, unsigned int flags)
d8307d
+{
d8307d
+  __set_errno (ENOSYS);
d8307d
+  return -1;
d8307d
+}
d8307d
+stub_warning (copy_file_range)
d8307d
diff --git a/io/tst-copy_file_range-compat.c b/io/tst-copy_file_range-compat.c
d8307d
deleted file mode 100644
d8307d
index 00c109a74d3c9d64..0000000000000000
d8307d
--- a/io/tst-copy_file_range-compat.c
d8307d
+++ /dev/null
d8307d
@@ -1,30 +0,0 @@
d8307d
-/* Test the fallback implementation of copy_file_range.
d8307d
-   Copyright (C) 2017-2018 Free Software Foundation, Inc.
d8307d
-   This file is part of the GNU C Library.
d8307d
-
d8307d
-   The GNU C Library is free software; you can redistribute it and/or
d8307d
-   modify it under the terms of the GNU Lesser General Public
d8307d
-   License as published by the Free Software Foundation; either
d8307d
-   version 2.1 of the License, or (at your option) any later version.
d8307d
-
d8307d
-   The GNU C Library is distributed in the hope that it will be useful,
d8307d
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
d8307d
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
d8307d
-   Lesser General Public License for more details.
d8307d
-
d8307d
-   You should have received a copy of the GNU Lesser General Public
d8307d
-   License along with the GNU C Library; if not, see
d8307d
-   <http://www.gnu.org/licenses/>.  */
d8307d
-
d8307d
-/* Get the declaration of the official copy_of_range function.  */
d8307d
-#include <unistd.h>
d8307d
-
d8307d
-/* Compile a local version of copy_file_range.  */
d8307d
-#define COPY_FILE_RANGE_DECL static
d8307d
-#define COPY_FILE_RANGE copy_file_range_compat
d8307d
-#include <io/copy_file_range-compat.c>
d8307d
-
d8307d
-/* Re-use the test, but run it against copy_file_range_compat defined
d8307d
-   above.  */
d8307d
-#define copy_file_range copy_file_range_compat
d8307d
-#include "tst-copy_file_range.c"
d8307d
diff --git a/io/tst-copy_file_range.c b/io/tst-copy_file_range.c
d8307d
index 3d531a19370911e5..4504020d2ee7d2ee 100644
d8307d
--- a/io/tst-copy_file_range.c
d8307d
+++ b/io/tst-copy_file_range.c
d8307d
@@ -20,22 +20,15 @@
d8307d
 #include <errno.h>
d8307d
 #include <fcntl.h>
d8307d
 #include <inttypes.h>
d8307d
-#include <libgen.h>
d8307d
-#include <poll.h>
d8307d
-#include <sched.h>
d8307d
 #include <stdbool.h>
d8307d
 #include <stdio.h>
d8307d
 #include <stdlib.h>
d8307d
 #include <string.h>
d8307d
 #include <support/check.h>
d8307d
-#include <support/namespace.h>
d8307d
 #include <support/support.h>
d8307d
 #include <support/temp_file.h>
d8307d
 #include <support/test-driver.h>
d8307d
 #include <support/xunistd.h>
d8307d
-#ifdef CLONE_NEWNS
d8307d
-# include <sys/mount.h>
d8307d
-#endif
d8307d
 
d8307d
 /* Boolean flags which indicate whether to use pointers with explicit
d8307d
    output flags.  */
d8307d
@@ -49,10 +42,6 @@ static int infd;
d8307d
 static char *outfile;
d8307d
 static int outfd;
d8307d
 
d8307d
-/* Like the above, but on a different file system.  xdevfile can be
d8307d
-   NULL if no suitable file system has been found.  */
d8307d
-static char *xdevfile;
d8307d
-
d8307d
 /* Input and output offsets.  Set according to do_inoff and do_outoff
d8307d
    before the test.  The offsets themselves are always set to
d8307d
    zero.  */
d8307d
@@ -61,13 +50,10 @@ static off64_t *pinoff;
d8307d
 static off64_t outoff;
d8307d
 static off64_t *poutoff;
d8307d
 
d8307d
-/* These are a collection of copy sizes used in tests.  The selection
d8307d
-   takes into account that the fallback implementation uses an
d8307d
-   internal buffer of 8192 bytes.  */
d8307d
+/* These are a collection of copy sizes used in tests.    */
d8307d
 enum { maximum_size = 99999 };
d8307d
 static const int typical_sizes[] =
d8307d
-  { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, 16383, 16384, 16385,
d8307d
-    maximum_size };
d8307d
+  { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, maximum_size };
d8307d
 
d8307d
 /* The random contents of this array can be used as a pattern to check
d8307d
    for correct write operations.  */
d8307d
@@ -76,101 +62,6 @@ static unsigned char random_data[maximum_size];
d8307d
 /* The size chosen by the test harness.  */
d8307d
 static int current_size;
d8307d
 
d8307d
-/* Maximum writable file offset.  Updated by find_maximum_offset
d8307d
-   below.  */
d8307d
-static off64_t maximum_offset;
d8307d
-
d8307d
-/* Error code when crossing the offset.  */
d8307d
-static int maximum_offset_errno;
d8307d
-
d8307d
-/* If true: Writes which cross the limit will fail.  If false: Writes
d8307d
-   which cross the limit will result in a partial write.  */
d8307d
-static bool maximum_offset_hard_limit;
d8307d
-
d8307d
-/* Fills maximum_offset etc. above.  Truncates outfd as a side
d8307d
-   effect.  */
d8307d
-static void
d8307d
-find_maximum_offset (void)
d8307d
-{
d8307d
-  xftruncate (outfd, 0);
d8307d
-  if (maximum_offset != 0)
d8307d
-    return;
d8307d
-
d8307d
-  uint64_t upper = -1;
d8307d
-  upper >>= 1;                  /* Maximum of off64_t.  */
d8307d
-  TEST_VERIFY ((off64_t) upper > 0);
d8307d
-  TEST_VERIFY ((off64_t) (upper + 1) < 0);
d8307d
-  if (lseek64 (outfd, upper, SEEK_SET) >= 0)
d8307d
-    {
d8307d
-      if (write (outfd, "", 1) == 1)
d8307d
-        FAIL_EXIT1 ("created a file larger than the off64_t range");
d8307d
-    }
d8307d
-
d8307d
-  uint64_t lower = 1024 * 1024; /* A reasonable minimum file size.  */
d8307d
-  /* Loop invariant: writing at lower succeeds, writing at upper fails.  */
d8307d
-  while (lower + 1 < upper)
d8307d
-    {
d8307d
-      uint64_t middle = (lower + upper) / 2;
d8307d
-      if (test_verbose > 0)
d8307d
-        printf ("info: %s: remaining test range %" PRIu64 " .. %" PRIu64
d8307d
-                ", probe at %" PRIu64 "\n", __func__, lower, upper, middle);
d8307d
-      xftruncate (outfd, 0);
d8307d
-      if (lseek64 (outfd, middle, SEEK_SET) >= 0
d8307d
-          && write (outfd, "", 1) == 1)
d8307d
-        lower = middle;
d8307d
-      else
d8307d
-        upper = middle;
d8307d
-    }
d8307d
-  TEST_VERIFY (lower + 1 == upper);
d8307d
-  maximum_offset = lower;
d8307d
-  printf ("info: maximum writable file offset: %" PRIu64 " (%" PRIx64 ")\n",
d8307d
-          lower, lower);
d8307d
-
d8307d
-  /* Check that writing at the valid offset actually works.  */
d8307d
-  xftruncate (outfd, 0);
d8307d
-  xlseek (outfd, lower, SEEK_SET);
d8307d
-  TEST_COMPARE (write (outfd, "", 1), 1);
d8307d
-
d8307d
-  /* Cross the boundary with a two-byte write.  This can either result
d8307d
-     in a short write, or a failure.  */
d8307d
-  xlseek (outfd, lower, SEEK_SET);
d8307d
-  ssize_t ret = write (outfd, " ", 2);
d8307d
-  if (ret < 0)
d8307d
-    {
d8307d
-      maximum_offset_errno = errno;
d8307d
-      maximum_offset_hard_limit = true;
d8307d
-    }
d8307d
-  else
d8307d
-    maximum_offset_hard_limit = false;
d8307d
-
d8307d
-  /* Check that writing at the next offset actually fails.  This also
d8307d
-     obtains the expected errno value.  */
d8307d
-  xftruncate (outfd, 0);
d8307d
-  const char *action;
d8307d
-  if (lseek64 (outfd, lower + 1, SEEK_SET) != 0)
d8307d
-    {
d8307d
-      if (write (outfd, "", 1) != -1)
d8307d
-        FAIL_EXIT1 ("write to impossible offset %" PRIu64 " succeeded",
d8307d
-                    lower + 1);
d8307d
-      action = "writing";
d8307d
-      int errno_copy = errno;
d8307d
-      if (maximum_offset_hard_limit)
d8307d
-        TEST_COMPARE (errno_copy, maximum_offset_errno);
d8307d
-      else
d8307d
-        maximum_offset_errno = errno_copy;
d8307d
-    }
d8307d
-  else
d8307d
-    {
d8307d
-      action = "seeking";
d8307d
-      maximum_offset_errno = errno;
d8307d
-    }
d8307d
-  printf ("info: %s out of range fails with %m (%d)\n",
d8307d
-          action, maximum_offset_errno);
d8307d
-
d8307d
-  xftruncate (outfd, 0);
d8307d
-  xlseek (outfd, 0, SEEK_SET);
d8307d
-}
d8307d
-
d8307d
 /* Perform a copy of a file.  */
d8307d
 static void
d8307d
 simple_file_copy (void)
d8307d
@@ -247,390 +138,6 @@ simple_file_copy (void)
d8307d
   free (bytes);
d8307d
 }
d8307d
 
d8307d
-/* Test that reading from a pipe willfails.  */
d8307d
-static void
d8307d
-pipe_as_source (void)
d8307d
-{
d8307d
-  int pipefds[2];
d8307d
-  xpipe (pipefds);
d8307d
-
d8307d
-  for (int length = 0; length < 2; ++length)
d8307d
-    {
d8307d
-      if (test_verbose > 0)
d8307d
-        printf ("info: %s: length=%d\n", __func__, length);
d8307d
-
d8307d
-      /* Make sure that there is something to copy in the pipe.  */
d8307d
-      xwrite (pipefds[1], "@", 1);
d8307d
-
d8307d
-      TEST_COMPARE (copy_file_range (pipefds[0], pinoff, outfd, poutoff,
d8307d
-                                     length, 0), -1);
d8307d
-      /* Linux 4.10 and later return EINVAL.  Older kernels return
d8307d
-         EXDEV.  */
d8307d
-      TEST_VERIFY (errno == EINVAL || errno == EXDEV);
d8307d
-      TEST_COMPARE (inoff, 0);
d8307d
-      TEST_COMPARE (outoff, 0);
d8307d
-      TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 0);
d8307d
-
d8307d
-      /* Make sure that nothing was read.  */
d8307d
-      char buf = 'A';
d8307d
-      TEST_COMPARE (read (pipefds[0], &buf, 1), 1);
d8307d
-      TEST_COMPARE (buf, '@');
d8307d
-    }
d8307d
-
d8307d
-  xclose (pipefds[0]);
d8307d
-  xclose (pipefds[1]);
d8307d
-}
d8307d
-
d8307d
-/* Test that writing to a pipe fails.  */
d8307d
-static void
d8307d
-pipe_as_destination (void)
d8307d
-{
d8307d
-  /* Make sure that there is something to read in the input file.  */
d8307d
-  xwrite (infd, "abc", 3);
d8307d
-  xlseek (infd, 0, SEEK_SET);
d8307d
-
d8307d
-  int pipefds[2];
d8307d
-  xpipe (pipefds);
d8307d
-
d8307d
-  for (int length = 0; length < 2; ++length)
d8307d
-    {
d8307d
-      if (test_verbose > 0)
d8307d
-        printf ("info: %s: length=%d\n", __func__, length);
d8307d
-
d8307d
-      TEST_COMPARE (copy_file_range (infd, pinoff, pipefds[1], poutoff,
d8307d
-                                     length, 0), -1);
d8307d
-      /* Linux 4.10 and later return EINVAL.  Older kernels return
d8307d
-         EXDEV.  */
d8307d
-      TEST_VERIFY (errno == EINVAL || errno == EXDEV);
d8307d
-      TEST_COMPARE (inoff, 0);
d8307d
-      TEST_COMPARE (outoff, 0);
d8307d
-      TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
d8307d
-
d8307d
-      /* Make sure that nothing was written.  */
d8307d
-      struct pollfd pollfd = { .fd = pipefds[0], .events = POLLIN, };
d8307d
-      TEST_COMPARE (poll (&pollfd, 1, 0), 0);
d8307d
-    }
d8307d
-
d8307d
-  xclose (pipefds[0]);
d8307d
-  xclose (pipefds[1]);
d8307d
-}
d8307d
-
d8307d
-/* Test a write failure after (potentially) writing some bytes.
d8307d
-   Failure occurs near the start of the buffer.  */
d8307d
-static void
d8307d
-delayed_write_failure_beginning (void)
d8307d
-{
d8307d
-  /* We need to write something to provoke the error.  */
d8307d
-  if (current_size == 0)
d8307d
-    return;
d8307d
-  xwrite (infd, random_data, sizeof (random_data));
d8307d
-  xlseek (infd, 0, SEEK_SET);
d8307d
-
d8307d
-  /* Write failure near the start.  The actual error code varies among
d8307d
-     file systems.  */
d8307d
-  find_maximum_offset ();
d8307d
-  off64_t where = maximum_offset;
d8307d
-
d8307d
-  if (current_size == 1)
d8307d
-    ++where;
d8307d
-  outoff = where;
d8307d
-  if (do_outoff)
d8307d
-    xlseek (outfd, 1, SEEK_SET);
d8307d
-  else
d8307d
-    xlseek (outfd, where, SEEK_SET);
d8307d
-  if (maximum_offset_hard_limit || where > maximum_offset)
d8307d
-    {
d8307d
-      TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
d8307d
-                                     sizeof (random_data), 0), -1);
d8307d
-      TEST_COMPARE (errno, maximum_offset_errno);
d8307d
-      TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
d8307d
-      TEST_COMPARE (inoff, 0);
d8307d
-      if (do_outoff)
d8307d
-        TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1);
d8307d
-      else
d8307d
-        TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where);
d8307d
-      TEST_COMPARE (outoff, where);
d8307d
-      struct stat64 st;
d8307d
-      xfstat (outfd, &st);
d8307d
-      TEST_COMPARE (st.st_size, 0);
d8307d
-    }
d8307d
-  else
d8307d
-    {
d8307d
-      /* The offset is not a hard limit.  This means we write one
d8307d
-         byte.  */
d8307d
-      TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
d8307d
-                                     sizeof (random_data), 0), 1);
d8307d
-      if (do_inoff)
d8307d
-        {
d8307d
-          TEST_COMPARE (inoff, 1);
d8307d
-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
d8307d
-        }
d8307d
-      else
d8307d
-        {
d8307d
-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 1);
d8307d
-          TEST_COMPARE (inoff, 0);
d8307d
-        }
d8307d
-      if (do_outoff)
d8307d
-        {
d8307d
-          TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1);
d8307d
-          TEST_COMPARE (outoff, where + 1);
d8307d
-        }
d8307d
-      else
d8307d
-        {
d8307d
-          TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where + 1);
d8307d
-          TEST_COMPARE (outoff, where);
d8307d
-        }
d8307d
-      struct stat64 st;
d8307d
-      xfstat (outfd, &st);
d8307d
-      TEST_COMPARE (st.st_size, where + 1);
d8307d
-    }
d8307d
-}
d8307d
-
d8307d
-/* Test a write failure after (potentially) writing some bytes.
d8307d
-   Failure occurs near the end of the buffer.  */
d8307d
-static void
d8307d
-delayed_write_failure_end (void)
d8307d
-{
d8307d
-  if (current_size <= 1)
d8307d
-    /* This would be same as the first test because there is not
d8307d
-       enough data to write to make a difference.  */
d8307d
-    return;
d8307d
-  xwrite (infd, random_data, sizeof (random_data));
d8307d
-  xlseek (infd, 0, SEEK_SET);
d8307d
-
d8307d
-  find_maximum_offset ();
d8307d
-  off64_t where = maximum_offset - current_size + 1;
d8307d
-  if (current_size == sizeof (random_data))
d8307d
-    /* Otherwise we do not reach the non-writable byte.  */
d8307d
-    ++where;
d8307d
-  outoff = where;
d8307d
-  if (do_outoff)
d8307d
-    xlseek (outfd, 1, SEEK_SET);
d8307d
-  else
d8307d
-    xlseek (outfd, where, SEEK_SET);
d8307d
-  ssize_t ret = copy_file_range (infd, pinoff, outfd, poutoff,
d8307d
-                                 sizeof (random_data), 0);
d8307d
-  if (ret < 0)
d8307d
-    {
d8307d
-      TEST_COMPARE (ret, -1);
d8307d
-      TEST_COMPARE (errno, maximum_offset_errno);
d8307d
-      struct stat64 st;
d8307d
-      xfstat (outfd, &st);
d8307d
-      TEST_COMPARE (st.st_size, 0);
d8307d
-    }
d8307d
-  else
d8307d
-    {
d8307d
-      /* The first copy succeeded.  This happens in the emulation
d8307d
-         because the internal buffer of limited size does not
d8307d
-         necessarily cross the off64_t boundary on the first write
d8307d
-         operation.  */
d8307d
-      if (test_verbose > 0)
d8307d
-        printf ("info:   copy_file_range (%zu) returned %zd\n",
d8307d
-                sizeof (random_data), ret);
d8307d
-      TEST_VERIFY (ret > 0);
d8307d
-      TEST_VERIFY (ret < maximum_size);
d8307d
-      struct stat64 st;
d8307d
-      xfstat (outfd, &st);
d8307d
-      TEST_COMPARE (st.st_size, where + ret);
d8307d
-      if (do_inoff)
d8307d
-        {
d8307d
-          TEST_COMPARE (inoff, ret);
d8307d
-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
d8307d
-        }
d8307d
-      else
d8307d
-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), ret);
d8307d
-
d8307d
-      char *buffer = xmalloc (ret);
d8307d
-      TEST_COMPARE (pread64 (outfd, buffer, ret, where), ret);
d8307d
-      TEST_VERIFY (memcmp (buffer, random_data, ret) == 0);
d8307d
-      free (buffer);
d8307d
-
d8307d
-      /* The second copy fails.  */
d8307d
-      TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
d8307d
-                                     sizeof (random_data), 0), -1);
d8307d
-      TEST_COMPARE (errno, maximum_offset_errno);
d8307d
-    }
d8307d
-}
d8307d
-
d8307d
-/* Test a write failure across devices.  */
d8307d
-static void
d8307d
-cross_device_failure (void)
d8307d
-{
d8307d
-  if (xdevfile == NULL)
d8307d
-    /* Subtest not supported due to missing cross-device file.  */
d8307d
-    return;
d8307d
-
d8307d
-  /* We need something to write.  */
d8307d
-  xwrite (infd, random_data, sizeof (random_data));
d8307d
-  xlseek (infd, 0, SEEK_SET);
d8307d
-
d8307d
-  int xdevfd = xopen (xdevfile, O_RDWR | O_LARGEFILE, 0);
d8307d
-  TEST_COMPARE (copy_file_range (infd, pinoff, xdevfd, poutoff,
d8307d
-                                 current_size, 0), -1);
d8307d
-  TEST_COMPARE (errno, EXDEV);
d8307d
-  TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
d8307d
-  struct stat64 st;
d8307d
-  xfstat (xdevfd, &st);
d8307d
-  TEST_COMPARE (st.st_size, 0);
d8307d
-
d8307d
-  xclose (xdevfd);
d8307d
-}
d8307d
-
d8307d
-/* Try to exercise ENOSPC behavior with a tempfs file system (so that
d8307d
-   we do not have to fill up a regular file system to get the error).
d8307d
-   This function runs in a subprocess, so that we do not change the
d8307d
-   mount namespace of the actual test process.  */
d8307d
-static void
d8307d
-enospc_failure_1 (void *closure)
d8307d
-{
d8307d
-#ifdef CLONE_NEWNS
d8307d
-  support_become_root ();
d8307d
-
d8307d
-  /* Make sure that we do not alter the file system mounts of the
d8307d
-     parents.  */
d8307d
-  if (! support_enter_mount_namespace ())
d8307d
-    {
d8307d
-      printf ("warning: ENOSPC test skipped\n");
d8307d
-      return;
d8307d
-    }
d8307d
-
d8307d
-  char *mountpoint = closure;
d8307d
-  if (mount ("none", mountpoint, "tmpfs", MS_NODEV | MS_NOEXEC,
d8307d
-             "size=500k") != 0)
d8307d
-    {
d8307d
-      printf ("warning: could not mount tmpfs at %s: %m\n", mountpoint);
d8307d
-      return;
d8307d
-    }
d8307d
-
d8307d
-  /* The source file must reside on the same file system.  */
d8307d
-  char *intmpfsfile = xasprintf ("%s/%s", mountpoint, "in");
d8307d
-  int intmpfsfd = xopen (intmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600);
d8307d
-  xwrite (intmpfsfd, random_data, sizeof (random_data));
d8307d
-  xlseek (intmpfsfd, 1, SEEK_SET);
d8307d
-  inoff = 1;
d8307d
-
d8307d
-  char *outtmpfsfile = xasprintf ("%s/%s", mountpoint, "out");
d8307d
-  int outtmpfsfd = xopen (outtmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600);
d8307d
-
d8307d
-  /* Fill the file with data until ENOSPC is reached.  */
d8307d
-  while (true)
d8307d
-    {
d8307d
-      ssize_t ret = write (outtmpfsfd, random_data, sizeof (random_data));
d8307d
-      if (ret < 0 && errno != ENOSPC)
d8307d
-        FAIL_EXIT1 ("write to %s: %m", outtmpfsfile);
d8307d
-      if (ret < sizeof (random_data))
d8307d
-        break;
d8307d
-    }
d8307d
-  TEST_COMPARE (write (outtmpfsfd, "", 1), -1);
d8307d
-  TEST_COMPARE (errno, ENOSPC);
d8307d
-  off64_t maxsize = xlseek (outtmpfsfd, 0, SEEK_CUR);
d8307d
-  TEST_VERIFY_EXIT (maxsize > sizeof (random_data));
d8307d
-
d8307d
-  /* Constructed the expected file contents.  */
d8307d
-  char *expected = xmalloc (maxsize);
d8307d
-  TEST_COMPARE (pread64 (outtmpfsfd, expected, maxsize, 0), maxsize);
d8307d
-  /* Go back a little, so some bytes can be written.  */
d8307d
-  enum { offset = 20000 };
d8307d
-  TEST_VERIFY_EXIT (offset < maxsize);
d8307d
-  TEST_VERIFY_EXIT (offset < sizeof (random_data));
d8307d
-  memcpy (expected + maxsize - offset, random_data + 1, offset);
d8307d
-
d8307d
-  if (do_outoff)
d8307d
-    {
d8307d
-      outoff = maxsize - offset;
d8307d
-      xlseek (outtmpfsfd, 2, SEEK_SET);
d8307d
-    }
d8307d
-  else
d8307d
-    xlseek (outtmpfsfd, -offset, SEEK_CUR);
d8307d
-
d8307d
-  /* First call is expected to succeed because we made room for some
d8307d
-     bytes.  */
d8307d
-  TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff,
d8307d
-                                 maximum_size, 0), offset);
d8307d
-  if (do_inoff)
d8307d
-    {
d8307d
-      TEST_COMPARE (inoff, 1 + offset);
d8307d
-      TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1);
d8307d
-    }
d8307d
-  else
d8307d
-      TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset);
d8307d
-  if (do_outoff)
d8307d
-    {
d8307d
-      TEST_COMPARE (outoff, maxsize);
d8307d
-      TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2);
d8307d
-    }
d8307d
-  else
d8307d
-    TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize);
d8307d
-  struct stat64 st;
d8307d
-  xfstat (outtmpfsfd, &st);
d8307d
-  TEST_COMPARE (st.st_size, maxsize);
d8307d
-  char *actual = xmalloc (st.st_size);
d8307d
-  TEST_COMPARE (pread64 (outtmpfsfd, actual, st.st_size, 0), st.st_size);
d8307d
-  TEST_VERIFY (memcmp (expected, actual, maxsize) == 0);
d8307d
-
d8307d
-  /* Second call should fail with ENOSPC.  */
d8307d
-  TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff,
d8307d
-                                 maximum_size, 0), -1);
d8307d
-  TEST_COMPARE (errno, ENOSPC);
d8307d
-
d8307d
-  /* Offsets should be unchanged.  */
d8307d
-  if (do_inoff)
d8307d
-    {
d8307d
-      TEST_COMPARE (inoff, 1 + offset);
d8307d
-      TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1);
d8307d
-    }
d8307d
-  else
d8307d
-    TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset);
d8307d
-  if (do_outoff)
d8307d
-    {
d8307d
-      TEST_COMPARE (outoff, maxsize);
d8307d
-      TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2);
d8307d
-    }
d8307d
-  else
d8307d
-    TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize);
d8307d
-  TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_END), maxsize);
d8307d
-  TEST_COMPARE (pread64 (outtmpfsfd, actual, maxsize, 0), maxsize);
d8307d
-  TEST_VERIFY (memcmp (expected, actual, maxsize) == 0);
d8307d
-
d8307d
-  free (actual);
d8307d
-  free (expected);
d8307d
-
d8307d
-  xclose (intmpfsfd);
d8307d
-  xclose (outtmpfsfd);
d8307d
-  free (intmpfsfile);
d8307d
-  free (outtmpfsfile);
d8307d
-
d8307d
-#else /* !CLONE_NEWNS */
d8307d
-  puts ("warning: ENOSPC test skipped (no mount namespaces)");
d8307d
-#endif
d8307d
-}
d8307d
-
d8307d
-/* Call enospc_failure_1 in a subprocess.  */
d8307d
-static void
d8307d
-enospc_failure (void)
d8307d
-{
d8307d
-  char *mountpoint
d8307d
-    = support_create_temp_directory ("tst-copy_file_range-enospc-");
d8307d
-  support_isolate_in_subprocess (enospc_failure_1, mountpoint);
d8307d
-  free (mountpoint);
d8307d
-}
d8307d
-
d8307d
-/* The target file descriptor must have O_APPEND enabled.  */
d8307d
-static void
d8307d
-oappend_failure (void)
d8307d
-{
d8307d
-  /* Add data, to make sure we do not fail because there is
d8307d
-     insufficient input data.  */
d8307d
-  xwrite (infd, random_data, current_size);
d8307d
-  xlseek (infd, 0, SEEK_SET);
d8307d
-
d8307d
-  xclose (outfd);
d8307d
-  outfd = xopen (outfile, O_RDWR | O_APPEND, 0);
d8307d
-  TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
d8307d
-                                 current_size, 0), -1);
d8307d
-  TEST_COMPARE (errno, EBADF);
d8307d
-}
d8307d
-
d8307d
 /* Test that a short input file results in a shortened copy.  */
d8307d
 static void
d8307d
 short_copy (void)
d8307d
@@ -721,14 +228,6 @@ struct test_case
d8307d
 static struct test_case tests[] =
d8307d
   {
d8307d
     { "simple_file_copy", simple_file_copy, .sizes = true },
d8307d
-    { "pipe_as_source", pipe_as_source, },
d8307d
-    { "pipe_as_destination", pipe_as_destination, },
d8307d
-    { "delayed_write_failure_beginning", delayed_write_failure_beginning,
d8307d
-      .sizes = true },
d8307d
-    { "delayed_write_failure_end", delayed_write_failure_end, .sizes = true },
d8307d
-    { "cross_device_failure", cross_device_failure, .sizes = true },
d8307d
-    { "enospc_failure", enospc_failure, },
d8307d
-    { "oappend_failure", oappend_failure, .sizes = true },
d8307d
     { "short_copy", short_copy, .sizes = true },
d8307d
   };
d8307d
 
d8307d
@@ -739,53 +238,18 @@ do_test (void)
d8307d
     *p = rand () >> 24;
d8307d
 
d8307d
   infd = create_temp_file ("tst-copy_file_range-in-", &infile);
d8307d
-  xclose (create_temp_file ("tst-copy_file_range-out-", &outfile));
d8307d
-
d8307d
-  /* Try to find a different directory from the default input/output
d8307d
-     file.  */
d8307d
+  outfd = create_temp_file ("tst-copy_file_range-out-", &outfile);
d8307d
   {
d8307d
-    struct stat64 instat;
d8307d
-    xfstat (infd, &instat);
d8307d
-    static const char *const candidates[] =
d8307d
-      { NULL, "/var/tmp", "/dev/shm" };
d8307d
-    for (const char *const *c = candidates; c < array_end (candidates); ++c)
d8307d
-      {
d8307d
-        const char *path = *c;
d8307d
-        char *to_free = NULL;
d8307d
-        if (path == NULL)
d8307d
-          {
d8307d
-            to_free = xreadlink ("/proc/self/exe");
d8307d
-            path = dirname (to_free);
d8307d
-          }
d8307d
-
d8307d
-        struct stat64 cstat;
d8307d
-        xstat (path, &cstat);
d8307d
-        if (cstat.st_dev == instat.st_dev)
d8307d
-          {
d8307d
-            free (to_free);
d8307d
-            continue;
d8307d
-          }
d8307d
-
d8307d
-        printf ("info: using alternate temporary files directory: %s\n", path);
d8307d
-        xdevfile = xasprintf ("%s/tst-copy_file_range-xdev-XXXXXX", path);
d8307d
-        free (to_free);
d8307d
-        break;
d8307d
-      }
d8307d
-    if (xdevfile != NULL)
d8307d
+    ssize_t ret = copy_file_range (infd, NULL, outfd, NULL, 0, 0);
d8307d
+    if (ret != 0)
d8307d
       {
d8307d
-        int xdevfd = mkstemp (xdevfile);
d8307d
-        if (xdevfd < 0)
d8307d
-          FAIL_EXIT1 ("mkstemp (\"%s\"): %m", xdevfile);
d8307d
-        struct stat64 xdevst;
d8307d
-        xfstat (xdevfd, &xdevst);
d8307d
-        TEST_VERIFY (xdevst.st_dev != instat.st_dev);
d8307d
-        add_temp_file (xdevfile);
d8307d
-        xclose (xdevfd);
d8307d
+        if (errno == ENOSYS)
d8307d
+          FAIL_UNSUPPORTED ("copy_file_range is not support on this system");
d8307d
+        FAIL_EXIT1 ("copy_file_range probing call: %m");
d8307d
       }
d8307d
-    else
d8307d
-      puts ("warning: no alternate directory on different file system found");
d8307d
   }
d8307d
   xclose (infd);
d8307d
+  xclose (outfd);
d8307d
 
d8307d
   for (do_inoff = 0; do_inoff < 2; ++do_inoff)
d8307d
     for (do_outoff = 0; do_outoff < 2; ++do_outoff)
d8307d
@@ -827,7 +291,6 @@ do_test (void)
d8307d
 
d8307d
   free (infile);
d8307d
   free (outfile);
d8307d
-  free (xdevfile);
d8307d
 
d8307d
   return 0;
d8307d
 }
d8307d
diff --git a/manual/llio.texi b/manual/llio.texi
d8307d
index 2733b9cb7331df07..26f7d2cb3ea220d9 100644
d8307d
--- a/manual/llio.texi
d8307d
+++ b/manual/llio.texi
d8307d
@@ -1404,10 +1404,13 @@ failure occurs.  The return value is zero if the end of the input file
d8307d
 is encountered immediately.
d8307d
 
d8307d
 If no bytes can be copied, to report an error, @code{copy_file_range}
d8307d
-returns the value @math{-1} and sets @code{errno}.  The following
d8307d
-@code{errno} error conditions are specific to this function:
d8307d
+returns the value @math{-1} and sets @code{errno}.  The table below
d8307d
+lists some of the error conditions for this function.
d8307d
 
d8307d
 @table @code
d8307d
+@item ENOSYS
d8307d
+The kernel does not implement the required functionality.
d8307d
+
d8307d
 @item EISDIR
d8307d
 At least one of the descriptors @var{inputfd} or @var{outputfd} refers
d8307d
 to a directory.
d8307d
@@ -1437,9 +1440,6 @@ reading.
d8307d
 
d8307d
 The argument @var{outputfd} is not a valid file descriptor open for
d8307d
 writing, or @var{outputfd} has been opened with @code{O_APPEND}.
d8307d
-
d8307d
-@item EXDEV
d8307d
-The input and output files reside on different file systems.
d8307d
 @end table
d8307d
 
d8307d
 In addition, @code{copy_file_range} can fail with the error codes
d8307d
diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h
d8307d
index 402d2573d75794d5..26344cd610a1f8e7 100644
d8307d
--- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h
d8307d
+++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h
d8307d
@@ -48,7 +48,6 @@
d8307d
 /* Support for copy_file_range, statx was added in kernel 4.13.  */
d8307d
 #if __LINUX_KERNEL_VERSION < 0x040D00
d8307d
 # undef __ASSUME_MLOCK2
d8307d
-# undef __ASSUME_COPY_FILE_RANGE
d8307d
 # undef __ASSUME_STATX
d8307d
 #endif
d8307d
 
d8307d
diff --git a/sysdeps/unix/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c
d8307d
index 7b1a50f7529f2a84..b88b7c9e2ecd825f 100644
d8307d
--- a/sysdeps/unix/sysv/linux/copy_file_range.c
d8307d
+++ b/sysdeps/unix/sysv/linux/copy_file_range.c
d8307d
@@ -20,27 +20,16 @@
d8307d
 #include <sysdep-cancel.h>
d8307d
 #include <unistd.h>
d8307d
 
d8307d
-/* Include the fallback implementation.  */
d8307d
-#ifndef __ASSUME_COPY_FILE_RANGE
d8307d
-#define COPY_FILE_RANGE_DECL static
d8307d
-#define COPY_FILE_RANGE copy_file_range_compat
d8307d
-#include <io/copy_file_range-compat.c>
d8307d
-#endif
d8307d
-
d8307d
 ssize_t
d8307d
 copy_file_range (int infd, __off64_t *pinoff,
d8307d
                  int outfd, __off64_t *poutoff,
d8307d
                  size_t length, unsigned int flags)
d8307d
 {
d8307d
 #ifdef __NR_copy_file_range
d8307d
-  ssize_t ret = SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff,
d8307d
-                                length, flags);
d8307d
-# ifndef __ASSUME_COPY_FILE_RANGE
d8307d
-  if (ret == -1 && errno == ENOSYS)
d8307d
-    ret = copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags);
d8307d
-# endif
d8307d
-  return ret;
d8307d
-#else  /* !__NR_copy_file_range */
d8307d
-  return copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags);
d8307d
+  return SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff,
d8307d
+                         length, flags);
d8307d
+#else
d8307d
+  __set_errno (ENOSYS);
d8307d
+  return -1;
d8307d
 #endif
d8307d
 }
d8307d
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
d8307d
index 5543d92d7e32e501..7a74835495250268 100644
d8307d
--- a/sysdeps/unix/sysv/linux/kernel-features.h
d8307d
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
d8307d
@@ -111,10 +111,6 @@
d8307d
 # define __ASSUME_MLOCK2 1
d8307d
 #endif
d8307d
 
d8307d
-#if __LINUX_KERNEL_VERSION >= 0x040500
d8307d
-# define __ASSUME_COPY_FILE_RANGE 1
d8307d
-#endif
d8307d
-
d8307d
 /* Support for statx was added in kernel 4.11.  */
d8307d
 #if __LINUX_KERNEL_VERSION >= 0x040B00
d8307d
 # define __ASSUME_STATX 1
d8307d
diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
d8307d
index e8e2ac6a873126ac..1c49f099b7993f1d 100644
d8307d
--- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
d8307d
+++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
d8307d
@@ -58,11 +58,6 @@
d8307d
 # undef __ASSUME_EXECVEAT
d8307d
 #endif
d8307d
 
d8307d
-/* Support for the copy_file_range syscall was added in 4.10.  */
d8307d
-#if __LINUX_KERNEL_VERSION < 0x040A00
d8307d
-# undef __ASSUME_COPY_FILE_RANGE
d8307d
-#endif
d8307d
-
d8307d
 /* Support for statx was added in kernel 4.12.  */
d8307d
 #if __LINUX_KERNEL_VERSION < 0X040C00
d8307d
 # undef __ASSUME_STATX