块缓存

缓冲和缓存是利用一部分系统物理内存,确保最重要的、最常使用的块设备数据在操作时可直接从主存获取,而无需从低速设备读取。内核为块设备提供了两种通用的缓存方案。、

1.        页缓存:针对以页为单位的所有操作,并考虑了特定体系结构上的页长度。基本上其他类型的文件访问也是基于内核中的这一技术实现的,所以也缓存实际上会负责块设备的大部分工作。

2.        块缓存:以块为操作单位。在进行I/O操作时,存取的是设备的各个块,而不是整个内存页。

在许多场合下,页缓存和块缓存是联合使用的。页的长度对所有文件系统都是相同的,基本上为4K,但是块长度则需要取决于特定的文件系统或其设置。

曾经,缓冲区是对块设备进行I/O操作的传统方式。但在现在这个领域中,缓冲区只用于支持规模很小的读取操作,在这种场合下高级方法可能显得比较笨重。所以在内核版本2.5开发期间引入了BIO,以替换缓冲区,用于块传输的标准数据结构。

 

块缓存的结构

与内存页相比,块的大小小于等于内存页的,且长度是可变的,依赖于使用的块设备文件系统。块缓存也由两部分组成。

1.        缓冲头(buffer header)包含了与缓冲区状态相关的管理数据

2.        数据保存在专门分配的页中,这些页也可能同时存在于页缓存中。它存储在物理内存的一个独立区域中,由缓冲头结构中一个对应的指针表示。

图1 页与缓冲之间的链接

从图1可以看出页与缓存之间的关系,sector表示的是磁盘一个扇区大小512 Byte,block表示块大小,假设为1024 Byte(也有可能是4096 Byte),page表示页大小4096 Byte。从图中可知,页可以细分为更小的部分,各个部分之间是完全连续的,一个缓冲区(block buffer)至少512 Byte组成,每页最多可包括MAX_BUF_PER_PAGE个缓冲区。

块缓存主要的数据元素是缓冲头,它的定义是buffer_head.h文件中。

/*
 * Historically, a buffer_head was used to map a single block
 * within a page, and of course as the unit of I/O through the
 * filesystem and block layers.  Nowadays the basic I/O unit
 * is the bio, and buffer_heads are used for extracting block
 * mappings (via a get_block_t call), for tracking state within
 * a page (via a page_mapping) and for wrapping bio submission
 * for backward compatibility reasons (e.g. submit_bh).
 */
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 当前缓冲头映射到的页*/

	sector_t b_blocknr;		/* start block number 起始块号*/
	size_t b_size;			/* size of mapping 映射长度*/
	char *b_data;			/* pointer to data within the page 指向页内数据的指针*/

	struct block_device *b_bdev;	/*块设备*/
	bh_end_io_t *b_end_io;		/* I/O completion I/O完成*/
 	void *b_private;		/* reserved for b_end_io 保留给b_end_io使用*/
	struct list_head b_assoc_buffers; /* associated with another mapping */
	struct address_space *b_assoc_map;	/* mapping this buffer is
						   associated with */
	atomic_t b_count;		/* users using this buffer_head 缓冲头的使用计数*/
};

缓冲区类似于页,可以有许多状态。缓冲头的当前状态保存在b_state成员中,可以接受枚举类型bh_state_bits提供的值。

enum bh_state_bits {
	BH_Uptodate,	/* Contains valid data 缓冲区当前的数据是否与后备存储器匹配*/
	BH_Dirty,	/* Is dirty 缓冲区数据已修改,不再与后备存储器匹配,脏缓冲区*/
	BH_Lock,	/* Is locked 锁定缓冲区,防止多线程并发处理缓冲区,干扰彼此*/
	BH_Req,		/* Has been submitted for I/O */
	BH_Uptodate_Lock,/* Used by the first bh in a page, to serialise
			  * IO completion of other buffers in the page
			  */

	BH_Mapped,	/* Has a disk mapping */
	BH_New,		/* Disk mapping was newly created by get_block 新建的缓冲区*/
	BH_Async_Read,	/* Is under end_buffer_async_read I/O */
	BH_Async_Write,	/* Is under end_buffer_async_write I/O */
	BH_Delay,	/* Buffer is not yet allocated on disk */
	BH_Boundary,	/* Block is followed by a discontiguity */
	BH_Write_EIO,	/* I/O error on write */
	BH_Ordered,	/* ordered write */
	BH_Eopnotsupp,	/* operation not supported (barrier) */
	BH_Unwritten,	/* Buffer is allocated on disk but not written */
	BH_Quiet,	/* Buffer Error Prinks to be quiet */

	BH_PrivateStart,/* not a state bit, but the first bit available
			 * for private allocation by other entities
			 */
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值