这篇文章接着讲解nfs_readpages()的流程。上篇文章中,我们讲到了read_cache_pages()将缓存页添加到文件缓存的radix树中,为每个缓存页创建了一个nfs_page结构,然后将这些缓存页链接到nfs_pageio_descriptor结构中。nfs_pageio_descriptor中包含了多个缓存页以及向服务器请求数据的函数集合。接下来就是调用nfs_pageio_descriptor中的函数向服务器请求数据了,这是通过函数nfs_pageio_complete()实现的,这个函数最终调用的是nfs_pageio_descriptor结构中pg_ops字段中的函数pg_doio(),读操作中,这个函数是nfs_generic_pg_readpages()。
static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
{
struct nfs_read_header *rhdr;
struct nfs_pgio_header *hdr;
int ret;
// 步骤1 创建一个nfs_read_header结构
rhdr = nfs_readhdr_alloc();
if (!rhdr) { // 创建rhdr失败了,不能处理desc中的缓存页了,需要释放这些缓存页
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
return -ENOMEM;
}
// 步骤2 初始化hdr
hdr = &rhdr->header; // 找到nfs_pgio_header结构
// 根据desc结构中的信息初始化hdr,向hdr中添加了nfs_page结构,
// 设置了hdr->completion_ops、inode、io_start、good_bytes
// nfs_readhdr_free用来释放nfs_read_header结构占用的内存
nfs_pgheader_init(desc, hdr, nfs_readhdr_free);
atom