Bug Report: MQX 4.1.1 MFS write does not update MQX_FILE size so fseek IO_SEEK_END does not work.

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Bug Report: MQX 4.1.1 MFS write does not update MQX_FILE size so fseek IO_SEEK_END does not work.

2,372 次查看
chrissolomon
Contributor III

Hi,

I have been doing some testing of the new MFS, verifying the functionality.

I think I have found a bug:

When a file is opened, the file MQX_FILE structure SIZE field is set to the current file size, however when the file is written to this field is not updated.

Here is an example of how this problem manifests:

Open a new file.

Write 100 bytes.

ftell will report 100

fseek IO_SEEK_END -10   -> Should position you at 90, but will actually fail with IO_ERROR since size is 0

ftell will still report 100, instead of 90.

I believe the problem is around line 821 of mfs_init.c.

There is an if statement checking for the case where the MFS_Write has returned MFS_NO_ERROR and errcode == MFS_EOF.

This is fine, except MFS_Write returns the number of bytes written, so if the file size is increased the file ptr is not updated.

Any suggestions?

Thanks

Chris

标签 (1)
标记 (3)
0 项奖励
回复
7 回复数

1,224 次查看
DavidS
NXP Employee
NXP Employee

Hi Chris,

My quick test seems to be working.  Are you using the same command as I am?

What I did was the following:

result = ftell(fd);//DES find file position

printf("\nftell result = %d", result);

printf("\nBacking up file pointer 10 bytes");

result = fseek(fd, result-10, IO_SEEK_END);//DES move from end-of-file back 10 bytes.

if(result != MQX_OK) {

   printf("\nERROR fseek'ing\n");

}

result = ftell(fd);//DES find file position

printf("\nupdated ftell result = %d", result);

I copied-n-pasted sh_write.c in the MFS and renamed it sh_write_ftell_fseek_ftell_test.c and modified it to test the ftell.

I added that file to the "mfs" folder in the shell MQX Component.

I modified the sh_mfs.h header to have extern of the Shell_write_ftell_fseek_ftell_test(int32_t argc, char *argv[] ); included.

RE-compile shell.

I am using the mfs_ramdisk example in the MFS folder.

I updated the shell_task.c so I would have a shell "write_ftell" command that I could run and forced example to use RAM disk and not MRAM.

Terminal output:

Demo start

Initialized Ram Disk to a:\

NOT A DOS DISK! You must format to continue.

Shell (build: Oct  6 2014)

Copyright (c) 2013 Freescale Semiconductor;

shell>

shell> format a: ramdisk

Formatting...

Done. Volume name is RAMDISK   

Free disk space: 1536 bytes

shell>

shell> write_ftell test100 100

ftell result = 100

Backing up file pointer 10 bytes

updated ftell result = 90

shell>


I ran this on the TWR-K60F120 tower kit.

Regards,

David

0 项奖励
回复

1,224 次查看
chrissolomon
Contributor III

Hi David,

in your test code, you are using

result = fseek(fd, result-10, IO_SEEK_END);

where result = 100, which is correctly reported by ftell after the 100 byte write since the location is updated correctly, so effectively:

result = fseek(fd, 90, IO_SEEK_END);

When you use IO_SEEK_END the seek is supposed to be relative to the end of the file, so this would set the location 90 bytes past the end of the file, so ftell should then report 190.

(What you have would work fine if you were using IO_SEEK_SET, that is supposed to be relative to the start of the file.)

If you want to get to a location of 90, the command should be

result = fseek(fd, -10, IO_SEEK_END);

However, since the SIZE element of the MQX_FILE structure is not updated, the calculation in io_fseek fails (and it returns IO_ERROR).

I'm pretty confident that's how it is supposed to work - here is the relevant code snippit from io_fseek :

    case IO_SEEK_END:

        if (offset < 0 && (file_ptr->SIZE < (_file_size) (-offset))) {

            return IO_ERROR;

        }

        file_ptr->LOCATION = file_ptr->SIZE + offset;

        break;

Looking at this code it seems that offset should be negative (which matched by understanding of the std lib documentation). There is error checking to confirm the magnitude of the negative offset doesn't exceed the size of the file.

BTW, I'm running my code on MQX 4.1.1 on a K70F120 based product.

Thanks

Chris

0 项奖励
回复

1,224 次查看
DavidS
NXP Employee
NXP Employee

Hi Chris,

Ok…you got me on that one. Saw results eyes wanted and didn’t let the brain do the work!

I do believe you first assessment is correct. If you change mfs_init.c at line 817 to following:

/* Check for EOF. The MFS EOF must be translated to the standard EOF */

#if 0 //DES 0=test, 1=default code

if (result == MFS_NO_ERROR && errcode == MFS_EOF)

#else

if (result == num && errcode != MFS_EOF) //DES should have been TRUE so file_ptr parameters get updated. Why not? The result==MFS_NO_ERROR makes no sense. Why not result==num? errcode deosn't make sense either.

#endif

{

file_ptr->FLAGS |= IO_FLAG_AT_EOF;

/* Update the file size in the old IO structure */

file_ptr->SIZE = handle->SIZE;

}

My test code seems to work for the various IO_SEEK #defines:

#define IO_SEEK_SET (1) /* Seek from start */

#define IO_SEEK_CUR (2) /* Seek from current location */

#define IO_SEEK_END (3) /* Seek from end */

My updated sh_write_ftell_fseek_ftell_test.c code has following update:

#if 1 //DES 1=test of ftell/fseek/ftell, 0=default code

result = ftell(fd); //DES find file position

printf("\nftell result = %d", result);

printf("\nBacking up file pointer 10 bytes");

result = fseek(fd, -10, IO_SEEK_END); //DES works...back up 10 bytes from EOF

if(result != MQX_OK) {

printf("\nERROR fseek'ing\n");

}

result = ftell(fd); //DES find file position

printf("\nupdated ftell result = %d", result);

result = fseek(fd, -10, IO_SEEK_CUR); //DES works...back up 10 bytes from current location

if(result != MQX_OK) {

printf("\nERROR fseek'ing\n");

}

result = ftell(fd); //DES find file position

printf("\nupdated ftell result = %d", result);

result = fseek(fd, +90, IO_SEEK_SET); //DES works...move 90 bytes from beginning of file

if(result != MQX_OK) {

printf("\nERROR fseek'ing\n");

}

result = ftell(fd); //DES find file position

printf("\nupdated ftell result = %d\n", result);

#endif

When I looked at the “fd” parameters all looked OK.

I will submit this to our MQX Development team to get confirmation this is correct and respond back.

Please give it a try and let me know.

Regards,

David

0 项奖励
回复

1,224 次查看
RuiFaria
Contributor III

Hello,

why is not like this?

    if (result >= 0 && errcode != MFS_EOF)

    {

        file_ptr->FLAGS |= IO_FLAG_AT_EOF;

        /* Update the file size in the old IO structure */

        file_ptr->SIZE = result;

    }

Freescale should release the patch 4.1.2 also and not only the new version 4.2.0, we can't be always updating MQX version in our Products.

Best Regards,

Rui Faria

0 项奖励
回复

1,224 次查看
chrissolomon
Contributor III

Hi David,

I gave that a test, and it seems to work, but I'm a little worried about corner cases, like if it can't write everything, result > 0, but not num?

I tried this - I think it should always work, and it passes my tests:

#if 0         //DES 0=test, 1=default code

    if (result == MFS_NO_ERROR && errcode == MFS_EOF)

    {

        file_ptr->FLAGS |= IO_FLAG_AT_EOF;

        /* Update the file size in the old IO structure */

        file_ptr->SIZE = handle->SIZE;

    }

#else

    /* Update the file size in the old IO structure */

    file_ptr->SIZE = handle->SIZE;

    if ( errcode == MFS_EOF)

    {

    file_ptr->FLAGS |= IO_FLAG_AT_EOF;

    }

#endif

The overhead of always updating the size is pretty minimal, so it's just translating the EOF.

What do you think?

Chris

0 项奖励
回复

1,224 次查看
RadekS
NXP Employee
NXP Employee

Thank you for your bug report.

Yes, you are right. This new bug (specific for MQX 4.1.0 for FRDMK64F/TWRK64F120M and MQX 4.1.1) was deported to code during preparation for SDK implementation.

Next MQX release will contain complete redesigned MFS subsystem which will solve this issue.


Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

1,224 次查看
DavidS
NXP Employee
NXP Employee

Hi Chris,

Run with it and I'll have the MQX Development team review and then will update the post.

Regards,

David

0 项奖励
回复