[libglnx] fdio: Add glnx_try_fallocate()
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libglnx] fdio: Add glnx_try_fallocate()
- Date: Tue, 13 Jun 2017 15:44:39 +0000 (UTC)
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]