Section 1.6. Drivers and IO Buffers

   

1.6 Drivers and I/O Buffers

This section elaborates on I/O buffers, introduced earlier in this chapter. Drivers have to deal with buffers for their I/O and I/O control (IOCTL) operations. For this purpose, drivers specify a method of I/O that they prefer via their driver object. There are three types of I/O that a Windows NT driver may support: Buffered I/O, Direct I/O, and Neither I/O. These are described in Sections 1.6.1 through 1.6.3.

1.6.1 Buffered I/O

Buffered I/O is typically used for smaller data transfers because it involves some data copy operations. When an application makes an I/O request, the I/O Manager validates the request to ensure that the application has appropriate access to the buffer it passed in with the I/O operation (in this case appropriate access means that the application has the necessary read or write privilege and access to the required size of the buffer as specified in the I/O operation). The I/O Manager allocates a buffer from a nonpageable pool of memory, and for a write request it copies the data from the application buffer to this newly allocated buffer. This buffer is passed to the driver.

The driver does not need to worry about thread context because this buffer in the nonpageable pool is valid under any thread or process context. The driver performs the desired I/O. For a read operation, the driver copies the data into the buffer it received. The driver can assume that this buffer is contiguous in terms of virtual address, but like any other buffer in Windows NT, a virtually contiguous buffer does not necessarily dictate a physically contiguous buffer.

The driver would complete the IRP at this point, and it is the responsibility of the I/O Manager to copy the data from the nonpaged pool buffer back into the application's buffer. This copy operation needs to be done in the context of the original process that made the I/O request. It is also the duty of the I/O Manager to free the nonpaged pool buffer used.

1.6.2 Direct I/O

Direct I/O is a little more involved than Buffered I/O, but more efficient for I/O operations involving larger amounts of data. The I/O Manager performs some basic checks, such as verifying that the application has appropriate access to the buffer over the entire desired amount of I/O. The memory buffer is described to the driver by means of a data structure called a memory descriptor list , or MDL . An MDL is a data structure that describes a buffer in a process-independent manner. The buffer address is specified as a systemwide virtual memory address.

Windows NT provides routines for drivers to access various fields on the memory descriptor list, and driver writers are encouraged to treat the MDL as an opaque entity and are referred to the Windows NT DDK to get details of the MDL- related routines provided by the DDK. The routines, which are described in the DDK, include functionality to

  • Lock and unlock the application memory buffer

  • Map the locked buffer into a virtual address that is accessible from any arbitrary thread context

  • Collect required information to perform a direct memory access (DMA) I/O to or from the buffer that is really a series of potentially physically separate pages

Direct I/O is the type of I/O most often used by storage drivers. For example, the disk and tape class drivers perform Direct I/O.

1.6.3 Neither I/O

Neither I/O eliminates the overhead associated with Buffered I/O (data copy operation and buffer allocation/deallocation) and with Direct I/O (setting up and tearing down of the memory descriptor list), but at the cost of limiting the situations in which this type of I/O can be used. With Neither I/O, the driver is directly passed the virtual address of the requesting application's data buffer. Astute readers will quickly deduce that since a virtual address makes sense only in the context of a particular process or thread, the driver must be called in the context of the requesting application. Further, the driver must perform the operation in the same context (that is, the driver cannot queue a request that could execute in an arbitrary context).

This constraint limits the situations in which this I/O method is used, and most storage drivers do not use this I/O method. File system drivers typically use Neither I/O. File system drivers are always called in the context of the process that initiates the I/O. In addition, Neither I/O facilitates the copy between the cache and data buffers because no buffer management (e.g., address mapping) is required.

The impression that a driver must choose only one of these methods is incorrect. A driver that performs an I/O control (IOCTL) operation can use one I/O method for regular IRPs, but a different I/O method for the IOCTL operations that are privately defined between it and the communicating application. Of course, even a driver that is down the stack chain and unsure of the context in which it is being called may not necessarily use Neither I/O in its privately defined IOCTL.

While we're on the topic of private IOCTLs, it is worthwhile noting that Microsoft actively discourages their use, especially when better alternatives exist. The big problem with private IOCTLs is that one cannot easily test the robustness of the driver code by deliberately passing bad buffers to the IOCTL operation to verify that the driver correctly handles the case. To pass bad buffers, one needs to have an idea of the valid buffer size, alignment, and boundary conditions expected by the IOCTL code, and these parameters are different for each private IOCTL operation.


   
Top


Inside Windows Storage
Inside Windows Storage: Server Storage Technologies for Windows 2000, Windows Server 2003 and Beyond
ISBN: 032112698X
EAN: 2147483647
Year: 2003
Pages: 111
Authors: Dilip C. Naik

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net