The getblk Function

The getblk( ) function is the main service routine for the buffer cache. When the kernel needs to read or write the contents of a block of a physical device, it must check whether the buffer head for the required buffer is already included in the buffer cache. If the buffer is not there, the kernel must create a new entry in the cache. To do this, the kernel invokes getblk( ), specifying as parameters the device identifier, the block number, and the block size. This function returns the address of the buffer head associated with the buffer.

Remember that having a buffer head in the cache does not imply that the data in the buffer is valid. (For instance, the buffer has yet to be read from disk.) Any function that reads blocks must check whether the buffer obtained from getblk( ) is up to date; if not, it must read the block first from disk before using the buffer.

The getblk( ) function looks deceptively simple:

struct buffer_head * getblk(kdev_t dev, int block, int size) {

struct buffer_head * bh; bh = get_hash_table(dev, block, size); if (bh)

return bh; if (!grow_buffers(dev, block, size))

free_more_memory( );

The function first invokes get_hash_table( ) (see the earlier section Section 14.2.1.3) to check whether the required buffer head is already in the cache. If so, getblk( ) returns the buffer head address.

Otherwise, if the required buffer head is not in the cache, getblk( ) invokes grow_buffers( ) to allocate a new buffer page that contains the buffer for the requested block. If grow_buffers( ) fails in allocating such a page, getblk( ) tries to reclaim some memory (see Chapter 16). These actions are repeated until get_hash_table( ) succeeds in finding the requested buffer in the buffer cache.

Was this article helpful?

0 0

Post a comment