【cubefs】预读解析-②
预读
预读结构体:
/*
* Track a single file's readahead state
*/
/*
|<----- async_size ---------|
|------------------- size -------------------->|
|==================#===========================|
^start ^page marked with PG_readahead
*/
struct file_ra_state {
/* 从start开始进行预读 */
pgoff_t start; /* where readahead started */
/* 预读page的个数,预读操作是有预读窗口大小的,如果内存充足则读取size个page 放入到预读窗口当中 */
unsigned int size; /* # of readahead pages */
/* 预读窗口中还剩async_size个page时启动异步预读, PageReadahead此时就会发挥作用 */
unsigned int async_size; /* do asynchronous readahead when
there are only # of pages ahead */
/* 预读最大窗口,也就是说此时一次性只能预读ra_pages个文件页
* 默认等于struct backing_dev_info->ra_pages, 可通过fadvise64_64调整。
* 如果read需要读的page数量小于ra_pages,最多读取ra_pages个页面。
* 如果read需要读的page数量大于ra_pages,最多读取min { read的page数量,存储器件单次io最大page数量 }个页面。*/
unsigned int ra_pages; /* Maximum readahead window */
unsigned int mmap_miss; /* Cache miss stat for mmap accesses */
/* 最后一次的预读位置,为后续偏移保存数据 */
loff_t prev_pos; /* Cache last read() position */
}
struct readahead_control {
struct file *file;
struct address_space *mapping;
/* private: use the readahead_* accessors instead */
pgoff_t _index;
unsigned int _nr_pages;
unsigned int _batch_count;
};
字段分析:
struct file *file;
表示当前正在进行预读的文件对象。
2. pgoff_t index;
表示预读 本次预读从哪个 page index 开始,page index = 文件偏移 / PAGE_SIZE,例如:
- 读取 offset = 128KB
- PAGE_SIZE = 4KB
- index = 32
总页数:
unsigned int _nr_pages;
表示:本次 readahead 计划读取多少页
例如:
- window = 128KB
- PAGE_SIZE = 4KB
- 那就是 32 pages
这表示“逻辑上”的预读数量。
当前批次数量:
unsigned int _batch_count;
这个字段是 内部控制用,表示:当前一批要提交给文件系统的页数量,为什么需要 batch?因为:
- 内核会批量分配 page
- 然后分批交给文件系统
- 文件系统可能一次处理一部分页
例如:总预读 32 页,但一次只给 filesystem 8 页,那 _batch_count = 8
参考资料
3. Linux read的核心函数generic_file_buffered_read
4. page cache之文件预读readahead内核源码详解

浙公网安备 33010602011771号