struct buffer_head { unsigned long b_state; /* buffer state bitmap (see above) */ struct buffer_head *b_this_page; /* circular list of page's buffers */ struct page *b_page; /* the page this bh is mapped to */
缓冲区头部对象buffer_head本身有一个叫做bh__cachep的slab分配器缓存。因此对buffer_head对象的分配与销毁都要通过kmem_cache_alloc()函数和kmem_cache_free()函数来进行。 NOTE!不要把bh_cachepSLAB分配器缓存和缓冲区buffer_head本身相混淆。前者只是buffer_head对象所使用的内存高速缓存,并不与块设备打交道,而...
个叫做bh__cachep的slab分配器缓存。因此对buffer_head对象的分配与销毁都要通过 kmem_cache_alloc函数和kmem_cache_free函数来进行。NOTE不要把bh_cachep SLAB分配器缓存和缓冲区buffer_head本身相混淆。前者只是buffer_head对象所使用 的内存高速缓存并不与块设备打交道而仅仅是一种有效管理buffer_head对象所占用 ...
AI代码解释 struct buffer_head{// 块缓存的标记unsigned long b_state;// 同一个页缓存的块缓存构成的环状链表struct buffer_head*b_this_page;// 所属的页缓存struct page*b_page;// 块缓存个数sector_t b_blocknr;size_t b_size;/* size of mapping */// 块缓存的起点char*b_data;// 所属的块...
alloc_buffer_head() 和 free_buffer_head() 分别获取和释放缓冲区首部。 buffer_head 的 b_count 字段是相应的块缓冲区的引用计数器。 每次对块缓冲区操作前递增计数器,操作后递减。 除了周期性地检查保持在页高速缓存中的块缓冲区外,当空闲内存变得很少时也检查它,当引用计数器为 0 时回收块缓冲区。
当一个进程被Read时,首先读取cache 中有没有相应的文件,这个cache由一个buffer_head结构读取。如果没有,文件系统就会利用块设备驱动去读取磁盘扇区的数据。于是read()函数就会初始化一个bio结构体,并提交给通用块层。通常用一个bio结构体来对应一个I/O请求。 (1-1)内核结构如下: 代码语言:javascript 代码...
在使用缓冲区之前,内核首先必须创建一个buffer_head结构实例,而其余的函数则对该结构进行操作。因为创建新缓冲头是一个频繁重现的任务,他应该尽快执行。这是一种很经典的情形,可使用slab缓存解决。 切记:内核源代码确实提供了一些函数,可用作前端,来创建和销毁缓冲头。alloc_buffer_head生成一个新的缓冲头,而free_bu...
static inline struct page *compound_head(struct page *page) { unsigned long head = READ_ONCE(page->compound_head); if (unlikely(head & 1)) return (struct page *) (head - 1); return page; } 再以page_mapping(page) 为例具体分析,进入函数内部,首先执行 compound_head(page) 获取 page map...
---当一个进程被Read时,首先读取cache 中有没有相应的文件,这个cache由一个buffer_head结构读取。如果没有,文件系统就会利用块设备驱动去读取磁盘扇区的数据。于是read()函数就会初始化一个bio结构体,并提交给通用块层。通常用一个bio结构体来对应一个I/O请求。 (1)...
缓冲区的高端被划分成一个个1024 字节的缓冲块,低端则分别建立起对应各缓冲块的缓冲头结构buffer_head(include/linux/fs.h,68 行),用于描述对应缓冲块的属性和把所有缓冲头连接成链表。直到它们之间已经不能再划分出缓冲块为止,见图9-10 所示。而各个buffer_head 被链接成一个空闲缓冲块双向链表结构。详细结构见...