stat-util: add vfs_free_bytes()

The casts and the right fields to multiply aren't entirely trivial,
let's add a helper for it.
This commit is contained in:
Lennart Poettering
2026-04-17 18:32:21 +02:00
parent d7b6d89d90
commit 7e8882a96f
3 changed files with 22 additions and 3 deletions
+17
View File
@@ -898,3 +898,20 @@ mode_t inode_type_from_string(const char *s) {
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;
}
+2
View File
@@ -161,3 +161,5 @@ static inline bool inode_type_can_hardlink(mode_t m) {
* 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);
+3 -3
View File
@@ -305,7 +305,6 @@ static int save_external_coredump(
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. */
@@ -335,8 +334,9 @@ static int save_external_coredump(
/* 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