I tried to enumerate all the files on my sd card and get the long file names by the way through mfs using k70 with mqx 4.0.0. I just find it a rough work to get the long name of a specified file because it takes too much time.
In the _io_mfs_ioctl method, we can see the IO_IOCTL_GET_LFN' code. It disables the efficient code with #if 0 and just use MFS_get_lfn(drive_ptr, pathname, lfn_ptr->LONG_FILENAME) to search the entire fs to find the corresponding long file name.
I tried to enable the dummy code and disable the above MFS_get_lfn(drive_ptr, pathname, lfn_ptr->LONG_FILENAME). Using the MFS_SEARCH_PARAM variable obtained from last find file passed to ioctl() IO_IOCTL_GET_LFN, The result unexpectedly came wrong with no lfn . Something is wrong with this code or the parameter.
Then I checked the dir entries sector cached into memory, I can see that "entry_ptr" a pointer that should point to the short dir entry points to a wrong entry(points to an entry begin with 0x42 which is a tag of the end of long dir entry) .When the program goes on, the desired long dir entry pointer points to a short dir entry leading to a failed finding.Obviously it is an "off-one" issue and the parameter should be changed.
Actually, the DIR_ENTRY_INDEX in SEARCH_DATA is the next index to search and nont the current one, this can be verified in mfs_search.c line 641~645. So something need to be done to decrease the index.Note that you should store and restore the data you changed. I wrote a function MFS_Decrement_dir_index to do that and Insert it in my app.
Finally, I tried, It worked well. Worked code shows below
My app code:
lfn_data.PATHNAME = search_data->NAME;
lfn_data.LONG_FILENAME = (char_ptr)lfn;
lfn_data.SEARCH_DATA_PTR = search_data;
//store the data
tmp_pre_cluster = lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.PREV_CLUSTER;
tmp_cluster = lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER;
tmp_index = lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX;
//current index indicates the next directory entry, so we decrement it here
MFS_Decrement_dir_index(
&lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER,
&lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX,
&lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.PREV_CLUSTER);
error = ioctl(fs_ptr, IO_IOCTL_GET_LFN, (pointer) (&lfn_data));
// restore
lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.PREV_CLUSTER = tmp_pre_cluster;
lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER = tmp_cluster;
lfn_data.SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX = tmp_index;
Mfs driver code:
case IO_IOCTL_GET_LFN: MFS_lock(file_ptr, &drive_ptr);
{
MFS_GET_LFN_STRUCT_PTR lfn_ptr = ((MFS_GET_LFN_STRUCT_PTR) param_ptr);
char_ptr pathname = MFS_Parse_Out_Device_Name(lfn_ptr->PATHNAME);
#if 0
result = MFS_get_lfn(drive_ptr, pathname, lfn_ptr->LONG_FILENAME);
#endif
#if 1 //change from 0 to1
// _mfs_error result;
MFS_DIR_ENTRY_PTR entry_ptr;
if ( lfn_ptr->SEARCH_DATA_PTR )
{
entry_ptr =
MFS_Read_directory_sector(drive_ptr,lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER,
INDEX_TO_SECTOR(lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX), &result);
if ( (result== MFS_NO_ERROR && entry_ptr!=NULL) )
{
entry_ptr += INDEX_TO_OFFSET (lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX) ;
result = MFS_get_lfn_of_entry(drive_ptr,entry_ptr,
lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER,
lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX ,
lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.PREV_CLUSTER,
lfn_ptr->LONG_FILENAME);
}
}
else
{
result = MFS_get_lfn(drive_ptr, pathname, lfn_ptr->LONG_FILENAME);
}
}
MFS_Decrement_dir_index() implementation is below
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name : MFS_Decrement_dir_index
* Returned Value : uint_32 error_code
* Comments :
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Decrement_dir_index
(
uint_32_ptr cluster_ptr, /*[IN/OUT] the initial/next cluster # */
uint_32_ptr index_ptr, /*[IN/OUT] the initial/next index */
uint_32_ptr prev_cluster_ptr /*[IN/OUT] the prev cluster # */
)
{
uint_32 index;
uint_32 cluster;
_mfs_error error_code;
error_code = MFS_NO_ERROR;
index = *index_ptr;
cluster = *cluster_ptr;
if(0 == index)
{
if ( *prev_cluster_ptr != 0 )
{
//restore prev cluster to current cluster
cluster = *prev_cluster_ptr;
index = 127;
}
else
{
error_code = MFS_INVALID_CLUSTER_NUMBER;
return error_code;
}
}
else
{
index --;
}
if ( (cluster != *cluster_ptr) )
{
if ( prev_cluster_ptr != NULL )
{
*prev_cluster_ptr = 0; //now *prev_cluster_ptr set to 0
}
}
//error is here when index is 138 ,above does not executed and wrongly increased
*index_ptr = index;
*cluster_ptr = cluster;
return(error_code);
}
#endif
Test result:
Sample: 27 directories and 803 files, directory depth is 4.
Currently time cost
Only SLN SLN&LFN
216ms 275ms
Previously the time
Only SLN SLN&LFN
216ms 751ms