feat(storage/vfs): improve mountpoint table memory usage

This commit is contained in:
Tomáš Rohlínek 2025-01-24 10:23:00 +01:00
parent 23ce1cc47d
commit a45b12a68b
No known key found for this signature in database
GPG Key ID: BDE1CEDD10F7E372
2 changed files with 34 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -7,6 +7,7 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_vfs.h" #include "esp_vfs.h"
#include "esp_vfs_common.h" #include "esp_vfs_common.h"
#include <stddef.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -19,12 +20,12 @@ extern "C" {
#endif #endif
typedef struct vfs_entry_ { typedef struct vfs_entry_ {
int flags; /*!< ESP_VFS_FLAG_CONTEXT_PTR and/or ESP_VFS_FLAG_READONLY_FS or ESP_VFS_FLAG_DEFAULT */ int flags; /*!< ESP_VFS_FLAG_CONTEXT_PTR and/or ESP_VFS_FLAG_READONLY_FS or ESP_VFS_FLAG_DEFAULT */
const esp_vfs_fs_ops_t *vfs; // contains pointers to VFS functions const esp_vfs_fs_ops_t *vfs; // contains pointers to VFS functions
char path_prefix[ESP_VFS_PATH_MAX]; // path prefix mapped to this VFS void *ctx; // optional pointer which can be passed to VFS
size_t path_prefix_len; // micro-optimization to avoid doing extra strlen int offset; // index of this structure in s_vfs array
void* ctx; // optional pointer which can be passed to VFS size_t path_prefix_len; // micro-optimization to avoid doing extra strlen
int offset; // index of this structure in s_vfs array const char path_prefix[] __attribute__ ((counted_by (path_prefix_len))); // path prefix mapped to this VFS
} vfs_entry_t; } vfs_entry_t;
/** /**
@ -53,7 +54,7 @@ typedef struct vfs_entry_ {
* ESP_ERR_NO_MEM if too many VFSes are registered. * ESP_ERR_NO_MEM if too many VFSes are registered.
* ESP_ERR_INVALID_ARG if given an invalid parameter. * ESP_ERR_INVALID_ARG if given an invalid parameter.
*/ */
esp_err_t esp_vfs_register_common(const char *base_path, size_t len, const esp_vfs_t* vfs, void* ctx, int *vfs_index); esp_err_t esp_vfs_register_common(const char *base_path, size_t len, const esp_vfs_t *vfs, void *ctx, int *vfs_index);
/** /**
* Get vfs fd with given path. * Get vfs fd with given path.

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -395,20 +395,30 @@ fail:
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
static esp_err_t esp_vfs_register_fs_common(const char* base_path, size_t len, const esp_vfs_fs_ops_t* vfs, int flags, void* ctx, int *vfs_index) static esp_err_t esp_vfs_register_fs_common(
const char *base_path,
size_t base_path_len,
const esp_vfs_fs_ops_t *vfs,
int flags,
void *ctx,
int *vfs_index)
{ {
if (s_vfs_count >= VFS_MAX_COUNT) {
return ESP_ERR_NO_MEM;
}
if (vfs == NULL) { if (vfs == NULL) {
ESP_LOGE(TAG, "VFS is NULL"); ESP_LOGE(TAG, "VFS is NULL");
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
if (len != LEN_PATH_PREFIX_IGNORED) { if (base_path_len != LEN_PATH_PREFIX_IGNORED) {
/* empty prefix is allowed, "/" is not allowed */ /* empty prefix is allowed, "/" is not allowed */
if ((len == 1) || (len > ESP_VFS_PATH_MAX)) { if ((base_path_len == 1) || (base_path_len > ESP_VFS_PATH_MAX)) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
/* prefix has to start with "/" and not end with "/" */ /* prefix has to start with "/" and not end with "/" */
if (len >= 2 && ((base_path[0] != '/') || (base_path[len - 1] == '/'))) { if (base_path_len >= 2 && ((base_path[0] != '/') || (base_path[base_path_len - 1] == '/'))) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
} }
@ -426,23 +436,26 @@ static esp_err_t esp_vfs_register_fs_common(const char* base_path, size_t len, c
s_vfs_count++; s_vfs_count++;
} }
vfs_entry_t *entry = (vfs_entry_t*) heap_caps_malloc(sizeof(vfs_entry_t), VFS_MALLOC_FLAGS); size_t alloc_size = sizeof(vfs_entry_t)
+ (base_path_len == LEN_PATH_PREFIX_IGNORED ? 0 : base_path_len + 1);
vfs_entry_t *entry = (vfs_entry_t*) heap_caps_malloc(alloc_size, VFS_MALLOC_FLAGS);
if (entry == NULL) { if (entry == NULL) {
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
s_vfs[index] = entry; s_vfs[index] = entry;
if (len != LEN_PATH_PREFIX_IGNORED) {
strcpy(entry->path_prefix, base_path); // we have already verified argument length entry->path_prefix_len = base_path_len;
} else {
bzero(entry->path_prefix, sizeof(entry->path_prefix));
}
entry->path_prefix_len = len;
entry->vfs = vfs; entry->vfs = vfs;
entry->ctx = ctx; entry->ctx = ctx;
entry->offset = index; entry->offset = index;
entry->flags = flags; entry->flags = flags;
if (base_path_len != LEN_PATH_PREFIX_IGNORED) {
memcpy((char *)(entry->path_prefix), base_path, base_path_len + 1);
}
if (vfs_index) { if (vfs_index) {
*vfs_index = index; *vfs_index = index;
} }