Module: Mesa
Branch: master
Commit: 16b2b4342b5d561e0c56c47c4fffed22cfe1721c
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=16b2b4342b5d561e0c56c47c4fffed22cfe1721c

Author: Timothy Arceri <[email protected]>
Date:   Wed Mar  3 15:12:09 2021 +1100

util/disk_cache: separate file reads from cache item validation

This will allow us to share validation between the single file cache
and the multifile cache.

It also reduces the number of malloc() calls.

Reviewed-By: Mike Blumenkrantz <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9443>

---

 src/util/disk_cache_os.c | 124 +++++++++++++++++++++++++----------------------
 1 file changed, 65 insertions(+), 59 deletions(-)

diff --git a/src/util/disk_cache_os.c b/src/util/disk_cache_os.c
index c4a0324725a..aeed1c9637b 100644
--- a/src/util/disk_cache_os.c
+++ b/src/util/disk_cache_os.c
@@ -57,6 +57,7 @@ struct cache_entry_file_data {
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "util/blob.h"
 #include "util/crc32.h"
 #include "util/debug.h"
 #include "util/disk_cache.h"
@@ -373,55 +374,33 @@ disk_cache_evict_item(struct disk_cache *cache, char 
*filename)
       p_atomic_add(cache->size, - (uint64_t)sb.st_blocks * 512);
 }
 
-void *
-disk_cache_load_item(struct disk_cache *cache, char *filename, size_t *size)
+static void *
+parse_and_validate_cache_item(struct disk_cache *cache, void *cache_item,
+                              size_t cache_item_size, size_t *size)
 {
-   int fd = -1, ret;
-   struct stat sb;
-   uint8_t *data = NULL;
    uint8_t *uncompressed_data = NULL;
-   uint8_t *file_header = NULL;
-
-   fd = open(filename, O_RDONLY | O_CLOEXEC);
-   if (fd == -1)
-      goto fail;
-
-   if (fstat(fd, &sb) == -1)
-      goto fail;
-
-   data = malloc(sb.st_size);
-   if (data == NULL)
-      goto fail;
-
-   size_t ck_size = cache->driver_keys_blob_size;
-   file_header = malloc(ck_size);
-   if (!file_header)
-      goto fail;
 
-   if (sb.st_size < ck_size)
-      goto fail;
+   struct blob_reader ci_blob_reader;
+   blob_reader_init(&ci_blob_reader, cache_item, cache_item_size);
 
-   ret = read_all(fd, file_header, ck_size);
-   if (ret == -1)
+   size_t header_size = cache->driver_keys_blob_size;
+   const void *keys_blob = blob_read_bytes(&ci_blob_reader, header_size);
+   if (ci_blob_reader.overrun)
       goto fail;
 
    /* Check for extremely unlikely hash collisions */
-   if (memcmp(cache->driver_keys_blob, file_header, ck_size) != 0) {
+   if (memcmp(cache->driver_keys_blob, keys_blob, header_size) != 0) {
       assert(!"Mesa cache keys mismatch!");
       goto fail;
    }
 
-   size_t cache_item_md_size = sizeof(uint32_t);
-   uint32_t md_type;
-   ret = read_all(fd, &md_type, cache_item_md_size);
-   if (ret == -1)
+   uint32_t md_type = blob_read_uint32(&ci_blob_reader);
+   if (ci_blob_reader.overrun)
       goto fail;
 
    if (md_type == CACHE_ITEM_TYPE_GLSL) {
-      uint32_t num_keys;
-      cache_item_md_size += sizeof(uint32_t);
-      ret = read_all(fd, &num_keys, sizeof(uint32_t));
-      if (ret == -1)
+      uint32_t num_keys = blob_read_uint32(&ci_blob_reader);
+      if (ci_blob_reader.overrun)
          goto fail;
 
       /* The cache item metadata is currently just used for distributing
@@ -430,44 +409,75 @@ disk_cache_load_item(struct disk_cache *cache, char 
*filename, size_t *size)
        * TODO: pass the metadata back to the caller and do some basic
        * validation.
        */
-      cache_item_md_size += num_keys * sizeof(cache_key);
-      ret = lseek(fd, num_keys * sizeof(cache_key), SEEK_CUR);
-      if (ret == -1)
+      const void UNUSED *metadata =
+         blob_read_bytes(&ci_blob_reader, num_keys * sizeof(cache_key));
+      if (ci_blob_reader.overrun)
          goto fail;
    }
 
    /* Load the CRC that was created when the file was written. */
-   struct cache_entry_file_data cf_data;
-   size_t cf_data_size = sizeof(cf_data);
-   ret = read_all(fd, &cf_data, cf_data_size);
-   if (ret == -1)
+   struct cache_entry_file_data *cf_data =
+      (struct cache_entry_file_data *)
+         blob_read_bytes(&ci_blob_reader, sizeof(struct 
cache_entry_file_data));
+   if (ci_blob_reader.overrun)
       goto fail;
 
-   /* Load the actual cache data. */
-   size_t cache_data_size =
-      sb.st_size - cf_data_size - ck_size - cache_item_md_size;
-   ret = read_all(fd, data, cache_data_size);
-   if (ret == -1)
-      goto fail;
+   size_t cache_data_size = ci_blob_reader.end - ci_blob_reader.current;
+   const uint8_t *data = (uint8_t *) blob_read_bytes(&ci_blob_reader, 
cache_data_size);
 
    /* Check the data for corruption */
-   if (cf_data.crc32 != util_hash_crc32(data, cache_data_size))
+   if (cf_data->crc32 != util_hash_crc32(data, cache_data_size))
       goto fail;
 
    /* Uncompress the cache data */
-   uncompressed_data = malloc(cf_data.uncompressed_size);
+   uncompressed_data = malloc(cf_data->uncompressed_size);
    if (!util_compress_inflate(data, cache_data_size, uncompressed_data,
-                              cf_data.uncompressed_size))
+                              cf_data->uncompressed_size))
+      goto fail;
+
+   if (size)
+      *size = cf_data->uncompressed_size;
+
+   return uncompressed_data;
+
+ fail:
+   if (uncompressed_data)
+      free(uncompressed_data);
+
+   return NULL;
+}
+
+void *
+disk_cache_load_item(struct disk_cache *cache, char *filename, size_t *size)
+{
+   uint8_t *data = NULL;
+
+   int fd = open(filename, O_RDONLY | O_CLOEXEC);
+   if (fd == -1)
+      goto fail;
+
+   struct stat sb;
+   if (fstat(fd, &sb) == -1)
+      goto fail;
+
+   data = malloc(sb.st_size);
+   if (data == NULL)
+      goto fail;
+
+   /* Read entire file into memory */
+   int ret = read_all(fd, data, sb.st_size);
+   if (ret == -1)
+      goto fail;
+
+    uint8_t *uncompressed_data =
+       parse_and_validate_cache_item(cache, data, sb.st_size, size);
+   if (!uncompressed_data)
       goto fail;
 
    free(data);
    free(filename);
-   free(file_header);
    close(fd);
 
-   if (size)
-      *size = cf_data.uncompressed_size;
-
    return uncompressed_data;
 
  fail:
@@ -475,10 +485,6 @@ disk_cache_load_item(struct disk_cache *cache, char 
*filename, size_t *size)
       free(data);
    if (filename)
       free(filename);
-   if (uncompressed_data)
-      free(uncompressed_data);
-   if (file_header)
-      free(file_header);
    if (fd != -1)
       close(fd);
 

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to