esp_vfs_fat_spiflash_format_rw_wl formats wrong partition (IDFGH-11404) #12542
Labels
Resolution: NA
Issue resolution is unavailable
Status: Done
Issue is done internally
Type: Bug
bugs in IDF
Answers checklist.
IDF version.
v5.3-dev-222-gb90dfe0759
Espressif SoC revision.
ESP32-S3
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
Custom Board
Power Supply used.
USB
What is the expected behavior?
I expected the ESP-IDF function
esp_vfs_fat_spiflash_format_rw_wl
to format the partition identified by the suppliedpartition_label
.What is the actual behavior?
Instead, the ESP-IDF function
esp_vfs_fat_spiflash_format_rw_wl
formats an SPI flash filesystem that has previously been mounted from a Micro SD card.Steps to reproduce.
esp_vfs_fat_sdspi_mount
to mount an existing FAT filesystem located on an SPI flash Micro SD card (e.g. /sdcard)esp_vfs_fat_spiflash_format_rw_wl
to format a new FAT filesystem on an internal SPI flash memory partition (e.g. /local)esp_vfs_fat_spiflash_format_rw_wl
does not return in a timely mannerDebug Logs.
More Information.
It looks like the problem is in the implementation of the ESP-IDF
esp_vfs_fat_spiflash_format_rw_wl
function in theesp-idf/components/fatfs/vfs/vfs_fat_spiflash.c
module.This module generally uses the following pattern to initialize a null terminated three byte drive designator string:
char drv[3] = {(char)('0' + pdrv), ':', 0};
This converts
pdrv
to a digit starting at '0' and assigns it to the first character in the string.In the case of the failing module, instead of initializing
drv
using the above single statement approach, it uses a two statement approach. The first statement consists of:char drv[3] = {0, ':', 0};
Later, the second statement consists of:
drv[1] = (char)('0' + s_ctx[id]->pdrv);
The first statement assigns a null terminator to the first character of
drv
(i.e. the byte at index 0), creating an empty string.The second statement assigns a drive digit to the second character of the string (i.e. the byte at index 1). However, because the first byte is the null terminator, this has no effect and it's still an empty string.
Following the second statement,
esp_vfs_fat_spiflash_format_rw_wl
calls:f_mount(0, drv, 0);
This function (
f_mount
) callsget_ldnumber
to convert the value indrv
back to a number. Functionget_ldnumber
validates for aNULL
drive designator, but it doesn't validate for an empty drive designator, and it returns 0 as the drive instead of an error.At this point,
esp_vfs_fat_spiflash_format_rw_wl
callsf_mkfs
to create a file system, passing adrv
value of 0 (the already mounted existing SD Card filesystem) instead of 1 (the local flash filesystem we want to flash).This wipes out the existing SD filesystem.
The simplest fix is to change the errant line from:
drv[1] = (char)('0' + s_ctx[id]->pdrv);
to:
drv[0] = (char)('0' + s_ctx[id]->pdrv);
I tried this and it fixes the problem.
Another alternative would be to combine the
drv
declaration and initialization statements by removing the declaration and replacing the initialization with a single statement that both declares and initializesdrv
(as is found elsewhere in the module):char drv[3] = {(char)('0' + s_ctx[id]->pdrv), ':', 0};
I'm happy to provide a pull request with this change.
However, it's worth noting there are other code quality issues in this module (e.g.
get_ldnumber
checks forNULL
string, but not empty string;esp_vfs_fat_spiflash_format_rw_wl
doesn't checkf_mount
return code). These should probably be added to a tech debt issue, if one exists.The text was updated successfully, but these errors were encountered: