From 46a8d5e7ef61735416d0c54886a7a9930621ae2c Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 12 Jul 2024 14:48:17 -0500 Subject: [PATCH] Disk cache should consistently create parent directories when needed In !25925 I attempted to fix an error spam caused by the disk cache not creating parent directories of the cache directory when needed, resulting in failure to create the disk cache. Presumably that is bad for performance. Unfortunately I did a really bad job and only fixed the edge case where the cache dir is given by $MESA_SHADER_CACHE_DIR rather than the general case. Here I attempt to be more comprehensive. Fixes #8294 Part-of: --- src/util/disk_cache_os.c | 20 +++++--------------- src/util/tests/cache_test.cpp | 15 ++------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/src/util/disk_cache_os.c b/src/util/disk_cache_os.c index 9f523f57caf..17a5406b196 100644 --- a/src/util/disk_cache_os.c +++ b/src/util/disk_cache_os.c @@ -105,6 +105,7 @@ disk_cache_get_function_identifier(void *ptr, struct mesa_sha1 *ctx) #include "util/rand_xor.h" /* Create a directory named 'path' if it does not already exist. + * This is for use by mkdir_with_parents_if_needed(). Use that instead. * * Returns: 0 if path already exists as a directory or if created. * -1 in all other cases. @@ -182,7 +183,6 @@ mkdir_with_parents_if_needed(const char *path) * * Returns NULL on any error, such as: * - * does not exist or is not a directory * / exists but is not a directory * / cannot be created as a directory */ @@ -190,17 +190,13 @@ static char * concatenate_and_mkdir(void *ctx, const char *path, const char *name) { char *new_path; - struct stat sb; - - if (stat(path, &sb) != 0 || ! S_ISDIR(sb.st_mode)) - return NULL; new_path = ralloc_asprintf(ctx, "%s/%s", path, name); - if (mkdir_if_needed(new_path) == 0) + if (mkdir_with_parents_if_needed(new_path) == 0) return new_path; - else - return NULL; + + return NULL; } struct lru_file { @@ -444,7 +440,7 @@ make_cache_file_directory(struct disk_cache *cache, const cache_key key) if (asprintf(&dir, "%s/%c%c", cache->path, buf[0], buf[1]) == -1) return; - mkdir_if_needed(dir); + mkdir_with_parents_if_needed(dir); free(dir); } @@ -904,9 +900,6 @@ disk_cache_generate_cache_dir(void *mem_ctx, const char *gpu_name, } if (path) { - if (mkdir_with_parents_if_needed(path) == -1) - return NULL; - path = concatenate_and_mkdir(mem_ctx, path, cache_dir_name); if (!path) return NULL; @@ -916,9 +909,6 @@ disk_cache_generate_cache_dir(void *mem_ctx, const char *gpu_name, char *xdg_cache_home = secure_getenv("XDG_CACHE_HOME"); if (xdg_cache_home) { - if (mkdir_if_needed(xdg_cache_home) == -1) - return NULL; - path = concatenate_and_mkdir(mem_ctx, xdg_cache_home, cache_dir_name); if (!path) return NULL; diff --git a/src/util/tests/cache_test.cpp b/src/util/tests/cache_test.cpp index 8dfd39d264c..a91ce0a095d 100644 --- a/src/util/tests/cache_test.cpp +++ b/src/util/tests/cache_test.cpp @@ -201,20 +201,9 @@ test_disk_cache_create(void *mem_ctx, const char *cache_dir_name, /* Test with XDG_CACHE_HOME set */ setenv("XDG_CACHE_HOME", CACHE_TEST_TMP "/xdg-cache-home", 1); - cache = disk_cache_create("test", driver_id, 0); - EXPECT_FALSE(cache_exists(cache)) - << "disk_cache_create with XDG_CACHE_HOME set with a non-existing parent directory"; - - err = mkdir(CACHE_TEST_TMP, 0755); - if (err != 0) { - fprintf(stderr, "Error creating %s: %s\n", CACHE_TEST_TMP, strerror(errno)); - GTEST_FAIL(); - } - disk_cache_destroy(cache); - cache = disk_cache_create("test", driver_id, 0); EXPECT_TRUE(cache_exists(cache)) - << "disk_cache_create with XDG_CACHE_HOME set"; + << "disk_cache_create with XDG_CACHE_HOME set with a non-existing parent directory"; char *path = ralloc_asprintf( mem_ctx, "%s%s", CACHE_TEST_TMP "/xdg-cache-home/", cache_dir_name); @@ -1456,4 +1445,4 @@ TEST_F(Cache, DeleteOldCache) rmdir(cache_dir_name); rmdir(dir_name); #endif -} \ No newline at end of file +}