aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/posix/posix_fallocate.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/posix/posix_fallocate.c')
-rw-r--r--sysdeps/posix/posix_fallocate.c122
1 files changed, 0 insertions, 122 deletions
diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c
deleted file mode 100644
index f87f536bd9..0000000000
--- a/sysdeps/posix/posix_fallocate.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (C) 2000-2017 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 <unistd.h>
-#include <stdint.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-
-/* Reserve storage for the data of the file associated with FD. This
- emulation is far from perfect, but the kernel cannot do not much
- better for network file systems, either. */
-
-int
-posix_fallocate (int fd, __off_t offset, __off_t len)
-{
- struct stat64 st;
-
- if (offset < 0 || len < 0)
- return EINVAL;
-
- /* Perform overflow check. The outer cast relies on a GCC
- extension. */
- if ((__off_t) ((uint64_t) offset + (uint64_t) len) < 0)
- return EFBIG;
-
- /* pwrite below will not do the right thing in O_APPEND mode. */
- {
- int flags = __fcntl (fd, F_GETFL, 0);
- if (flags < 0 || (flags & O_APPEND) != 0)
- return EBADF;
- }
-
- /* We have to make sure that this is really a regular file. */
- if (__fxstat64 (_STAT_VER, fd, &st) != 0)
- return EBADF;
- if (S_ISFIFO (st.st_mode))
- return ESPIPE;
- if (! S_ISREG (st.st_mode))
- return ENODEV;
-
- if (len == 0)
- {
- /* This is racy, but there is no good way to satisfy a
- zero-length allocation request. */
- if (st.st_size < offset)
- {
- int ret = __ftruncate (fd, offset);
-
- if (ret != 0)
- ret = errno;
- return ret;
- }
- return 0;
- }
-
- /* Minimize data transfer for network file systems, by issuing
- single-byte write requests spaced by the file system block size.
- (Most local file systems have fallocate support, so this fallback
- code is not used there.) */
-
- unsigned increment;
- {
- struct statfs64 f;
-
- if (__fstatfs64 (fd, &f) != 0)
- return errno;
- if (f.f_bsize == 0)
- increment = 512;
- else if (f.f_bsize < 4096)
- increment = f.f_bsize;
- else
- /* NFS does not propagate the block size of the underlying
- storage and may report a much larger value which would still
- leave holes after the loop below, so we cap the increment at
- 4096. */
- increment = 4096;
- }
-
- /* Write a null byte to every block. This is racy; we currently
- lack a better option. Compare-and-swap against a file mapping
- might additional local races, but requires interposition of a
- signal handler to catch SIGBUS. */
- for (offset += (len - 1) % increment; len > 0; offset += increment)
- {
- len -= increment;
-
- if (offset < st.st_size)
- {
- unsigned char c;
- ssize_t rsize = __pread (fd, &c, 1, offset);
-
- if (rsize < 0)
- return errno;
- /* If there is a non-zero byte, the block must have been
- allocated already. */
- else if (rsize == 1 && c != 0)
- continue;
- }
-
- if (__pwrite (fd, "", 1, offset) != 1)
- return errno;
- }
-
- return 0;
-}