[libglnx] fdio: Add glnx_try_fallocate()



commit 05abf2143f967cd85b1b1b777ee412a581979cf1
Author: Colin Walters <walters verbum org>
Date:   Mon Jun 12 17:00:53 2017 -0400

    fdio: Add glnx_try_fallocate()
    
    The glibc `posix_fallocate()` implementation has a bad fallback,
    and further we need to handle `EOPNOTSUPP` for musl.
    https://github.com/flatpak/flatpak/issues/802

 glnx-fdio.c |   13 ++-----------
 glnx-fdio.h |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 11 deletions(-)
---
diff --git a/glnx-fdio.c b/glnx-fdio.c
index 19de9ec..87e2dbb 100644
--- a/glnx-fdio.c
+++ b/glnx-fdio.c
@@ -920,7 +920,6 @@ glnx_file_replace_contents_with_perms_at (int                   dfd,
                                           GCancellable         *cancellable,
                                           GError              **error)
 {
-  int r;
   char *dnbuf = strdupa (subpath);
   const char *dn = dirname (dnbuf);
 
@@ -940,16 +939,8 @@ glnx_file_replace_contents_with_perms_at (int                   dfd,
   if (len == -1)
     len = strlen ((char*)buf);
 
-  /* Note that posix_fallocate does *not* set errno but returns it. */
-  if (len > 0)
-    {
-      r = posix_fallocate (tmpf.fd, 0, len);
-      if (r != 0)
-        {
-          errno = r;
-          return glnx_throw_errno_prefix (error, "fallocate");
-        }
-    }
+  if (!glnx_try_fallocate (tmpf.fd, 0, len, error))
+    return FALSE;
 
   if (glnx_loop_write (tmpf.fd, buf, len) < 0)
     return glnx_throw_errno (error);
diff --git a/glnx-fdio.h b/glnx-fdio.h
index dda32d1..e52c823 100644
--- a/glnx-fdio.h
+++ b/glnx-fdio.h
@@ -167,6 +167,38 @@ int glnx_renameat2_exchange (int olddirfd, const char *oldpath,
                              int newdirfd, const char *newpath);
 
 /**
+ * glnx_try_fallocate:
+ * @fd: File descriptor
+ * @size: Size
+ * @error: Error
+ *
+ * Wrapper for Linux fallocate().  Explicitly ignores a @size of zero.
+ * Also, will silently do nothing if the underlying filesystem doesn't
+ * support it.  Use this instead of posix_fallocate(), since the glibc fallback
+ * is bad: https://sourceware.org/bugzilla/show_bug.cgi?id=18515
+ */
+static inline gboolean
+glnx_try_fallocate (int      fd,
+                    off_t    offset,
+                    off_t    size,
+                    GError **error)
+{
+  /* This is just nicer than throwing an error */
+  if (size == 0)
+    return TRUE;
+
+  if (fallocate (fd, 0, offset, size) < 0)
+    {
+      if (errno == ENOSYS || errno == EOPNOTSUPP)
+        ; /* Ignore */
+      else
+        return glnx_throw_errno_prefix (error, "fallocate");
+    }
+
+  return TRUE;
+}
+
+/**
  * glnx_fstat:
  * @fd: FD to stat
  * @buf: (out caller-allocates): Return location for stat details


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]