at v6.19 68 lines 1.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* Manage a cache of file names' existence */ 3#include <pthread.h> 4#include <stdlib.h> 5#include <string.h> 6#include <unistd.h> 7#include <linux/compiler.h> 8#include "fncache.h" 9#include "hashmap.h" 10 11static struct hashmap *fncache; 12 13static size_t fncache__hash(long key, void *ctx __maybe_unused) 14{ 15 return str_hash((const char *)key); 16} 17 18static bool fncache__equal(long key1, long key2, void *ctx __maybe_unused) 19{ 20 return strcmp((const char *)key1, (const char *)key2) == 0; 21} 22 23static void fncache__init(void) 24{ 25 fncache = hashmap__new(fncache__hash, fncache__equal, /*ctx=*/NULL); 26} 27 28static struct hashmap *fncache__get(void) 29{ 30 static pthread_once_t fncache_once = PTHREAD_ONCE_INIT; 31 32 pthread_once(&fncache_once, fncache__init); 33 34 return fncache; 35} 36 37static bool lookup_fncache(const char *name, bool *res) 38{ 39 long val; 40 41 if (!hashmap__find(fncache__get(), name, &val)) 42 return false; 43 44 *res = (val != 0); 45 return true; 46} 47 48static void update_fncache(const char *name, bool res) 49{ 50 char *old_key = NULL, *key = strdup(name); 51 52 if (key) { 53 hashmap__set(fncache__get(), key, res, &old_key, /*old_value*/NULL); 54 free(old_key); 55 } 56} 57 58/* No LRU, only use when bounded in some other way. */ 59bool file_available(const char *name) 60{ 61 bool res; 62 63 if (lookup_fncache(name, &res)) 64 return res; 65 res = access(name, R_OK) == 0; 66 update_fncache(name, res); 67 return res; 68}