Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache


The functionwait_on_page_writebackis provided to wait until the bit disappears:

<pagemap.h>
static inline void wait_on_page_writeback(struct page *page)
{
if (PageWriteback(page))
wait_on_page_bit(page, PG_writeback);
}

wait_on_page_bitinstalls a wait queue on which the process can sleep until thePG_writebackbit is
removed from the page flags.

Likewise, the need to wait for a page to become unlocked can arise.wait_on_page_lockedis responsible
to handle this case.

16.4.4 Operations with Whole Pages


Modern block devices can — despite their name — transfer not just individual blocks but much larger
units of data in a single operation, thus boosting system performance. This is reflected by a strong ker-
nel focus on algorithms and structures that use pages as the elementary units of transfer between block
devices and memory. Buffer-by-buffer transfer acts as a substantial brake on performance when handling
complete pages. In the course of redesign of the block layer, BIOs were introduced during the develop-
ment of 2.5 as a replacement for buffers to handle transfers with block devices. Four new functions were
added to the kernel to support the reading and writing of one or more pages:

<mpage.h>
int mpage_readpages(struct address_space *mapping, struct list_head *pages,
unsigned nr_pages, get_block_t get_block);
int mpage_readpage(struct page *page, get_block_t get_block);
int mpage_writepages(struct address_space *mapping,
struct writeback_control *wbc, get_block_t get_block);
int mpage_writepage(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);

The meaning of the parameters is evident from the preceding sections, the only exception being
writeback_control. As discussed in Chapter 17, this is an option for fine control of the writeback
operation.

Since the implementations of the four functions share much in common (their goal is always to construct
a suitablebioinstance for transfer to the block layer), this discussion will be confined to examining just
the one specimen —mpage_readpages. The function expectsnr_pages pageinstances as parameters
passed in a linked list.mappingis the associated address space, andget_blockis, as usual, invoked to
find the matching block addresses.

The function iterates in a loop over allpageinstances:

fs/mpage.c
int
mpage_readpages(struct address_space *mapping, struct list_head *pages,
unsigned nr_pages, get_block_t get_block)
Free download pdf