Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache


fs/buffer.c
lru = &__get_cpu_var(bh_lrus);

Caution: Iflookup_bh_lrufails, the desired buffer is not automatically read from the block device. This
is done by the following interface functions.

Interface Functions


Normal kernel code does not generally come into contact with eitherbh_lookup_lruorbh_lru_install
because these functions are encapsulated. The kernel provides generic routines for accessing individual
blocks, and these automatically cover the buffer cache, thus rendering explicit interaction with the cache
unnecessary. These routines include__getblkand__bread, which are implemented infs/buffer.c.

Before discussing their implementation, it is best to describe not only what the two functions have in
common, but also how they differ. First, they both require the same parameters:

fs/buffer.c
struct buffer_head *
__getblk(struct block_device *bdev, sector_t block, int size)
{
...
}

struct buffer_head *
__bread(struct block_device *bdev, sector_t block, int size)
{
...
}

A data block is uniquely identified by theblock_deviceinstance of the desired block device, the sector
number (of typesector_t), and the block size.

The differences relate to the goals of the two functions.__breadguaranteesthat an up-to-date buffer is
returned; this entails, if necessary, read access to the underlying block device.

Invocations of__getblkalways return a non-NULL pointer (i.e., a buffer head).^15 If the data of the
desired buffer already reside in memory, the data are returned, but there is no guarantee as to what their
state will be — in contrast to__bread, it need not be up-to-date. In the second possible scenario, the
buffer does not yet exist in memory. In this case,__getblkensures that the memory space required for
the data are reserved and that the buffer head is inserted in the LRU cache.

__getblkalwaysreturns a buffer head with the result that even senseless
requests — for non-existent sector addresses — are processed.

(^15) There is one exception. The function returns a NULL pointer if the desired block size is less than 512 bytes, larger than a page, or
not a multiple of the hardware sector size of the underlying block device. However, a stack dump is also output at the same time
because an invalid block size is interpreted as a kernel bug.

Free download pdf