I came across this problem when accessing a faulty directory on my USB.
When I tried to do ls -al under this directory or rm -rf this directory, an EIO error was thrown.
I added debug information and found out the EIO error was from the code below:
Function call trace: fuse_exfat_readdir->exfat_opendir->exfat_cache_directory->readdir->parse_file_entry->parse_file_entries->check_entries
The check_entries() function (node.c:165-207) performs strict validation:
// node.c:171-204
/* check transitions between entries types */
for (i = 0; i < n + 1; previous = current, i++) {
// Validates entry type transitions:
// - EXFAT_ENTRY_NONE -> EXFAT_ENTRY_FILE
// - EXFAT_ENTRY_FILE -> EXFAT_ENTRY_FILE_INFO
// - EXFAT_ENTRY_FILE_INFO -> EXFAT_ENTRY_FILE_NAME
// - EXFAT_ENTRY_FILE_NAME -> EXFAT_ENTRY_FILE_NAME or EXFAT_ENTRY_NONE
// ...
if (!valid) {
exfat_error("unexpected entry type %#x after %#x at %d/%d",
current, previous, i, n);
return false;
}
}
This error is probably caused by corrupted entry data on disk due to unknown reasons yet.
However, I tried to do the same thing on linux kernel's version of exfat and found the behaviors were different: ls -al can be performed under this faulty directory, rm -rf threw the error of ENOTEMPTY.
I looked the code and discovered that linux kernal handles this error differently:
- Linux kernel exfat: Skips corrupted entries and continues reading, showing subsequent valid files with code implementation as such:
exfat_readdir() (dir.c:68):
// dir.c:121-134
ep = exfat_get_dentry(sb, &clu, i, &bh);
if (!ep)
return -EIO; // Read error, but handled by caller
type = exfat_get_entry_type(ep);
if (type == TYPE_UNUSED) {
brelse(bh);
break;
}
if (type != TYPE_FILE && type != TYPE_DIR) {
brelse(bh);
continue; // Skip invalid entry types, continue reading
}
// Process file/directory entry...
- fuse-exfat: Returns -EIO error immediately upon encountering any corrupted entry, making all subsequent files inaccessible with code implementation aforementioned.
I think it is worthwhile to consider to align fuse-exfat behavior with the linux kernel, because under this circumstance, linux kernel's version of "best effort" approach seems to make more sense and provides better user experience.
I came across this problem when accessing a faulty directory on my USB.
When I tried to do
ls -alunder this directory orrm -rfthis directory, an EIO error was thrown.I added debug information and found out the EIO error was from the code below:
Function call trace:
fuse_exfat_readdir->exfat_opendir->exfat_cache_directory->readdir->parse_file_entry->parse_file_entries->check_entriesThe
check_entries()function (node.c:165-207) performs strict validation:This error is probably caused by corrupted entry data on disk due to unknown reasons yet.
However, I tried to do the same thing on linux kernel's version of exfat and found the behaviors were different:
ls -alcan be performed under this faulty directory,rm -rfthrew the error of ENOTEMPTY.I looked the code and discovered that linux kernal handles this error differently:
exfat_readdir()(dir.c:68):I think it is worthwhile to consider to align fuse-exfat behavior with the linux kernel, because under this circumstance, linux kernel's version of "best effort" approach seems to make more sense and provides better user experience.