3

我正在研究内核源代码,我注意到了这个功能set_bh_page()。但是,我无法清楚地理解它的作用。

我只能在fs/buffer.c文件中找到这条评论:

/* 将缓冲区链接到它的页面 */

set_bh_page(bh,页面,偏移量);

但我仍然不清楚它的作用。

所以,为了说清楚,我想了解这个函数调用与缓冲区和物理页面的关系是什么,以及它是否与页面缓存本身有任何关系。

更新 1:

该函数alloc_page_buffers()调用 this set_bh_page(),对此有一些注释,如下所示:

当给定数据区域的页面和每个缓冲区的大小时,创建适当的缓冲区。使用 bh->b_this_page 链表跟踪创建的缓冲区。如果无法创建更多缓冲区,则返回 NULL。

我检查了谁调用了alloc_page_buffers(),其中一个是read_page(),具有以下描述:

从文件中读取一页。

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

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

那是对的吗?

4

1 回答 1

1

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

struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size, bool retry);

page指向要保存块的缓冲区页的描述符。size表示一个块的大小(以字节为单位),其中缓冲页的所有块都具有相同的大小。请注意,块是块设备的内存区域,而缓冲区是主存储器的内存区域。缓冲区保存单个块的数据,并且大小相同。所以缓冲区页面如下所示:

       .
       .
       .
|-------------|
|    buffer   |
|-------------|
|    buffer   |
|-------------|
|    buffer   |
|-------------|
       .
       .
       .

每个缓冲区中包含的块由缓冲区头标识。您可以在此处找到 buffer_head 的结构声明。和字段b_bdev一起b_blocknr标识块设备上的块。请注意,每个缓冲区头都有一个指向同一缓冲区页面内下一个缓冲区头的指针。该alloc_page_buffers函数分配和初始化指定缓冲区页的所有缓冲区的缓冲区头。alloc_page_buffers调用该set_bh_page函数来初始化缓冲区头的两个特定字段b_pageb_data,这些字段由代码中的注释描述:

struct page *b_page;    /* the page this bh is mapped to */
char        *b_data;    /* pointer to data within the page */

如您所见,它“将缓冲区链接到其页面”。

于 2018-04-13T22:14:06.240 回答