[newlib-cygwin/main] Cygwin: introduce fallocate(2)

Corinna Vinschen corinna@sourceware.org
Tue Nov 28 10:03:05 GMT 2023


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e01c50c7b0a6c5d2a25feb02958d57902c25c141

commit e01c50c7b0a6c5d2a25feb02958d57902c25c141
Author:     Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Sun Nov 26 21:05:07 2023 +0100
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Tue Nov 28 10:52:05 2023 +0100

    Cygwin: introduce fallocate(2)
    
    First cut of the new, Linux-specific fallocate(2) function.
    Do not add any functionality yet, except of basic handling
    of FALLOC_FL_KEEP_SIZE.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/cygwin.din               |  1 +
 winsup/cygwin/fhandler/disk_file.cc    | 41 +++++++++++++++++++++++++++++-----
 winsup/cygwin/include/cygwin/version.h |  3 ++-
 winsup/cygwin/include/fcntl.h          | 14 +++++++++++-
 winsup/cygwin/release/3.5.0            |  2 ++
 winsup/cygwin/syscalls.cc              | 34 ++++++++++++++++++++++++++++
 winsup/doc/new-features.xml            |  4 ++++
 7 files changed, 92 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index d5e8f8c05ef8..9b76ce67a9a4 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -506,6 +506,7 @@ fabsf NOSIGFE
 fabsl NOSIGFE
 faccessat SIGFE
 facl SIGFE
+fallocate SIGFE
 fchdir SIGFE
 fchmod SIGFE
 fchmodat SIGFE
diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
index 51602f30f10a..b49b25c71ad0 100644
--- a/winsup/cygwin/fhandler/disk_file.cc
+++ b/winsup/cygwin/fhandler/disk_file.cc
@@ -1153,15 +1153,46 @@ fhandler_disk_file::fallocate (int mode, off_t offset, off_t length)
       if (!NT_SUCCESS (status))
 	return geterrno_from_nt_status (status);
 
-      /* If called through posix_fallocate, silently succeed if
-	 offset + length is less than the file's actual length. */
-      if (mode == 0 && offset + length < fsi.EndOfFile.QuadPart)
-	return 0;
+      /* Never change file size if FALLOC_FL_KEEP_SIZE is specified. */
+      if ((mode & FALLOC_FL_KEEP_SIZE)
+	  && offset + length > fsi.EndOfFile.QuadPart)
+	{
+	  if (offset > fsi.EndOfFile.QuadPart) /* no-op */
+	    return 0;
+	  length = fsi.EndOfFile.QuadPart - offset;
+	}
+      mode &= ~FALLOC_FL_KEEP_SIZE;
+
+      switch (mode)
+	{
+	case 0:
+	case __FALLOC_FL_TRUNCATE:
+	  break;
+	case FALLOC_FL_PUNCH_HOLE: /* TODO */
+	  return EOPNOTSUPP;
+	  break;
+	case FALLOC_FL_ZERO_RANGE: /* TODO */
+	  return EOPNOTSUPP;
+	  break;
+	default:
+	  return EINVAL;
+	}
+
+      if (mode == 0)
+	{
+	  /* If called through posix_fallocate, silently succeed if
+	     offset + length is less than the file's actual length. */
+
+	  /* TODO: If the file is sparse, POSIX requires to allocate
+		   the holes within offset and offset + length. */
+	  if (offset + length < fsi.EndOfFile.QuadPart)
+	    return 0;
+	}
 
       feofi.EndOfFile.QuadPart = offset + length;
       /* Create sparse files only when called through ftruncate, not when
 	 called through posix_fallocate. */
-      if ((mode & __FALLOC_FL_TRUNCATE)
+      if (mode == __FALLOC_FL_TRUNCATE
 	  && !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
 	  && pc.support_sparse ()
 	  && offset + length >= fsi.EndOfFile.QuadPart + (128 * 1024))
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 833de646c563..c8177c2b17d7 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -483,12 +483,13 @@ details. */
        posix_spawn_file_actions_addfchdir_np.
   347: Add c16rtomb, c32rtomb, mbrtoc16, mbrtoc32.
   348: Add c8rtomb, mbrtoc.
+  349: Add fallocate.
 
   Note that we forgot to bump the api for ualarm, strtoll, strtoull,
   sigaltstack, sethostname. */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 348
+#define CYGWIN_VERSION_API_MINOR 349
 
 /* There is also a compatibity version number associated with the shared memory
    regions.  It is incremented when incompatible changes are made to the shared
diff --git a/winsup/cygwin/include/fcntl.h b/winsup/cygwin/include/fcntl.h
index 1ef51e50c575..b38dfa50bcc1 100644
--- a/winsup/cygwin/include/fcntl.h
+++ b/winsup/cygwin/include/fcntl.h
@@ -42,12 +42,24 @@ details. */
 #define POSIX_FADV_DONTNEED	4
 #define POSIX_FADV_NOREUSE	5
 
-#define __FALLOC_FL_TRUNCATE		0x0001	/* internal */
+#if __GNU_VISIBLE
+#define FALLOC_FL_PUNCH_HOLE		0x0001
+#define FALLOC_FL_ZERO_RANGE		0x0002
+#define FALLOC_FL_UNSHARE_RANGE		0x0004
+#define FALLOC_FL_COLLAPSE_RANGE	0x0008
+#define FALLOC_FL_INSERT_RANGE		0x0010
+#define FALLOC_FL_KEEP_SIZE		0x1000
+/* Internal flags */
+#define __FALLOC_FL_TRUNCATE		0x2000
+#endif
 
 __BEGIN_DECLS
 
 extern int posix_fadvise (int, off_t, off_t, int);
 extern int posix_fallocate (int, off_t, off_t);
+#if __GNU_VISIBLE
+extern int fallocate (int, int, off_t, off_t);
+#endif
 
 __END_DECLS
 
diff --git a/winsup/cygwin/release/3.5.0 b/winsup/cygwin/release/3.5.0
index aee21c972fcb..3b6df951d4d3 100644
--- a/winsup/cygwin/release/3.5.0
+++ b/winsup/cygwin/release/3.5.0
@@ -43,6 +43,8 @@ What's new:
 
 - New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32.
 
+- New API call: fallocate (Linux-specific).
+
 - Implement OSS-based sound mixer device (/dev/mixer).
 
 What changed:
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index b2e6ba16ca04..0e4c54bcfae9 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2987,6 +2987,40 @@ posix_fadvise (int fd, off_t offset, off_t len, int advice)
   return res;
 }
 
+extern "C" int
+fallocate (int fd, int mode, off_t offset, off_t len)
+{
+  int res = 0;
+
+  /* First check mask of allowed flags */
+  if (mode & ~(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE
+	       | FALLOC_FL_UNSHARE_RANGE | FALLOC_FL_COLLAPSE_RANGE
+	       | FALLOC_FL_INSERT_RANGE | FALLOC_FL_KEEP_SIZE))
+    res = EOPNOTSUPP;
+  /* Either FALLOC_FL_PUNCH_HOLE or FALLOC_FL_ZERO_RANGE, never both */
+  else if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
+	   == (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
+    res = EOPNOTSUPP;
+  /* FALLOC_FL_PUNCH_HOLE must be ORed with FALLOC_FL_KEEP_SIZE */
+  else if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE))
+	   == FALLOC_FL_PUNCH_HOLE)
+    res = EOPNOTSUPP;
+  else if (offset < 0 || len == 0)
+    res = EINVAL;
+  else
+    {
+      cygheap_fdget cfd (fd);
+      if (cfd >= 0)
+	res = cfd->fallocate (mode, offset, len);
+      else
+	res = EBADF;
+      if (res == EISDIR)
+	res = ENODEV;
+    }
+  syscall_printf ("%R = posix_fallocate(%d, %D, %D)", res, fd, offset, len);
+  return 0;
+}
+
 extern "C" int
 posix_fallocate (int fd, off_t offset, off_t len)
 {
diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml
index 2c31a4accd44..c5e6cdd7f2dc 100644
--- a/winsup/doc/new-features.xml
+++ b/winsup/doc/new-features.xml
@@ -74,6 +74,10 @@ posix_spawn_file_actions_addfchdir_np.
 New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32.
 </para></listitem>
 
+<listitem><para>
+New API call: fallocate (Linux-specific).
+</para></listitem>
+
 <listitem><para>
 FIFOs now also work over NFS.
 </para></listitem>


More information about the Cygwin-cvs mailing list