mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-28 03:45:10 -04:00
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
This commit is contained in:
13
glnx-fdio.c
13
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);
|
||||
|
||||
32
glnx-fdio.h
32
glnx-fdio.h
@@ -166,6 +166,38 @@ int glnx_renameat2_noreplace (int olddirfd, const char *oldpath,
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user