Guide to Large Files

The enhanced file server supports large files, greater than 2GB, by introducing 64-bit variants of existing functions. This maintains binary and source compatibility.

Introduction

The file server client, file server and file systems have been modified to use 64-bit arguments and arithmetic. The overhead of these changes are small in relation to the number of calls per second for streaming read, write and recursive file access operations. These changes have no impact on performance.

The following components have been enhanced to support large file access:

  • file server client API

  • file server

  • FAT32 file system.

File server client API

The change to 64-bit file use is not automatic. Code must be modified to use 64-bit file support. Any code that is not modified will continue to operate in legacy 32-bit mode.

Applications that are not designed to handle large files may experience behavioural breaks. For example, unexpected return codes or values when an attempt is made to seek to the end of a large file using the 32-bit APIs, and code that sits in a loop counting bytes written may overflow if TInt32 values are used.

These values have been changed to support 64-bit operations:

  • the size of a file

  • the current position in a file

  • the length for lock and unlock operations on a file.

RFile64

The existing RFile APIs have not been changed but extended so that legacy code can be easily altered. The class RFile64 has been added that enables the 64-bit APIs for use by new applications.

The RFile64 class provides the following main functions:

A mechanism has been provided that assists the porting of code from 32-bit to 64-bit APIs. To assist migration, use the _F32_STRICT_64_BIT_MIGRATION macro to force compiler errors if TInt orTUint variables are used.
Note: This does not guarantee that all areas of code will be highlighted. For example, a function can operate on a large file using 32-bit APIs, which can only be guaranteed to be detected by close code inspection.

The legacy 32-bit versions of RFile::Seek() and RFile::Size() are privately overloaded so that any software that migrates from RFile to RFile64 without updating their code to use the TInt64 versions of these APIs will encounter build errors. This guarantees that 64-bit aware clients will use the correct APIs.

Compatibility

A file opened by a 32-bit client can also be opened by a client with 64-bit awareness, and as a result the size of this file can grow beyond the 2GB-1 boundary if the 64-bit client increases the size of the file. This can result in the client experiencing situations where an error (KErrTooBig, or a negative file size) is returned by calls to RFile::Size() or to RFile::Seek().

The 32-bit function RFile::Read() returns KErrTooBig when attempting to read from a position greater than 2GB–1. This did not occur before the File Server was enhanced as a large file could not be opened.

File server

The file server has been modified to handle 64-bit parameters from the user to the file system. Currently, the arguments representing file size, position and length for RFile::Lock() and RFile::UnLock() are stored in a TIpcArgs object and are sent to the server using RSessionBase::SendReceive() as a file server request.

As these parameters do not require more than 32-bits, they are packaged as TInt values in a TIpcArgs slot. When Lock() and UnLock() require 64-bit values for position, size and length, these values are packaged using a package descriptor that is stored in the TIpcArgs instead of the value itself.

On the file server side the following changes have been implemented:
  • The server now handles 64-bit wide IPC parameters from the client library, only when the value is greater than 32 bits.

  • File server side classes have been modified to use 64-bit file sizes. This includes changes to operations that enable file sharing, cache, file lock & asynchronous requests, position and lock/unlock section lengths.

  • Calls to the file system's 32-bit functions from within the file server have been replaced with calls to 64-bit variants.

See Interfacing File Systems to the 64-bit File Server.

IPC

64-Bit APIs require an additional IPC data transfer between file server & client when accessing file data beyond 4GB-1. This IPC overhead is expected to impose some degradation in performance when using cached I/O, particularly when issuing requests for small quantities of data (compared to the equivalent operations below the 4GB boundary and legacy APIs where no additional IPC is required).

FAT32 file system

The standard FAT32 file system only supports file sizes up to 4GB-1. The current CFatFileCB::MExtendedFileInterface restricts operations to sizes less than 2GB-1. The FAT32 file system has been modified to support files of sizes up to 4GB–1.

The CFatFileCB::MExtendedFileInterface implementation has been altered to allow operations up to 4GB–1. All signed int and TInt types are now treated as unsigned int and TUint to support large file access.

The CMountCB::MFileExtendedInterface class has been introduced along with the CFileCB::MExtendedFileInterface class to support reading large files from RFs, as described in the tutorials Using the CMountCB function ReadSectionL() and Using the CFileCB functions ReadL(), WriteL() and SetSizeL().