- SDK: 15.2
- SoftDevice: s140_nrf52_6.1.0
- FreeRTOS
- Hardware: nRF52840 (Custom boards)
- SD card formatted as FAT32 (No ExFAT)
Hello,
I have been stress testing the FatFS library provided in the Nordic SDK (Elm-Chan FatFs) using an 8 GB SD card. The directory structure is as follows:
/dir1/dir2/dir3
'dir3' contains 65534 files of size 12 KB. They each have unique files names but their contents are identical.
My code scans all files in the directory similar to the following (I am omitting f_opendir() etc as it is not related to the issue).
FRESULT fresult;
DIR dir;
FILINFO fileInfo;
while((fresult = f_readdir(&dir, &fileInfo)) == FR_OK)
{
if(fileInfo.fname[0] == NULL)
{
break; /* end of files */
}
printf("File name: %s", fileInfo.fname);
}
The issue is that this while() loop will never exit because f_readdir() will always return FR_OK. After digging into the FatFS library, I discovered the following:
FRESULT f_readdir (
DIR* dp, /* Pointer to the open directory object */
FILINFO* fno /* Pointer to file information to return */
)
{
FRESULT res;
FATFS *fs;
DEF_NAMBUF
res = validate(&dp->obj, &fs); /* Check validity of the directory object */
if (res == FR_OK) {
if (!fno) {
res = dir_sdi(dp, 0); /* Rewind the directory object */
} else {
INIT_NAMBUF(fs);
res = dir_read(dp, 0); /* Read an item */
if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */
if (res == FR_OK) { /* A valid entry is found */
get_fileinfo(dp, fno); /* Get the object information */
res = dir_next(dp, 0); /* Increment index for next */
if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory now */ <--------- ISSUE
}
FREE_NAMBUF();
}
}
LEAVE_FF(fs, res);
}
See the line above "if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory now */"
Looking into dir_next() you see the following:
ofs = dp->dptr + SZDIRE; /* Next entry */
if (!dp->sect || ofs >= (DWORD)((_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) return FR_NO_FILE; /* Report EOT when offset has reached max value */
Summary:
- dir_next() is returning FR_NO_FILE when it tries to increment the directory pointer because it now equals MAX_DIR.
- f_readdir() checks for FR_NO_FILE, and doesn't return it. Instead, it returns FR_OK.
- The while loop never exits and continues to read the same file over and over because the directory pointer cannot be incremented beyond MAX_DIR resulting in fresult always returning FR_OK.
Questions:
1. Is this a bug in the FatFs library, or is this intended behavior?
2. If a bug, how should this be fixed? If not a bug, what is the best practice to handle this scenario where a directory contains the maximum number of files supported by FAT32?
Thanks,
Derek