Portable Systems Group

Caching Design Note

Author: Tom Miller

Revision 1.3, October 31, 1991

Copyright (c) Microsoft Corporation - Use subject to the Windows Research Kernel License

Caching Design Note i

.Begin Table C.

1. Overview 1

1.1 File Streams and Cache Maps 1

1.2 Target Clients of the Cache Manager 2

1.3 Cache Manager Interfaces 3

2. WalkThrough of Cache Manager Interaction 5

2.1 Setting up the File Object on Create 5

2.1.1 FsContext 5

2.1.2 SectionObjectPointer 7

2.1.3 PrivateCacheMap field 7

2.2 Initializing Cache Maps for a File Stream 7

2.3 Accessing Data in the Cache 8

2.3.1 Copying Data To and From the Cache 8

2.3.2 DMA Transfer of Data To and From the Cache 9

2.3.3 Accessing Data Directly in the Cache 9

2.4 Uninitializing Cache Maps for a File Stream 10

2.5 Fast I/O Optimization 10

2.6 Use of the Wait Input Parameter 11

2.7 Use of Stream Files 11

2.8 File System Cleanup and Close Routines 12

2.9 Using Write Through and Cache Flushing 13

2.10 Valid Data Length and File Size Considerations 14

2.11 Resource Locking Rules 15

2.12 Network File Server Interfaces 17

3. File System Maintenance Functions (FSSUP) 19

3.1 CcInitializeCacheMap 19

3.1.1 Cache Manager Callbacks 20

3.2 CcUninitializeCacheMap 21

3.3 CcExtendCachedFileSize 23

3.4 CcExtendCacheSection 23

3.5 CcFlushCache 24

3.6 CcPurgeFromWorkingSet 24

3.7 CcPurgeCacheSection 25

3.8 CcTruncateCachedFileSize 25

3.9 CcZeroData 26

3.10 CcRepinBcb 27

3.11 CcUnpinRepinnedBcb 27

3.12 CcIsFileCached 27

3.13 CcReadAhead 28

3.14 CcSetAdditionalCacheAttributes 29

4. Copy Interface (COPYSUP) 30

4.1 CcCopyRead 30

4.2 CcCopyWrite 30

5. Mdl Interface (MDLSUP) 32

5.1 CcMdlRead 32

5.2 CcMdlReadComplete 33

5.3 CcPrepareMdlWrite 34

5.4 CcMdlWriteComplete 35

6. Pin Interface (PINSUP) 36

6.1 CcPinRead 36

6.2 CcMapData 37

6.3 CcPinMappedData 38

6.4 CcPreparePinWrite 40

6.5 CcSetDirtyPinnedData 41

6.6 CcUnpinData 41

7. Revision History 42

.End Table C.

Copyright (c) Microsoft Corporation - Use subject to the Windows Research Kernel License

Caching Design Note 45

1. Overview

This design note describes the Cache Manager for Windows NT. The Cache Manager uses a file mapping model, which is closely integrated with memory management.

The file mapping model or virtual block cache, has been chosen over a logical block cache for the following reasons:

o Virtual block caching is more compatible with the ability of user programs to map files. It is possible for some programs to do NtReadFile and NtWriteFile at the same time that other programs have the file mapped with read-only or read/write access. With proper synchronization, both types of programs are able to see the most current data.

o By using a file mapping model, all of physical memory becomes available for data caching, with the allocation of pages reacting dynamically to the changing needs for image file pages versus data file pages.

o Cache hits are processed more efficiently by handling virtual block hits directly in a mapped file. In most cases an I/O request is able to access the data directly in the cache, without calling the file system at all (see Section ). The I/O system makes a subroutine call to access the cache, and the Cache Manager resolves the access via a single hardware virtual address lookup.

o For the a recoverable file system such as NTFS, it is necessary to have caching closely synchronized with logging. This requires that all cache entries be directly identifiable by the recoverable file to which they belong.

The Cache Manager also provides a simple mechanism for dealing with unaligned buffers. If a file has been opened with caching disabled (FILE_NO_INTERMEDIATE_BUFFERING specified in the Create/Open options), then an NtReadFile or NtWriteFile will fail if the alignment and size of the specified transfer is less than that required by the target disk. The assumption is, that if a program specified a request with caching disabled, then it really does not want to pay the cost of having the transfer go to an intermediate buffer and be copied.

1.1 File Streams and Cache Maps

The Cache Manager is a central system component which may be thought of as being layered closely on top of the Memory Management support. Key to understanding the Cache Manager is the concept of File Streams.

A File Stream is a linear stream of bytes associated with a File Object. Each File System creates, deletes and manipulates File Streams both for external use via NT File System APIs, as well as for internal use by the File System itself. Examples of File Streams maintained by File Systems are the data of a given file, the EAs of a file, the Acl of a file, a directory, or any other file system metadata. How virtual byte offsets within the File Stream are mapped to physical locations in nonvolatile store is strictly an opaque operation determined by the File System, and may vary for different types of file streams.

Once a file system has identified which streams it wishes to support, it needs to decide which of these streams it wishes to cache. For all streams which are to be cached, the file system must actually support both cached and noncached access. Noncached access is always issued via a read or write I/O Request Packet (IRP), in which the IRP_NOCACHE flag is set in the Irp flags. (See the NT I/O System Specification.) For streams which may be accessed by normal user programs, such as the data of a file, the file system will also receive cached I/O requests via read or write IRPs with the IRP_NOCACHE flag not set. Also for internal use a file system may perform cached access to any of the streams it defines via direct calls to the Cache Manager.

As mentioned earlier, the Cache Manager uses mapping to implement the caching of streams, and to integrate caching with Memory Management's policy with other uses of pageable memory. Thus when a file system calls the Cache Manager to intitiate caching of a stream, the Cache Manager immediately maps all or a portion of the stream via a call to memory management. For larger streams, the Cache Manager may subsequently find it necessary to map additional portions of the stream on an as-needed basis. To keep track of which portions of a file stream the Cache Manager currently has mapped, it uses private data structures which it refers to as Cache Maps. For each stream being cached, the Cache Manager maintains a single Shared Cache Map. For each File Object through which the cached stream is being accessed, the Cache Manager also maintains a Private Cache Map. The Shared Cache Map describes an initial portion of the file stream which is mapped for common access via all File Objects for this stream. Each Private Cache Map optionally describes an additional nonoverlapping portion of the stream mapped on an as-needed basis to access bytes in the stream which were not mapped by the Shared Cache Map.

Again, the Cache Maps are private structures maintained by the Cache Manager, and a further understanding of these structures is not required by a person writing a file system. However, a file system writer does have to be aware of the respective relationships between a file system, the Cache Manager, and Memory Management. For example, when an attempted cache access results in a "miss", this miss results in a page fault which is serviced by Memory Management who subsequently makes a (recursive) call back to the file system with a noncached I/O request.

1.2 Target Clients of the Cache Manager

The Cache Manager interfaces have been primarily designed to support the following clients:

o Normal file systems such as FAT, HPFS and CDFS. File systems may create and cache File Streams for normal data files, the EAs associated with a file, the volume structure of a volume, etc. Note that the Cache Manager knows nothing about different types of streams; it only knows about File Objects and different modes of access.

For example, HPFS creates File Streams to cache normal file data, the first time the data is actually accessed. It also creates a File Stream for a "Volume File", which is a compressed mapping of the volume structure on a HPFS volume. If the EAs or ACL for a given file fit in the Fnode, then they are simply cached with the Fnode in the Volume File. The other case HPFS has is that the EA or ACL is too large to fit in the Fnode, and is described by one or more runs of contiguous sectors external to the Fnode. In this case, a separate stream is created to cache the EA or ACL the first time they are accessed.

Interfaces are provided for File Systems to access data by copying, or accessing it directly in the cache.

o Network File System clients, such as the Lan Manager Redirector. For starters, a Network File System looks like any other File System, with normal data streams, and potentially other types of streams associated with files. However, a Network File System client would normally not be maintaining any "volume" structure of its own.

o Network File Servers, such as the Lan Manager Server. A file server is not expected to look like a file system at all. However, it also may be considered a "client" of the Cache Manager via the host file system(s) which it calls. Indeed, some of the file system calls which are ultimately supported by the Cache Manager (such as the Mdl interfaces defined later), were designed with Network File Servers in mind.

1.3 Cache Manager Interfaces

The Cache Manager has four sets of interfaces. One is for basic File Stream maintenance, and the other three implement different access methods for the cache. The three access methods share common support routines, but acknowledge the different ways in which the cache will be used.

Following is a brief description of the four sets of interfaces supported by the cache manager, which are described in detail in the following sections:

o File Stream maintenance functions.

The File Stream maintenance functions are implemented in the Cache Manager module fssup.c. These routines are for initializing and uninitializing cached operation for a stream, extending and truncating cached streams and file sizes, flushing pages to disk, purging pages from the cache without flushing, zeroing file data, and so on.

o Copy Interface.

The Copy Interface is implemented by the Cache Manager module copysup.c. The copy interface is the simplest form of cached access. It supports copying a range of bytes from a specified offset in a cached file stream to a buffer in memory, or from a buffer in memory to a specifiedd offset in a cached file stream. The copy interface also has a related call to initiate read ahead.

o Mdl Interface.

The Mdl Interface is implemented by the Cache Manager module mdlsup.c. The Mdl interface supports direct access to the cache via DMA. For example, a network file server can efficiently support large client reads via DMA of the desired bytes directly out of the cache to a network device. Similarly a network file server is able to support large client writes by DMA directly into the cache. The Mdl interface shares the same Read Ahead call as the copy interface.

o A Pinning Interface.

The Pinning Interface is implemented by the Cache Manager module pinsup.c. The pin interface may be used to lock (pin) data in the cache and access it directly via a pointer, and then unpin the data when the pointer is no longer required. Pinning is a database concept, and it is the optimal way for a File System to deal with the caching of file system metadata:

The following table summarizes which of the Cache Manager's clients are intended to use which of the four interface classes. Note that Network File Servers never call the Cache Manager directly, but rather benefit from the specified interfaces via associated calls to local file systems.

Local File Network FS Network File
Systems Clients Servers

FS Maint. x x

Copy Int. x x x

Mdl Int. x x

Pin Int. x

The next section walks through what a file system has to do to set up for and use the Cache Manager. Then, subsequent sections will document the individual routines belonging to the four classes of interfaces presented above.

2. WalkThrough of Cache Manager Interaction

This section attempts to present all of the background information which is important to understand when about to write a File System (including a Network File System client) or File Server which intends to use the Cache Manager. All of the following subsections but the last one relate only to file systems, but may provide some insight to someone writing a file server.

The final subsection describes how a file server accesses cached file streams. The final section should also be understood by anyone writing a local file system.

The following include files, present in \nt\private\inc, define the data structures and procedure calls described in this section and the rest of this document:

cache.h Cache Manager structures and routines

fsrtl.h File System Rtl structures and routines

io.h I/O system structures and routines

ex.h Executive structures and routines

2.1 Setting up the File Object on Create

When a file system is called at its Create Fsd entry point, one of the important fields in the Irp is a pointer to a File Object (see io.h) for the file being opened. There are three pointers in the File Object which must be initialized in a particular way for a file system which wishes to use the Cache Manager. These fields are FsContext, SectionObjectPointer, and PrivateCacheMap. (A fourth pointer, FsContext2, has no significance to the Cache Manager, and is usually used to point to a per file object context called the Channel Control Block or CCB.) The following subsections describe how these fields are to be initialized.