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 */
如您所见,它“将缓冲区链接到其页面”