return MODE_INVALID;
}
+
+int vfs_free_bytes(int fd, uint64_t *ret) {
+ assert(fd >= 0);
+ assert(ret);
+
+ /* Safely returns the current available disk space (for root, i.e. including any space reserved for
+ * root) of the disk referenced by the fd, converted to bytes. */
+
+ struct statvfs sv;
+ if (fstatvfs(fd, &sv) < 0)
+ return -errno;
+
+ if (!MUL_SAFE(ret, (uint64_t) sv.f_frsize, (uint64_t) sv.f_bfree))
+ return -ERANGE;
+
+ return 0;
+}
* type). */
return IN_SET(m & S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFCHR, S_IFIFO);
}
+
+int vfs_free_bytes(int fd, uint64_t *ret);
if (storage_on_tmpfs && config->compress) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
uint64_t cgroup_limit = UINT64_MAX;
- struct statvfs sv;
/* If we can't get the cgroup limit, just ignore it, but don't fail,
* try anyway with the config settings. */
/* tmpfs might get full quickly, so check the available space too. But don't worry about
* errors here, failing to access the storage location will be better logged when writing to
* it. */
- if (fstatvfs(fd, &sv) >= 0)
- max_size = MIN((uint64_t)sv.f_frsize * (uint64_t)sv.f_bfree, max_size);
+ uint64_t free_bytes;
+ if (vfs_free_bytes(fd, &free_bytes) >= 0)
+ max_size = MIN(free_bytes, max_size);
/* Impose a lower minimum, otherwise we will miss the basic headers. */
max_size = MAX(PROCESS_SIZE_MIN, max_size);
/* Ensure we can always switch to compressing on the fly in case we are running out of space