Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96914
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-01 19:43
文章分类
文章存档

2017年(4)

2015年(24)

2014年(1)

我的朋友

分类: LINUX

2015-07-11 13:56:27

原文地址:缓冲区首部结构 作者:zixin

 

缓冲区首部结构

struct buffer_head { 
 struct buffer_head *b_next;     //
用于缓冲块索引的散列链
 
 unsigned long b_blocknr;       //
该缓冲区在块设备上的块号 

 unsigned short b_size;     //
该缓冲区数据块尺寸 
 unsigned short b_list;       //
lru_list[]中的序号,表示该缓冲区的使用状态.
 
 kdev_t b_dev;     //
缓冲区所属的逻辑块设备
 
 atomic_t b_count;     //
引用计数
 
 kdev_t b_rdev;     //
所属的物理块设备
 
 unsigned long b_state; 
 unsigned long b_flushtime; 
 struct buffer_head *b_next_free;    // 
指向下一备用缓冲块
 
 struct buffer_head *b_prev_free;     //
指向前一备用缓冲块
 
 struct buffer_head *b_this_page;    // 
指向同一页面的缓冲块,形成环形链表
 
 struct buffer_head *b_reqnext;     //
用于块设备驱动程序
 
 struct buffer_head **b_pprev;      //
用于缓冲块散列链
 
 char * b_data;     //
指向缓冲块的数据区
 
 struct page *b_page;    // 
缓冲块的数据区所在的页面
 
 void (*b_end_io)(struct buffer_head *bh, int uptodate); 
  void *b_private; 
 unsigned long b_rsector; 
 wait_queue_head_t b_wait; 
 struct inode *      b_inode; 
 struct list_head     b_inode_buffers; 
}; 

#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512) 每页最多的缓冲块数

 

 

 

b_state域表示缓冲区的状态,可以是下表1中一种标志或多种标志的组合。合法的标志存放在bh_state_bits枚举中,该枚举在<linux/buffer_head.h>中定义。
1   bh_state 标志
状态标志                
BH_Uptodate        
该缓冲区包含可用数据
BH_Dirty           
该缓冲区是脏的(缓存中的内容比磁盘中的块内容新,
所以缓冲区内容必须被写回磁盘)
BH_Lock           
该缓冲区正在被I/O操作使用,被锁定以防被并发访问
BH_Req           
该缓冲区有I/O请求操作
BH_Mapped           
该缓冲区是映射磁盘块的可用缓冲区
BH_New           
缓冲区是通过get_block()刚刚映射的,尚且不能访问
          
BH_Async_Read        
该缓冲区正通过end_buffer_async_read()被异步I/O读操作使用
BH_Async_write  
该缓冲区正通过end_buffer_async_write()被异步I/O写操作使用
BH_Delay             
该缓冲区尚未和磁盘块关联
BH_Boundary        
该缓冲区处于连续块区的边界——下一个块不再连续
bh_state_bits
列表还包含了一个特殊标志——BH_PrivateStart,该标志不是可用状态标志,使用它是为了指明可被其他代码使用的起始位。块I/O层不会使用BH_PrivateStart或更高的位。那么某个驱动程序希望通过b_state域存储信息时就可以安全地使用这些位。驱动程序可以在这些位中定义自己的状态标志,只要保证自定义的状态标志不与块I/O层的专用位发生冲突就可以了。
b_count
域表示缓冲区的使用记数,可通过两个定义在文件<linux/buffer_head.h>中的内联函数对此域进行增减。


static inline void get_bh(struct buffer_head *bh)
{
      atomic_inc(&bh->b_count);
}

static inline void put_bh(struct buffer_head *bh)
{
      atomic_dec(&bh->b_count);
}
在操作缓冲区头之前,应该先使用get_bh()函数增加缓冲区头的引用计数,确保该缓冲区头不会再被分配出去;当完成对缓冲区头的操作之后,还必须使用put_bh()函数减少引用计数。

与缓冲区对应的磁盘物理块由b_blocknr域索引,该值是b_bdev域指明的块设备中的逻辑块号。
与缓冲区对应的内存物理页由b_page域表示,另外,b_data域直接指向相应的块(它位于b_page域所指明的页面中的某个位置上),块的大小由b_size域表示,所以块在内存中的起始位置在b_data处,结束位置在(b_data + b_size)处。

缓冲区头的目的在于描述磁盘块和物理内存缓冲区(在特定页面上的字节序列)之间的映射关系。这个结构体在内核中只扮演一个描述符的角色,说明从缓冲区到块的映射关系。

 

附加:

阅读(1579) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~