NFS系统read调用过程(三)

来源:互联网 发布:网络电视看cctv5的apk 编辑:程序博客网 时间:2024/05/22 05:10

        上一篇文章讲解了函数nfs_readpages()的整体流程,这个函数的作用是向服务器发起READ请求,用请求到的数据更新缓存页中的内容。这个函数分为六个步骤:

步骤1:获取用户信息。

步骤2:检查FS-Cache缓存是否有效。

步骤3:初始化一个nfs_pageio_descriptor结构。

步骤4:将链表pages中的缓存页添加到文件缓存的radix树中,然后为每个缓存页创建一个nfs_page结构。

步骤5:向服务器发起READ请求。

步骤6:更新统计信息。

这篇文章详细讲解步骤3,步骤3中只有一条语句

NFS_PROTO(inode)->read_pageio_init(&pgio, inode, &nfs_async_read_completion_ops);

NFSv2、NFSv3以及NFSv4(没有使用pNFS)中,read_pageio_init对应的函数是nfs_pageio_init(),这个函数的定义如下:

void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,                              struct inode *inode,                              const struct nfs_pgio_completion_ops *compl_ops){        nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, compl_ops,                        NFS_SERVER(inode)->rsize, 0);}

这只是nfs_pageio_init()的封装函数

void nfs_pageio_init(struct nfs_pageio_descriptor *desc,                     struct inode *inode,                     const struct nfs_pageio_ops *pg_ops,                     const struct nfs_pgio_completion_ops *compl_ops,                     size_t bsize,                     int io_flags){        INIT_LIST_HEAD(&desc->pg_list); // 这是一个链表,链表中存放了多个nfs_page结构,现在初始化链表为空.        desc->pg_bytes_written = 0;     // 已经传输的数据量        desc->pg_count = 0;             // 需要处理的数据量,因为现在还没有nfs_page结构,所以这个值为0        desc->pg_bsize = bsize;         // 每次RPC请求中最多可以传输的数据量        // pg_list可能包含多个缓存页,这些缓存页是连续的,pg_base是第一个缓存页中数据在缓存页中的偏移值.        // 不是在文件中的偏移值        desc->pg_base = 0;        desc->pg_moreio = 0;            // 这是WRITE操作中使用的一个字段,READ操作没有使用.        desc->pg_recoalesce = 0;        // 当新的nfs_page结构不能添加到nfs_pageio_descriptor中时使用这个字段.        desc->pg_inode = inode;         // 文件节点        desc->pg_ops = pg_ops;          // 两个操作函数集合        desc->pg_completion_ops = compl_ops;        desc->pg_ioflags = io_flags;    // 标志位信息        desc->pg_error = 0;             // 错误码        desc->pg_lseg = NULL;           // pNFS使用的字段,暂时不管了        desc->pg_dreq = NULL;           // 直接IO使用的字段,暂时不管了}

这个函数就是在初始化一个nfs_pageio_descriptor结构,其中涉及到了两个操作函数集合struct nfs_pageio_ops和struct nfs_pgio_completion_ops,对于读操作来说,这两个操作函数集合定义如下:

static const struct nfs_pageio_ops nfs_pageio_read_ops = {        .pg_test = nfs_generic_pg_test,        .pg_doio = nfs_generic_pg_readpages,};

static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = {        .error_cleanup = nfs_async_read_error,        .completion = nfs_read_completion,};


但是现在还不能讲这两个函数集合,步骤4和步骤5中调用了这两个函数集合,我们马上就讲。

原创粉丝点击