普通文件的readpage方法(do_mpage_readpage)

当文件的块不在页高速缓存时,readpage方法用于将数据从磁盘读入内存并加入页缓存。在普通文件中,readpage通常调用mpage_readpage函数,该函数根据文件系统类型如ext2,通过get_block函数获取磁盘块信息。do_mpage_readpage负责创建bio请求并提交,处理磁盘读取操作,其策略根据数据块是否连续选择不同的读取方式。
摘要由CSDN通过智能技术生成

当所读文件所在的块并不在页高速缓存,我们需要使用readpage方法把页从磁盘读到内存中来,并加入到页缓存中去。
address_space对象的readpage方法存放的是函数地址,这种函数激活从磁盘到页高速缓存的io数据传送。对于普通文件,这个字段通常指向调用mpage_readpage( )函数的封装函数。如ext2文件系统的readpage方法:

static int ext2_readpage(struct file *file, struct page *page)
{
       return mpage_readpage(page, ext2_get_block);
}

该函数调用 mpage_readpage函数,传给他需要读入页高速缓存的页面的页描述符地址,以及ext2_get_block函数地址作为参数。
需要封装函数是因为mpage_readpage()函数接收的参数为待填充页的页描述符page及有助于mpage_readpage()找到正确块的函数的地址get_block。封装函数依赖文件系统并因此能提供适当的函数来得到块。这个函数把相对于文件开始位置的逻辑块号转换为相对于磁盘分区开始位置的逻辑块号。

后一个参数依赖于普通文件所在文件系统的类型。在我们的例子中,这个参数就是ext2_get_block()函数的地址。所传递的get_block函数总是用缓冲区首部buffer_head来存放有关重要信息,如块设备(b_dev字段)、设备上请求数据的位置(b_blocknr字段)和块状态(b_state字段)。

函数mpage_readpage()在从磁盘读入一页时可选择两种不同的策略。如果包含请求数据的块在磁盘上是连续的,那么函数就用单个bio描述符向通用块层发出读I/O操作;而如果不连续,函数就对页上的每一块用不同的bio描述符来读。所以,依赖于文件系统的get_block函数的一个重要作用就是:确定文件中的下一块在磁盘上是否也是下一块。

int mpage_readpage(struct page *page, get_block_t get_block)
{
    struct bio *bio = NULL;
    sector_t last_block_in_bio = 0;
    struct buffer_head map_bh;
    unsigned long first_logical_block = 0;

    map_bh.b_state = 0;
    map_bh.b_size = 0;
    bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio,
            &map_bh, &first_logical_block, get_block);
    if (bio)
        mpage_bio_submit(READ, bio);
    return 0;
}

首先将一个类型为buffer_head的变量map_bh的b_state和b_size字段清零;随后调用函数 do_mpage_readpage 函数创建了一个 bio 请求,该请求指明了要读取的数据块所在磁盘的位置、数据块的数量以及拷贝该数据的目标位置——缓存区中 page 的信息。然后调用 mpage_bio_submit 函数处理请求。
下面我们就研究一下do_mpage_readpage


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值