接着前面的内容讲,这篇文章主要介绍了nfs_readpages()函数中的步骤4,步骤4中包含下面一条语句
ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
read_cache_pages()是一个通用函数(不是NFS中的函数),这个函数定义在mm/readahead.c,这个函数的完整定义如下:
参数mapping: 这是文件缓存的数据结构
参数pages: 这是一个链表,链表中保存的是缓存页,缓存页中的index字段必须已经设置好了
参数filler: 这是一个函数指针,对链表中每一个缓存页执行函数filler
参数data: 这是供filler使用的参数
int read_cache_pages(struct address_space *mapping, struct list_head *pages,
int (*filler)(void *, struct page *), void *data)
{
struct page *page;
int ret = 0;
while (!list_empty(pages)) { // 处理链表中每一个缓存页
page = list_to_page(pages); // 从链表中取出一个缓存页
list_del(&page->lru);
// 将缓存页添加到radix树中,然后添加到lru链表中.
// page->index是缓存页在文件中的索引值
// 这个函数会增加缓存页的引用计数
if (add_to_page_cache_lru(page, mapping,
page->index, GFP_KERNEL)) {
// 添加缓存页失败了,需要释放这个缓存页.
read_cache_pages_invalidate_page(mapping, page);
continue;
}
// 由于add_to_page_cache_lru()增加了缓存页的引用计数,
// 这里需要减少引用计数.
page_cache_release(page);