Caching is a mechanism used to increase performance by optimizing access to commonly-used data or information. The CBFS class provides caching functionality for three distinct areas:
- File data caching
- File metadata caching
- Nonexistent file information caching
Each virtual drive can be individually configured to use all, some, or none of these caches; please refer to the sections below for more information about each one.
File Data Caching
The CBFS class can employ a file data cache to help decrease the ReadFile and WriteFile events' rate of fire. There are three different file data cache implementations available: the Windows file management system cache, which is built into Windows itself; and the internal kernel- and user mode caches, which are implemented using the CBFS class and its system driver.
At a basic level, all three cache implementations work by storing blocks of file data in memory pages (which may, or may not, be swappable), and use some sort of LRU-based cache replacement algorithm to decide which pages to discard first (when necessary). Implementation-specific information is discussed in more detail below.
For each virtual drive, the FileCache property controls whether file data caching is enabled and specifies which file data cache implementation to use; by default, file data caching is enabled, and the system's cache implementation is used.
The FileCachePolicyWriteThrough configuration setting controls the behavior of the driver with regards to writing file data. When the setting is enabled, the driver will fire WriteFile as soon as the data has been cached to ensure that it is written out to storage as soon as the write request is received. When the setting is disabled (default), the data is cached, and flushed out to storage later; this causes write operations to appear to finish very quickly, but since some operations (e.g., file copying) require a flushing step, they can appear to get "stuck" at the last moment as flushing occurs.
If the writing process opens a file with FILE_FLAG_WRITE_THROUGH option, the system and the driver behave as if FileCachePolicyWriteThrough were set.
System Cache Details
By default, the CBFS class leverages Windows' built-in file management system cache, offloading the job of file data caching to the OS entirely. For CBFS-based virtual drives configured to use the system cache, Windows automatically caches file data in a dedicated area of the system memory region. This caching operates on a per-file basis, and the overall cache size is managed automatically by the system based on current memory pressure. The system automatically balances the rate at which cached data is flushed to storage for optimal system performance. Together, these attributes ensure access to frequently-read file data is as fast as possible. Please refer to Microsoft's File Caching article for more information about the system cache.
The system cache, by virtue of being a built-in Windows mechanism, is faster, more robust, and more flexible than the either of the CBFS-implemented file data caches. Therefore, unless there are specific reasons to do otherwise, applications should always prefer the system cache over either of the internal implementations.
Kernel Mode Cache Details
The internal kernel mode file data cache uses a nonpaged (i.e., non-swappable) memory region to cache file data. As with the system cache, this approach guarantees high-speed access to cached data since it is guaranteed to remain in-memory. However, there are a couple of caveats to be aware of regarding the memory region itself:
- The memory region is limited to a finite size that cannot be increased. On modern systems this is typically 300 MB, but the exact amount depends on how much physical memory the system has.
- Since the memory region is allocated by the CBFS system driver, it's shared between all CBFS-based virtual drives on the system configured to use kernel mode file data caching.
If the kernel mode cache's size limit is reached, pages are freed in LRU order. Pages are also freed if they haven't been used for 120 seconds.
User Mode Cache Details
The internal user mode file data cache uses pageable (i.e., swappable) memory regions, allocated per-process, to cache file data. Caching the file data in each process' memory space means the cache size can be as large as desired; but as with the internal kernel mode cache, there are some caveats to keep in mind:
- Since the memory regions are allocated per-process, all CBFS-based virtual drives within a given process (that are configured to use user mode file data caching) share that process' memory region.
- Since the memory is pageable, the OS can swap any page out to storage at any time, causing the next access of such pages' data to be slower.
- CBFS locks recently-used pages to prevent them from being swapped out, but the total size of all locked pages' data is limited to about 300 MB (and this limit is shared between all CBFS-based virtual drives on the system configured to use user mode file data caching).
The UserModeFileCacheSize configuration setting controls the size of the user mode file data cache. Since the memory is allocated per-process, this setting's value is synced between all CBFS class instances in a process, and can only be changed when the user mode cache is not in use by any virtual drive in the process (please refer to its documentation for details).
If the user mode cache's size limit is reached, pages are freed in LRU order.
File Metadata Caching
The CBFS class can employ a file metadata cache to help decrease the EnumerateDirectory and GetFileInfo events' rate of fire. The file metadata cache stores entries containing files' names, times, attributes, etc.; which the class uses to automatically respond to file information requests (rather than firing the aforementioned events).
The MetadataCacheEnabled property controls whether file metadata should be cached for a virtual drive; it is enabled by default. The MetadataCacheSize property specifies the maximum number of cache entries.
While a file or directory is open, its metadata is kept available in a special record called a File Control Block, regardless of whether the metadata cache is enabled.
Nonexistent File Information Caching
The CBFS class can also employ a "nonexistent files" cache to help further decrease the GetFileInfo event's rate of fire. The nonexistent files cache stores entries representing files that are known to be nonexistent (based on previous responses to the GetFileInfo event) so that the class can automatically respond to information requests for such files.
The NonExistentFilesCacheEnabled property controls whether nonexistent file information should be cached for a virtual drive; it is enabled by default. The NonExistentFilesCacheSize property specifies the maximum number of cache entries.