mirror of
https://github.com/drakmor/ShadowMountPlus.git
synced 2026-10-22 06:32:25 -05:00
143 lines
4.6 KiB
C
143 lines
4.6 KiB
C
#include "sm_platform.h"
|
|
#include <pthread.h>
|
|
|
|
#include "sm_image_cache.h"
|
|
#include "sm_limits.h"
|
|
|
|
struct ImageCache {
|
|
char path[MAX_PATH];
|
|
char mount_point[MAX_PATH];
|
|
int unit_id;
|
|
attach_backend_t backend;
|
|
bool valid;
|
|
};
|
|
|
|
static struct ImageCache g_image_cache[MAX_IMAGE_MOUNTS];
|
|
static pthread_mutex_t g_image_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
static int find_cache_index(const char *path, const char *mount_point) {
|
|
for (int k = 0; k < MAX_IMAGE_MOUNTS; k++) {
|
|
if (!g_image_cache[k].valid)
|
|
continue;
|
|
if (mount_point && strcmp(g_image_cache[k].mount_point, mount_point) == 0) {
|
|
return k;
|
|
}
|
|
if (path && strcmp(g_image_cache[k].path, path) == 0)
|
|
return k;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int upsert_image_source_mapping(const char *path, const char *mount_point) {
|
|
int entry_index = find_cache_index(path, mount_point);
|
|
if (entry_index >= 0) {
|
|
struct ImageCache *entry = &g_image_cache[entry_index];
|
|
(void)strlcpy(entry->path, path, sizeof(entry->path));
|
|
(void)strlcpy(entry->mount_point, mount_point, sizeof(entry->mount_point));
|
|
return entry_index;
|
|
}
|
|
|
|
for (int k = 0; k < MAX_IMAGE_MOUNTS; k++) {
|
|
if (!g_image_cache[k].valid) {
|
|
(void)strlcpy(g_image_cache[k].path, path, sizeof(g_image_cache[k].path));
|
|
(void)strlcpy(g_image_cache[k].mount_point, mount_point,
|
|
sizeof(g_image_cache[k].mount_point));
|
|
g_image_cache[k].unit_id = -1;
|
|
g_image_cache[k].backend = ATTACH_BACKEND_NONE;
|
|
g_image_cache[k].valid = true;
|
|
return k;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
bool cache_image_source_mapping(const char *path, const char *mount_point) {
|
|
pthread_mutex_lock(&g_image_cache_mutex);
|
|
bool ok = upsert_image_source_mapping(path, mount_point) >= 0;
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return ok;
|
|
}
|
|
|
|
bool cache_image_mount(const char *path, const char *mount_point, int unit_id,
|
|
attach_backend_t backend) {
|
|
pthread_mutex_lock(&g_image_cache_mutex);
|
|
int entry_index = upsert_image_source_mapping(path, mount_point);
|
|
if (entry_index < 0) {
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return false;
|
|
}
|
|
|
|
struct ImageCache *entry = &g_image_cache[entry_index];
|
|
entry->unit_id = unit_id;
|
|
entry->backend = backend;
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return true;
|
|
}
|
|
|
|
bool get_image_cache_entry(int index, image_cache_entry_t *entry_out) {
|
|
pthread_mutex_lock(&g_image_cache_mutex);
|
|
if (index < 0 || index >= MAX_IMAGE_MOUNTS || !g_image_cache[index].valid) {
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return false;
|
|
}
|
|
|
|
memset(entry_out, 0, sizeof(*entry_out));
|
|
(void)strlcpy(entry_out->path, g_image_cache[index].path,
|
|
sizeof(entry_out->path));
|
|
(void)strlcpy(entry_out->mount_point, g_image_cache[index].mount_point,
|
|
sizeof(entry_out->mount_point));
|
|
entry_out->unit_id = g_image_cache[index].unit_id;
|
|
entry_out->backend = g_image_cache[index].backend;
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return true;
|
|
}
|
|
|
|
void invalidate_image_cache_entry(int index) {
|
|
pthread_mutex_lock(&g_image_cache_mutex);
|
|
if (index < 0 || index >= MAX_IMAGE_MOUNTS) {
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return;
|
|
}
|
|
memset(&g_image_cache[index], 0, sizeof(g_image_cache[index]));
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
}
|
|
|
|
bool resolve_device_from_mount_cache(const char *mount_point,
|
|
attach_backend_t *backend_out,
|
|
int *unit_out) {
|
|
pthread_mutex_lock(&g_image_cache_mutex);
|
|
int entry_index = find_cache_index(NULL, mount_point);
|
|
if (entry_index < 0) {
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return false;
|
|
}
|
|
const struct ImageCache *entry = &g_image_cache[entry_index];
|
|
if (entry->backend == ATTACH_BACKEND_NONE || entry->unit_id < 0) {
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return false;
|
|
}
|
|
*backend_out = entry->backend;
|
|
*unit_out = entry->unit_id;
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return true;
|
|
}
|
|
|
|
bool resolve_image_source_from_mount_cache(const char *mount_point,
|
|
char *path_out,
|
|
size_t path_out_size) {
|
|
pthread_mutex_lock(&g_image_cache_mutex);
|
|
int entry_index = find_cache_index(NULL, mount_point);
|
|
if (entry_index < 0) {
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return false;
|
|
}
|
|
const struct ImageCache *entry = &g_image_cache[entry_index];
|
|
|
|
path_out[0] = '\0';
|
|
(void)strlcpy(path_out, entry->path, path_out_size);
|
|
pthread_mutex_unlock(&g_image_cache_mutex);
|
|
return true;
|
|
}
|