util/disk_cache: use posix_fallocate() for index files
authorJuston Li <justonli@google.com>
Thu, 23 Mar 2023 20:06:55 +0000 (13:06 -0700)
committerMarge Bot <emma+marge@anholt.net>
Thu, 30 Mar 2023 01:09:10 +0000 (01:09 +0000)
ftruncate() allocates disk space lazily. If the disk is full and it is
unable to allocate disk space when accesed via mmap(), it will crash
with a SIGBUS.

Switch to posix_fallocate(), which ensures disk space is allocated
otherwise it fails if there isn't enough disk space. The disk cache
won't be enabled in this case.

For normal cases, a small increase in disk usage as the 1.3MB index
file will be fully allocated when initialized now.

fallback to ftruncate() if posix_fallocate() isn't found.

Signed-off-by: Juston Li <justonli@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22097>

meson.build
src/util/disk_cache_os.c

index c99aaed..a09ad15 100644 (file)
@@ -1277,6 +1277,7 @@ functions_to_detect = {
   'strtok_r': '',
   'getrandom': '',
   'qsort_s': '',
+  'posix_fallocate': '',
 }
 
 foreach f, prefix: functions_to_detect
index 27a1392..e3596f2 100644 (file)
@@ -1019,8 +1019,20 @@ disk_cache_mmap_cache_index(void *mem_ctx, struct disk_cache *cache,
    /* Force the index file to be the expected size. */
    size_t size = sizeof(*cache->size) + CACHE_INDEX_MAX_KEYS * CACHE_KEY_SIZE;
    if (sb.st_size != size) {
+#if HAVE_POSIX_FALLOCATE
+      /* posix_fallocate() ensures disk space is allocated otherwise it
+       * fails if there is not enough space on the disk.
+       */
+      if (posix_fallocate(fd, 0, size) != 0)
+         goto path_fail;
+#else
+      /* ftruncate() allocates disk space lazily. If the disk is full
+       * and it is unable to allocate disk space when accessed via
+       * mmap, it will crash with a SIGBUS.
+       */
       if (ftruncate(fd, size) == -1)
          goto path_fail;
+#endif
    }
 
    /* We map this shared so that other processes see updates that we