+FAT ff_filelength() returns Error when file length is >2GB

sonycman wrote on Monday, June 05, 2017:

Hello.

The ff_filelength() function incorrectly interprets big files (>2GB) length as error and returns zero.
This is because it uses MSB of the length value returned by FF_FileSize() as an error flag, which in case of the big files leads to misinterpretation of correct value as an erratic.

Regards
Vladimir.

heinbali01 wrote on Tuesday, June 06, 2017:

Vladimir, this is indeed something to be finished: files longer than 2 GB.

Throughout the library, signed 32-bit values are used to indicate the length, and negative values are interpreted as an error.

lseek also has an intrinsic problem:

    long lseek(int fd, long offset, int whence);

FreeRTOS+TCP is using the same syntax for ff_fseek().

The Posix varian is ok, if off_t is a 64-bit signed integer:

    off_t lseek(int fd, off_t offset, int whence);

The +FAT library will not force people to include 64-bit arithmetic.

Right now I have a 2 GB file ( -2,147,483,648 bytes :slight_smile: ) on an SD-card and I will test it. To be continued.

sonycman wrote on Tuesday, June 06, 2017:

Hello, Hein
Thanks for an explanation.

I understand, that big files support is not so important for the embedded systems.
Its not needed in my case too.

But glad to hear such a support might be available one day in the future :slight_smile:

heinbali01 wrote on Tuesday, June 06, 2017:

All right, I made some minor changes: ff_filelength() will return correct values for files between 0 bytes and 4 GB.

A return value of 0 can mean two things: the size is either 0, or the handle is invalid.

size_t uxLength;

    /* Clear errno. */
    stdioSET_ERRNO( 0 );
    uxLength = ff_filelength( pxFile );

    if( ( uxLength != 0 ) || ( stdioGET_ERRNO() == 0 ) )
    {
        /* Length equals to uxLength. */
    }
    else
    {
        /* Invalid handle. */
    }

Also I introduced a new low-level function that splits up the result and the file length:

    /* Use the following function in case files may get larger than 2  GB. */
    int32_t FF_GetFileSize( FF_FILE *pFile, uint32_t *pulSize );

And more importantly: FF_Seek() now works correctly with sizes and offsets larger than 2GB.

Here below I attach 3 files, which are a copy of the ‘160919’ release along with mentioned changes.

    ff_file.c
    ff_stdio.c
    include/ff_file.h
    

Hein Tibosch

sonycman wrote on Wednesday, June 07, 2017:

Thanks a lot, Hein!
This is the best support I have ever seen!
My respects!