Block Device Operations
Block devices account for the second large group of peripherals supported via the VFS interface of the kernel. Unfortunately, the situation faced by block device drivers is more complicated than that for character devices. This is caused by a range of circumstances, above all by the need for continuous speed adjustment occasioned by the design of the block device layer, by the way in which block devices work, and by the historical development of the block device layer.
Block devices differ fundamentally from character devices in three principle areas.
□ Access can be performed at any point within the data. This can but need not be the case with character devices.
□ Data are always transferred in fixed-size blocks. Even if a single byte is requested, the device driver must always fetch a complete block from the device. In contrast, character devices are able to return individual bytes.
□ Accesses to block devices are massively cached; that is, read data are kept in memory and are accessed from there if they are needed again. Write operations are also delayed by using caches.
This makes no sense on character devices (such as keyboards); each read request must be satisfied by genuine interaction with the device.
We use two terms repeatedly below — block and sector. A block is a byte sequence of a specific size used to hold data transferred between the kernel and a device; the size of the block can be modified by software means. A sector is a fixed hardware unit and specifies the smallest amount of data that can be transferred by a device. A block is nothing more than a sequence of successive sectors; consequently, the block size must always be an integer multiple of the sector size. As a sector is a hardware-specific constant, it is also used to specify the position of a data block on a device. The kernel regards each block device as a linear list of integer-numbered sectors or blocks.
Today, almost all common block devices have a sector size of 512 bytes, which equates to a block size of 512, 1,024, 2,048 or 4,096. It should, however, be noted that the maximum block size is limited by the memory page size of the particular architecture. IA-32 systems support a maximum block size of 4,096 bytes because the memory page size is 4,096 bytes. On the other hand, IA-64 and Alpha systems are able to handle blocks with 8,192 bytes.
The relative freedom of choice with regard to block size has advantages for many block device applications as you will see when examining, for example, how filesystems are implemented. Filesystems may divide the hard disk into blocks of different sizes in order to optimize performance when many small files or few large files are involved. Implementation is made much easier because the filesystem is able to match the transfer block size to its own block size.
The block device layer is not only responsible for addressing the block devices but also for carrying out other tasks to enhance the performance of all block devices in the system. Such tasks include the implementation of readahead algorithms that read data from a block device speculatively in advance when the kernel assumes that the data will be required shortly by an application program.
The block device layer must provide buffers and caches to hold the readahead data if they are not required immediately. Such buffers and caches are not reserved solely for readahead data but are also used to temporarily store frequently needed block device data.
The list of tricks and optimizations performed by the kernel when addressing block devices is long and beyond the scope of this chapter. What is more important is to sketch the various components of the block device layer and demonstrate how they interact.
Continue reading here: Representation of Block Devices
Was this article helpful?