基于 commit

commit ffc253263a1375a65fa6c9f62a893e9767fbebfa (HEAD, tag: v6.6)
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sun Oct 29 16:31:08 2023 -1000

    Linux 6.6

分析带缓存的文件读

generic_file_read_iter 作为入口,首先判断是不是 direct io,如果不是,那么直接调用 filemap_read

ssize_t
generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
	size_t count = iov_iter_count(iter);
	ssize_t retval = 0;
 
	if (!count)
		return 0; /* skip atime */
 
	if (iocb->ki_flags & IOCB_DIRECT) {
		...
	}
 
	return filemap_read(iocb, iter, retval); // 非directio
}

filemap_read 该函数主要准备一些数据结构和状态,比如初始化 fbatch,调用 filemap_get_pages 获取数据,最后将 fbatch 中的数据拷贝到 iov_iter

error = filemap_get_pages(iocb, iter->count, &fbatch, false);
 
 
for (i = 0; i < folio_batch_count(&fbatch); i++) {
	struct folio *folio = fbatch.folios[i];
	copied = copy_folio_to_iter(folio, offset, bytes, iter);
}