在页高速缓存中搜索块


当内核需要读或写一个单独的物理设备块时(例如一个超级块),必须检查所请求的块缓冲区是否已经在页高速缓存中。在页高速缓存中搜索指定的块缓冲区(由块设备描述符的地址bdev和逻辑块号nr表示)的过程分成三个步骤:
 
1. 获取一个指针,让它指向包含指定块的块设备的address_space对象(bdev->bd_inode->i_mapping)。
 
2. 获得设备的块大小(bdev->bd_block_size),并计算包含指定块的页索引。这需要在逻辑块
摘要由CSDN通过智能技术生成

当内核需要读或写一个单独的物理设备块时(例如一个超级块),必须检查所请求的块缓冲区是否已经在页高速缓存中。在页高速缓存中搜索指定的块缓冲区(由块设备描述符的地址bdev和逻辑块号nr表示)的过程分成三个步骤:

 

1. 获取一个指针,让它指向包含指定块的块设备的address_space对象(bdev->bd_inode->i_mapping)。

 

2. 获得设备的块大小(bdev->bd_block_size),并计算包含指定块的页索引。这需要在逻辑块号上进行位移操作。例如,如果块的大小是1024字节,每个缓冲区页包含四个块缓冲区,那么页的索引是nr/4。

 

3. 在块设备的基树中搜索缓冲区页。获得页描述符之后,内核访问缓冲区首部,它描述了页中块缓冲区的状态。

 

不过,实现的细节要更为复杂。为了提高系统性能,内核维持一个小磁盘高速缓存数组bh_lrus(每个CPU对应一个数组元素),即所谓的最近最少使用(LRU)块高速缓存。每个磁盘高速缓存有8个指针,指向被指定CPU最近访问过的缓冲区首部。对每个CPU数组的元素排序,使指向最后被使用过的那个缓冲区首部的指针索引为0。相同的缓冲区首部可能出现在几个CPU数组中(但是同一个CPU数组中不会有相同的缓冲区首部)。在LRU块高速缓存中每出现一次缓冲区首部,该缓冲区首部的使用计数器b_count就加1。

 

1 __find_get_block()函数

 

函数__find_get_block()的参数有:block_device描述符地址bdev,块号block和块大小size。函数返回页高速缓存中的块缓冲区对应的缓冲区首部的地址;如果不存在指定的块,就返回NULL:
struct buffer_head *
__find_get_block(struct block_device *bdev, sector_t block, int size)
{
      struct buffer_head *bh = lookup_bh_lru(bdev, block, size);

      if (bh == NULL) {
            bh = __find_get_block_slow(bdev, block);
            if (bh)
                  bh_lru_install(bh);
      }
      if (bh)
            touch_buffer(bh);
      return bh;
}

 

数本质上执行下面的操作:


1. 检查执行CPU的LRU块高速缓存数组中是否有一个缓冲区首部,其b_bdev、b_blocknr和b_size字段分别等于bdev、block和size:
static struct buffer_head *
lookup_bh_lru(struct block_device *bdev, sector_t block, int size)
{
      struct buffer_head *ret = NULL;
      struct bh_lru *lru;
      int i;

      check_irqs_on();
      bh_lru_lock();
      lru = &__get_cpu_var(bh_lrus);
      for (i = 0; i < BH_LRU_SIZE

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值