From f04c7e93ce37c733b23c88ffad78768986a6f231 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 14 Apr 2021 12:56:07 +0300 Subject: interactive-wayland: fallback to ftruncate() if needed Fallback to ftruncate() if the underlying filesystem does not support posix_fallocate(). Idea by: Jan Beich , Niclas Zeising Inspired by: Wayland cursor/os-compatibility.c [ran: small adjustments] Signed-off-by: Ran Benita --- tools/interactive-wayland.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/interactive-wayland.c b/tools/interactive-wayland.c index 3ac7ad7..d23432d 100644 --- a/tools/interactive-wayland.c +++ b/tools/interactive-wayland.c @@ -130,6 +130,27 @@ create_tmpfile_cloexec(char *tmpname) } #endif +static int +os_resize_anonymous_file(int fd, off_t size) +{ + int ret; +#ifdef HAVE_POSIX_FALLOCATE + ret = posix_fallocate(fd, 0, size); + if (ret == 0) + return 0; + /* + * Filesystems that do support fallocate will return EINVAL + * or EOPNOTSUPP, fallback to ftruncate() then. + */ + if (ret != EINVAL && ret != EOPNOTSUPP) + return ret; +#endif + ret = ftruncate(fd, size); + if (ret != 0) + return errno; + return 0; +} + /* * Create a new, unique, anonymous file of the given size, and * return the file descriptor for it. The file descriptor is set @@ -148,8 +169,8 @@ create_tmpfile_cloexec(char *tmpname) * If the C library implements posix_fallocate(), it is used to * guarantee that disk space is available for the file at the * given size. If disk space is insufficent, errno is set to ENOSPC. - * If posix_fallocate() is not supported, program may receive - * SIGBUS on accessing mmap()'ed file contents instead. + * If posix_fallocate() is not supported, program will fallback + * to ftruncate() instead. */ static int os_create_anonymous_file(off_t size) @@ -180,20 +201,12 @@ os_create_anonymous_file(off_t size) if (fd < 0) return -1; -#ifdef HAVE_POSIX_FALLOCATE - ret = posix_fallocate(fd, 0, size); + ret = os_resize_anonymous_file(fd, size); if (ret != 0) { close(fd); errno = ret; return -1; } -#else - ret = ftruncate(fd, size); - if (ret < 0) { - close(fd); - return -1; - } -#endif return fd; } -- cgit v1.2.1