Memory management 对于页面缓存中给定的缓冲区头,set_bh_page到底做了什么?

Memory management 对于页面缓存中给定的缓冲区头,set_bh_page到底做了什么?,memory-management,linux-kernel,operating-system,paging,block-device,Memory Management,Linux Kernel,Operating System,Paging,Block Device,我正在深入研究内核源代码,我注意到这个函数set\u bh\u page()。然而,我无法清楚地理解它的作用 我只能在fs/buffer.c文件中找到此注释: /*将缓冲区链接到其页面*/ 设置页面(页面,页面,偏移) 但我仍然不清楚它的作用 因此,为了清楚起见,我想了解这个函数调用与缓冲区和物理页面之间的关系,以及它是否与页面缓存本身有关 更新1: 函数alloc\u page\u buffers()调用此函数set\u bh\u page(),对此有一些注释,如下所示: struct buf

我正在深入研究内核源代码,我注意到这个函数
set\u bh\u page()
。然而,我无法清楚地理解它的作用

我只能在
fs/buffer.c
文件中找到此注释:

/*将缓冲区链接到其页面*/

设置页面(页面,页面,偏移)

但我仍然不清楚它的作用

因此,为了清楚起见,我想了解这个函数调用与缓冲区和物理页面之间的关系,以及它是否与页面缓存本身有关

更新1:

函数
alloc\u page\u buffers()
调用此函数
set\u bh\u page()
,对此有一些注释,如下所示:

struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size, bool retry);
当给定的数据区域和每个缓冲区的大小为页面时,创建适当的缓冲区。。使用bh->b_此页面链接列表跟踪创建的缓冲区。如果无法创建更多缓冲区,则返回NULL

我检查了谁调用了
alloc\u page\u buffers()
,其中哪一个是
read\u page()
,具有以下描述:

从文件中读取页面

我们都读取页面,并将缓冲区附加到页面以记录每个块的地址(使用bmap)。这些地址将用于稍后写入块,完全绕过文件系统。这种用法类似于交换文件的处理方式,允许我们写入文件而不必担心内存分配失败

因此,通过查看
read_page()
的源代码,我的理解是分配的
buffer_head
必须与其物理页面地址相关联,就像直接映射一样


正确吗?

当内核需要从块设备访问一个块,并且发现页面缓存中没有包含该块的页面时,它会分配一个页面,称为块设备缓冲页面或简单的缓冲页面,然后将请求的块写入该页面。该过程从调用的函数开始,该函数声明如下:

struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size, bool retry);
page
指向将保存块的缓冲区页面的描述符<代码>大小表示块的大小(以字节为单位),其中缓冲页的所有块大小相同。注意,块是块设备的存储区域,而缓冲器是主存储器的存储区域。缓冲区保存单个块的数据,且大小相同。因此,缓冲区页面如下所示:

       .
       .
       .
|-------------|
|    buffer   |
|-------------|
|    buffer   |
|-------------|
|    buffer   |
|-------------|
       .
       .
       .
每个缓冲区中包含的块由缓冲头标识。您可以找到buffer_head的结构声明。
b_bdev
b_blocknr
字段一起标识块设备上的块。请注意,每个缓冲头都有一个指向同一缓冲页内下一个缓冲头的指针。
alloc\u page\u buffers
函数分配并初始化指定缓冲页的所有缓冲区的缓冲头
alloc_page_buffers
调用
set_bh_page
函数初始化缓冲头的两个特定字段,
b_page
b_data
,这两个字段由代码中的注释描述:

struct page *b_page;    /* the page this bh is mapped to */
char        *b_data;    /* pointer to data within the page */
如您所见,它“将缓冲区链接到其页面”