From 9702ed5257958cbdcd348fa76d8531f8d0d5fd77 Mon Sep 17 00:00:00 2001 From: Martin Vychodil Date: Tue, 7 Apr 2026 12:08:49 +0200 Subject: [PATCH 1/2] fix(fatfs): Fixed uninitialized FATFS pointer for already mounted path Co-authored-by: Cursor --- components/fatfs/vfs/esp_vfs_fat.h | 4 +++- components/fatfs/vfs/vfs_fat.c | 7 ++++++- components/fatfs/vfs/vfs_fat_spiflash.c | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/components/fatfs/vfs/esp_vfs_fat.h b/components/fatfs/vfs/esp_vfs_fat.h index b8ac7e625c1..6e0dd495d5f 100644 --- a/components/fatfs/vfs/esp_vfs_fat.h +++ b/components/fatfs/vfs/esp_vfs_fat.h @@ -63,7 +63,9 @@ typedef struct { * @param[out] out_fs pointer to FATFS structure which can be used for FATFS f_mount call is returned via this argument. * @return * - ESP_OK on success - * - ESP_ERR_INVALID_STATE if esp_vfs_fat_register was already called + * - ESP_ERR_INVALID_STATE if a filesystem is already registered at this base path. + * If @p out_fs is not NULL, @p *out_fs is set to the existing FATFS object so callers + * can run f_mount (e.g. remount the same path). * - ESP_ERR_NO_MEM if not enough memory or too many VFSes already registered */ esp_err_t esp_vfs_fat_register(const esp_vfs_fat_conf_t* conf, FATFS** out_fs); diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 4cac2facdb9..152343e13dd 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -179,6 +179,9 @@ esp_err_t esp_vfs_fat_register(const esp_vfs_fat_conf_t* conf, FATFS** out_fs) { size_t ctx = find_context_index_by_path(conf->base_path); if (ctx < FF_VOLUMES) { + if (out_fs) { + *out_fs = &s_fat_ctxs[ctx]->fs; + } return ESP_ERR_INVALID_STATE; } @@ -221,7 +224,9 @@ esp_err_t esp_vfs_fat_register(const esp_vfs_fat_conf_t* conf, FATFS** out_fs) //compatibility s_fat_ctx = fat_ctx; - *out_fs = &fat_ctx->fs; + if (out_fs) { + *out_fs = &fat_ctx->fs; + } return ESP_OK; } diff --git a/components/fatfs/vfs/vfs_fat_spiflash.c b/components/fatfs/vfs/vfs_fat_spiflash.c index b1764a049ac..8c8cf099af5 100644 --- a/components/fatfs/vfs/vfs_fat_spiflash.c +++ b/components/fatfs/vfs/vfs_fat_spiflash.c @@ -171,7 +171,7 @@ esp_err_t esp_vfs_fat_spiflash_mount_rw_wl(const char* base_path, char drv[3] = {(char)('0' + pdrv), ':', 0}; ESP_GOTO_ON_ERROR(ff_diskio_register_wl_partition(pdrv, *wl_handle), fail, TAG, "ff_diskio_register_wl_partition failed pdrv=%i, error - 0x(%x)", pdrv, ret); - FATFS *fs; + FATFS *fs = NULL; esp_vfs_fat_conf_t conf = { .base_path = base_path, .fat_drive = drv, @@ -366,7 +366,7 @@ esp_err_t esp_vfs_fat_spiflash_mount_ro(const char* base_path, char drv[3] = {(char)('0' + pdrv), ':', 0}; ESP_GOTO_ON_ERROR(ff_diskio_register_raw_partition(pdrv, data_partition), fail, TAG, "ff_diskio_register_raw_partition failed pdrv=%i, error - 0x(%x)", pdrv, ret); - FATFS *fs; + FATFS *fs = NULL; esp_vfs_fat_conf_t conf = { .base_path = base_path, .fat_drive = drv, From 872ca1fa3c45db6df7b89fd5dd59900ec47ba69d Mon Sep 17 00:00:00 2001 From: Martin Vychodil Date: Tue, 7 Apr 2026 12:15:51 +0200 Subject: [PATCH 2/2] fix(fatfs): Fixed VFS adapter early return paths Co-authored-by: Cursor --- components/fatfs/vfs/vfs_fat.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 152343e13dd..99052bfaf79 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -567,7 +567,12 @@ static ssize_t vfs_fat_pwrite(void *ctx, int fd, const void *src, size_t size, o f_res = f_write(file, src, size, &wr); if (((wr == 0) && (size != 0)) && (f_res == 0)) { errno = ENOSPC; - return -1; + ret = -1; + FRESULT seek_res = f_lseek(file, prev_pos); + if (seek_res != FR_OK) { + ESP_LOGE(TAG, "%s: f_lseek restore after ENOSPC write failed (fresult=%d)", __func__, seek_res); + } + goto pwrite_release; } if (f_res == FR_OK) { ret = wr; @@ -1014,7 +1019,7 @@ static void vfs_fat_seekdir(void* ctx, DIR* pdir, long offset) if (res != FR_OK) { ESP_LOGD(TAG, "%s: rewinddir fresult=%d", __func__, res); errno = fresult_to_errno(res); - return; + goto seekdir_done; } fat_dir->offset = 0; } @@ -1023,10 +1028,11 @@ static void vfs_fat_seekdir(void* ctx, DIR* pdir, long offset) if (res != FR_OK) { ESP_LOGD(TAG, "%s: f_readdir fresult=%d", __func__, res); errno = fresult_to_errno(res); - return; + goto seekdir_done; } fat_dir->offset++; } +seekdir_done: _lock_release(&fat_ctx->lock); }