如果在 inode 的缓存中找不到页面,do_generic_file_read() 函数会在哪里休眠?

Where does the do_generic_file_read() function sleep in case page is not found in inode's cache?

在读取 io 操作的情况下,为 ext3 文件系统调用 do_generic_file_read 函数。如果 inode 的页面缓存不包含需要从中读取数据的页面,则会调用文件系统特定的读取页面地址 space 函数指针。在 ext3 文件系统的情况下,调用 ext3_readpage() 函数,该函数又调用通用的 do_mpage_readpage() 函数。 do_mpage_readpage() 函数创建一个 bio,该 bio 被调度以通过 submit_bio() 函数从设备获取数据,而控件依次 returns 到 do_generic_file_read()功能。但是在 do_generic_file_read() 中,执行的下一条指令是检查提交简历的页面是否是最新的。在这个流程中,内核在哪里等待bio操作完成并更新页面?

do_mpage_readpage函数创建bio结构从磁盘块中获取数据并提交给io。

do_mpage_readpage
..
mpage_bio_submit(READ, bio)
..

提交生物时,控制 returns 到 do_generic_file_read() 函数,然后调用 lock_page_killable() 函数,它等待生物的更新位页。

do_generic_file_read()
...
        if (!PageUptodate(page)) {
            error = lock_page_killable(page); <<<<<<<< it sleeps here
...

一旦从设备完成 io,mpage_end_io() 将作为 return 处理程序调用。(因为我们已经填充了 bio->bi_end_io = mpage_end_io 同时提交 IO)。在阅读的情况下,这会将生物发送的页面标记为更新并调用 unlock_page() 函数。此函数唤醒正在等待页面更新的控件。

mpage_end_io
...
            unlock_page(page); <<< this wakes up the waiting do_generic_file_read
...