MFS LOST_CHAIN problem and possible errors on MQX 4.2.0.1/2 patches

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MFS LOST_CHAIN problem and possible errors on MQX 4.2.0.1/2 patches

Jump to solution
2,145 Views
lfschrickte
Contributor IV

Hi,

I'm looking for the reason of many LOST_CHAIN errors happening in a FTPSRV application and, while looking, spotted 2 inconsistencies in the MQX 4.2.0.1/2 patches that got my attention:

1. MQX-5639

The PDF says that the line:

     else if (sp_ptr->ATTRIBUTE & MFS_SEARCH_SUBDIR)

should be change to:

else if ((sp_ptr->ATTRIBUTE & 0x3F) == MFS_SEARCH_SUBDIR)

but this is NOT what the patch does!

The patch changes the order of condition checking and also the following line:

else if (sp_ptr->ATTRIBUTE & MFS_SEARCH_NORMAL)

to

     else if ((sp_ptr->ATTRIBUTE & 0x3F) == MFS_SEARCH_NORMAL)

So - which line should be changed? The one containing SEARCH_SUBDIR or the one containing SEARCH_NORMAL, or both? Which one is right - the PDF, the patch, or neither of them? As the PDF mentions the MFS_SEARCH_SUBDIR in the issue explanation, I suspect the patch may not be correct!

2. MQX-5537

In many places this patch changes the:

sector_count--; 

line of code to outside of the nonzero checking condition due to a +1/-1 error - however there is a place (that looks important) in which it doesn't modify: function MFS_lfn_chain_extract in file mfs_lfn.c

Was that meant to be in this way or did you miss this change?

---------------

I'm having some trouble with MFS - some files are not being found while I'm performing a FTP upload through RTCS app ftpsrv. I'm debugging it and the error returned by MQX when trying to fopen the file is 0x30F0 - which is, according to mqx.h, FS_LOST_CHAIN - and this is the reason I'm looking for help. I've also experienced some other weird behavior on MFS which I couldn't explain and may be related to this, but I couldn't get more clues (the errors happened on production boards). I've already tried correcting the lfn_chain_extract function already according to MQX-5537 comments above, but it didn't help

UPDATE: I've just figured out what the problem probably is about - I just can't create directories whose filename has more than 8 characters! To test it, I've just executed the following command on my httpd dir (my shell is a regular MQX Shell, as in example supplied in MQX files):

shell> pwd

a:\httpd

shell> mkdir a2345678

shell> cd a2345678

shell> write a.txt 1

shell> type a.txt

0

shell> del a.txt

shell> cd ..

shell> rmdir a2345678

shell> mkdir a23456789

shell> cd a23456789

shell> write a.txt 1

Error, unable to open file a.txt

shell> dir

.                   0 07-20-2016 18:35:48     D  .

..                  0 07-20-2016 18:35:48     D  ..

Before you ask, I've already applied the MQX 4.2.0.2 fixes a long time ago, including theextra sector_count-- not included in the patch.

Any help is appreciated. I assume I'm having trust issues with MFS due to these sporadic problems - do anyone have any suggestion on changing it by other FAT implementation (without spending one month on it)?

Thank you very much!

Regards,

Luiz Fernando

Labels (1)
Tags (1)
1 Solution
1,590 Views
lfschrickte
Contributor IV

Hi, I've changed some of MFS code and now things are working well.

I'm not sure if any of these changes may affect other functionalities, but I've already tested the rest of my application and things look fine.

I'm posting the changes here to help others and luckily for someone on NXP to check.

The problem is on the mfs_search.c file, more specifically in the MFS_Find_directory_entry function. I've found two bugs:

1. Even the filename being "invalid" for the 8.3 standard, the first search for-loop step considers the function passed attributes instead of looking for LFN entries. This is probably NOT the cause of my problem, but (correct me if I'm wrong) can cause a LFN entry to be missed. In order to fix it, I've the replaced the following lines in the beginning of the function:

        /* We also need special treatement for a directory name */

        if (attribute == (ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME))

        {

            attribute = MFS_ATTR_LFN;

            dirname = 1;

        }

by:

        attribute = MFS_ATTR_LFN; /* added by LFS - 2016-07-20 */

Why? If the file or directory being searched has an invalid 8.3 name - we MUST find a LFN entry in order to find it - so that condition makes no sense.

The dirname var is originally used later to restore the dir search attributes, however the second problem (the root cause of the problem reported in this topic) solution makes it useless.

2. In the first search loop the attribute parm being searched is changed to the LFN pattern if the file being searched has invalid 8.3 name - but the original attribute being searched is NOT saved anywhere! As the attribute being passed to the function should be used in order to check the 8.3 entry pointed by the LFN entries, the function can't just discard it! Explaining it better - when looking for a dirname which qualifies as LFN, the following steps were being executed:

1. The attribute passed by the function call is being replaced by the LFN pattern in the firstentry that didn't match what we are looking for - after that only LFN entries are being checked - according to the following lines

                              if (MFS_Attribute_match(mqx_dtohc(dir_entry_ptr->ATTRIBUTE),

                                  attribute) == true)

                              {

                               ... /*checking code here */

                              } else

                               {

                              if (lfn_flag)

                            {

                                attribute = MFS_ATTR_LFN;

                                lfn_ptr = file_ptr + lfn_len; /* reset ptr */

                                maybe = true;

                                found_lfn = false;

                            }

                              }

2. The function finds the LFN entry matching the name being searched (fine) and marks the flag to check the next entry for 8.3 matching in the next loop (found_lfn). Notice that the attribute value is not being reverted to the attributes being searched - it keeps the LFN bits marked - except when the attribute was being restored to a dir search - and this happens if, and only if, the function call was looking ONLY for dirs (dirname set to 1 on function beginning only if attribute == (ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME)). This is not the case when looking for dirs or files (usual search).

                                    if (lfn_ptr == file_ptr)

                                    {

                                        found_lfn = true;

                                        if (dirname)

                                        {

                                            attribute = ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME;

                                        }

                                    }

3. After that the next entry is the 8.3 entry corresponding to the search (not LFN) - but as it is searching for LFN attribute entries only, the file entry was never being found! The following condition never holds in the loop beginning:

if (MFS_Attribute_match(mqx_dtohc(dir_entry_ptr->ATTRIBUTE),

                                                attribute) == true)

So, for error 2, what have I changed (the changed file is attached):

1. On function beginning I save the attribute parameter to a var (original_attribute):

    unsigned char original_attribute = attribute;

2. If we are looking for a LFN entry, the attribute being searched is set to MFS_ATTR_LFN (as described in the fix for problem 1)

3. When the LFN name is found (in one or more entries), I revert the attribute back to the original function call:

                                    if (lfn_ptr == file_ptr)

                                    {

                                        found_lfn = true;

                                    //    if (dirname)

                                    //    {

                                    //        attribute = ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME;

                                     //   }

                                        attribute = original_attribute;

                                    }

4. I've also removed the dirname var (as it is useless now).

If in the next loop step the file attributes don't match the ones being searched - it is reverted back to MFS_ATTR_LFN and the search continues.

The corrected mfs_search.c file is attached - I'll be grateful if any of you with knowledge about FAT32 can have a look. I've spotted some other coding bad practices, but didn't change them in order to avoid inserting any bug.

After these changes my FTPSRV is working like a charm.

Thanks

Luiz Fernando

p.s.: I'm still waiting for answers about the MQX 4.2.0.2 patch posted in the original topic

View solution in original post

5 Replies
1,591 Views
lfschrickte
Contributor IV

Hi, I've changed some of MFS code and now things are working well.

I'm not sure if any of these changes may affect other functionalities, but I've already tested the rest of my application and things look fine.

I'm posting the changes here to help others and luckily for someone on NXP to check.

The problem is on the mfs_search.c file, more specifically in the MFS_Find_directory_entry function. I've found two bugs:

1. Even the filename being "invalid" for the 8.3 standard, the first search for-loop step considers the function passed attributes instead of looking for LFN entries. This is probably NOT the cause of my problem, but (correct me if I'm wrong) can cause a LFN entry to be missed. In order to fix it, I've the replaced the following lines in the beginning of the function:

        /* We also need special treatement for a directory name */

        if (attribute == (ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME))

        {

            attribute = MFS_ATTR_LFN;

            dirname = 1;

        }

by:

        attribute = MFS_ATTR_LFN; /* added by LFS - 2016-07-20 */

Why? If the file or directory being searched has an invalid 8.3 name - we MUST find a LFN entry in order to find it - so that condition makes no sense.

The dirname var is originally used later to restore the dir search attributes, however the second problem (the root cause of the problem reported in this topic) solution makes it useless.

2. In the first search loop the attribute parm being searched is changed to the LFN pattern if the file being searched has invalid 8.3 name - but the original attribute being searched is NOT saved anywhere! As the attribute being passed to the function should be used in order to check the 8.3 entry pointed by the LFN entries, the function can't just discard it! Explaining it better - when looking for a dirname which qualifies as LFN, the following steps were being executed:

1. The attribute passed by the function call is being replaced by the LFN pattern in the firstentry that didn't match what we are looking for - after that only LFN entries are being checked - according to the following lines

                              if (MFS_Attribute_match(mqx_dtohc(dir_entry_ptr->ATTRIBUTE),

                                  attribute) == true)

                              {

                               ... /*checking code here */

                              } else

                               {

                              if (lfn_flag)

                            {

                                attribute = MFS_ATTR_LFN;

                                lfn_ptr = file_ptr + lfn_len; /* reset ptr */

                                maybe = true;

                                found_lfn = false;

                            }

                              }

2. The function finds the LFN entry matching the name being searched (fine) and marks the flag to check the next entry for 8.3 matching in the next loop (found_lfn). Notice that the attribute value is not being reverted to the attributes being searched - it keeps the LFN bits marked - except when the attribute was being restored to a dir search - and this happens if, and only if, the function call was looking ONLY for dirs (dirname set to 1 on function beginning only if attribute == (ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME)). This is not the case when looking for dirs or files (usual search).

                                    if (lfn_ptr == file_ptr)

                                    {

                                        found_lfn = true;

                                        if (dirname)

                                        {

                                            attribute = ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME;

                                        }

                                    }

3. After that the next entry is the 8.3 entry corresponding to the search (not LFN) - but as it is searching for LFN attribute entries only, the file entry was never being found! The following condition never holds in the loop beginning:

if (MFS_Attribute_match(mqx_dtohc(dir_entry_ptr->ATTRIBUTE),

                                                attribute) == true)

So, for error 2, what have I changed (the changed file is attached):

1. On function beginning I save the attribute parameter to a var (original_attribute):

    unsigned char original_attribute = attribute;

2. If we are looking for a LFN entry, the attribute being searched is set to MFS_ATTR_LFN (as described in the fix for problem 1)

3. When the LFN name is found (in one or more entries), I revert the attribute back to the original function call:

                                    if (lfn_ptr == file_ptr)

                                    {

                                        found_lfn = true;

                                    //    if (dirname)

                                    //    {

                                    //        attribute = ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME;

                                     //   }

                                        attribute = original_attribute;

                                    }

4. I've also removed the dirname var (as it is useless now).

If in the next loop step the file attributes don't match the ones being searched - it is reverted back to MFS_ATTR_LFN and the search continues.

The corrected mfs_search.c file is attached - I'll be grateful if any of you with knowledge about FAT32 can have a look. I've spotted some other coding bad practices, but didn't change them in order to avoid inserting any bug.

After these changes my FTPSRV is working like a charm.

Thanks

Luiz Fernando

p.s.: I'm still waiting for answers about the MQX 4.2.0.2 patch posted in the original topic

1,590 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi Luiz Fernando:

Thank you very much for your feedback about MFS.

About MQX-5639

I think the description in pdf is not clear. It fixed some combinations of search attributes issue, it includes MFS_SEARCH_NORMAL and MFS_SEARCH_SUBDIR.

For MFS_SEARCH_NORMAL,   it's value is 0x00    (in mfs.h    #define MFS_SEARCH_NORMAL 0x00)

so

else if (sp_ptr->ATTRIBUTE & MFS_SEARCH_NORMAL)

should be changed to

else if ((sp_ptr->ATTRIBUTE & 0x3F) == MFS_SEARCH_NORMAL)

For your next question, I need some time to reproduce your issue, I will get back to you when I have the results.

Regards

Daniel

1,590 Views
lfschrickte
Contributor IV

Hi,

Could you reproduce the problem and check my solution?

Thank you very much!

Regards

Luiz

0 Kudos
Reply
1,590 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi Luiz:

I tried  the shell demo with your commands on TWR-K64 borad, it can work in my side.

C:\Freescale\Freescale_MQX_4_2\rtcs\examples\shell

\pastedImage_0.png

I remember that can't create directories whose name is more than 8 characters is a fixed issue in MQX 4.2.

Regards

Daniel

0 Kudos
Reply
1,590 Views
lfschrickte
Contributor IV

Hi Mr. Chen,

I appreciate your feedback!

I don't know how to proceed with this question as here in my system, using mqx + mfs 4.2 (both patched regarding MFS issues), the problem persists and could only be solved by changing the code as I've explained in the first response in this topic.

As conceptually both errors I've found are real, and after changing the code my original question is solved, I'll mark that answer as right, hoping somebody else can confirm the issues and find this useful!

If you have any other comments about the changes I've proposed I'll be glad too, as I think they may be useful during MQXv5 development.

Thank you very much for your attention!

Luiz Fernando

0 Kudos
Reply