mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feat/optimize_vfs_mountpoint_table' into 'master'
feat(storage/vfs): improve mountpoint table memory usage Closes IDF-12560 See merge request espressif/esp-idf!36613
This commit is contained in:
commit
8606eb43f7
@ -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, contains length of the string, not the size of path_prefix array */
|
||||||
int offset; // index of this structure in s_vfs array
|
const char path_prefix[]; /*!< 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.
|
||||||
|
@ -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,38 @@ 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 bool is_path_prefix_valid(const char *path, size_t length) {
|
||||||
|
return (length >= 2)
|
||||||
|
&& (length <= ESP_VFS_PATH_MAX)
|
||||||
|
&& (path[0] == '/')
|
||||||
|
&& (path[length - 1] != '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t esp_vfs_register_fs_common(
|
||||||
|
const char *base_path,
|
||||||
|
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) {
|
size_t base_path_len = 0;
|
||||||
/* empty prefix is allowed, "/" is not allowed */
|
const char *_base_path = "";
|
||||||
if ((len == 1) || (len > ESP_VFS_PATH_MAX)) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
if (base_path != NULL) {
|
||||||
}
|
base_path_len = strlen(base_path);
|
||||||
/* prefix has to start with "/" and not end with "/" */
|
_base_path = base_path;
|
||||||
if (len >= 2 && ((base_path[0] != '/') || (base_path[len - 1] == '/'))) {
|
|
||||||
|
if (base_path_len != 0 && !is_path_prefix_valid(base_path, base_path_len)) {
|
||||||
|
ESP_LOGE(TAG, "Invalid path prefix");
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,23 +444,21 @@ 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);
|
vfs_entry_t *entry = heap_caps_malloc(sizeof(vfs_entry_t) + base_path_len + 1, 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 == NULL ? LEN_PATH_PREFIX_IGNORED : 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;
|
||||||
|
|
||||||
|
memcpy((char *)(entry->path_prefix), _base_path, base_path_len + 1);
|
||||||
|
|
||||||
if (vfs_index) {
|
if (vfs_index) {
|
||||||
*vfs_index = index;
|
*vfs_index = index;
|
||||||
}
|
}
|
||||||
@ -457,8 +473,13 @@ esp_err_t esp_vfs_register_fs(const char* base_path, const esp_vfs_fs_ops_t* vfs
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base_path == NULL) {
|
||||||
|
ESP_LOGE(TAG, "base_path cannot be null");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags & ESP_VFS_FLAG_STATIC)) {
|
if ((flags & ESP_VFS_FLAG_STATIC)) {
|
||||||
return esp_vfs_register_fs_common(base_path, strlen(base_path), vfs, flags, ctx, NULL);
|
return esp_vfs_register_fs_common(base_path, vfs, flags, ctx, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_vfs_fs_ops_t *_vfs = esp_vfs_duplicate_fs_ops(vfs);
|
esp_vfs_fs_ops_t *_vfs = esp_vfs_duplicate_fs_ops(vfs);
|
||||||
@ -466,7 +487,7 @@ esp_err_t esp_vfs_register_fs(const char* base_path, const esp_vfs_fs_ops_t* vfs
|
|||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t ret = esp_vfs_register_fs_common(base_path, strlen(base_path), _vfs, flags, ctx, NULL);
|
esp_err_t ret = esp_vfs_register_fs_common(base_path, _vfs, flags, ctx, NULL);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
esp_vfs_free_fs_ops(_vfs);
|
esp_vfs_free_fs_ops(_vfs);
|
||||||
return ret;
|
return ret;
|
||||||
@ -487,13 +508,29 @@ esp_err_t esp_vfs_register_common(const char* base_path, size_t len, const esp_v
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len != LEN_PATH_PREFIX_IGNORED) {
|
||||||
|
if (base_path == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Path prefix cannot be NULL");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is for backwards compatibility
|
||||||
|
if (strlen(base_path) != len) {
|
||||||
|
ESP_LOGE(TAG, "Mismatch between real and given path prefix lengths.");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// New API expects NULL in this case
|
||||||
|
base_path = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
esp_vfs_fs_ops_t *_vfs = NULL;
|
esp_vfs_fs_ops_t *_vfs = NULL;
|
||||||
esp_err_t ret = esp_vfs_make_fs_ops(vfs, &_vfs);
|
esp_err_t ret = esp_vfs_make_fs_ops(vfs, &_vfs);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = esp_vfs_register_fs_common(base_path, len, _vfs, vfs->flags, ctx, vfs_index);
|
ret = esp_vfs_register_fs_common(base_path, _vfs, vfs->flags, ctx, vfs_index);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
esp_vfs_free_fs_ops(_vfs);
|
esp_vfs_free_fs_ops(_vfs);
|
||||||
return ret;
|
return ret;
|
||||||
@ -551,7 +588,7 @@ esp_err_t esp_vfs_register_fs_with_id(const esp_vfs_fs_ops_t *vfs, int flags, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
*vfs_id = -1;
|
*vfs_id = -1;
|
||||||
return esp_vfs_register_fs_common("", LEN_PATH_PREFIX_IGNORED, vfs, flags, ctx, vfs_id);
|
return esp_vfs_register_fs_common(NULL, vfs, flags, ctx, vfs_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_vfs_register_with_id(const esp_vfs_t *vfs, void *ctx, esp_vfs_id_t *vfs_id)
|
esp_err_t esp_vfs_register_with_id(const esp_vfs_t *vfs, void *ctx, esp_vfs_id_t *vfs_id)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user