]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
stat-util: add vfs_free_bytes() 41684/head
authorLennart Poettering <lennart@amutable.com>
Mon, 13 Apr 2026 15:57:10 +0000 (17:57 +0200)
committerLennart Poettering <lennart@amutable.com>
Fri, 17 Apr 2026 16:32:21 +0000 (18:32 +0200)
The casts and the right fields to multiply aren't entirely trivial,
let's add a helper for it.

src/basic/stat-util.c
src/basic/stat-util.h
src/coredump/coredump-submit.c

index 06634b7df60c8ac19e74e353be85804489297dd1..e0dc59a863bad53bc6c5595bf168027002a06ffc 100644 (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;
+}
index ec04a2b80cd08644a93f99507e67b9e51612cade..de9ee03f44034321935a073173a42ba6569c6ced 100644 (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);
index 6ce03cdec0770ff9f1dc6dc38e70be90d455de27..42d92a32e9c6dd23c06900388f7dd7b07b9a5592 100644 (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